PDO (PHP Data Object) là các API có sẵn của PHP cho phép người lập trình có thể kết nối để làm việc với cơ sở dữ liệu. PDO không phải là một khái niệm mới, nó được giới thiệu lần đầu tiên ở phiên bản PHP 5, hiện nay đang được sử dụng rất phổ biến. PDO là các đối tượng dữ liệu trong PHP, nó sẽ chuyển tất cả dữ liệu thành đối tượng, đồng thời cũng cung cấp các phương thức để thao tác với cơ sở dữ liệu. Show
I. Lưu ýKhi Sử dụng các đoạn code có khả năng lỗi cần viết vào try, catch try { } catch (PDOException $e) { }II. Fetch dữ liệuCó hai cách căn bản để lấy dữ liệu trong PDO là query và excute. - Query: sử dụng trong các trường hợp câu truy vấn không có biến truyền vào, hoặc các biến chắc chắn không gây ra Sql Injection $result = $db->query('select SQL_CALC_FOUND_ROWS * from nv3_config LIMIT 0, 30'); $rs1 = $db->query('SELECT FOUND_ROWS()'); $all_page = $rs1->fetchColumn(); print("all_page $all_page rows"); foreach ($result as $row) { }- Exec: sử dụng trong các trường hợp câu truy vấn không có biến truyền vào, hoặc các biến chắc chắn không gây ra Sql Injection, giá trị trả về là số dòng thực hiện. $count = $db->exec("DELETE FROM nv3_config WHERE module = 'khongco'"); print("Deleted $count rows"); Ngoài ra, còn có một cách tiếp cận khác nữa là sử dụng $config_name = 'users2'; $del = $db->prepare('DELETE FROM nv3_config2 WHERE config_name=:config_name'); $del->bindValue(':config_name', $config_name); $del->execute(); 3, phương thức này sử dụng trong trường hợp nếu có biến truyền vào câu truy vấn. $config_name = 'users2'; $del = $db->prepare('DELETE FROM nv3_config2 WHERE config_name=:config_name'); $del->bindValue(':config_name', $config_name); $del->execute(); $module = 'users'; $sth = $db->prepare("select * from nv3_config WHERE module=:module LIMIT 0, 4"); $sth->bindParam(':module', $module); $sth->execute(); $array = $sth->fetchAll(); var_export($array); III. Chỉ định dữ liệu đầu raCũng như cách dùng của API mysql, dữ liệu khi được lấy ra từ cơ sở dữ liệu cần phải được “đổ” (fetch) vào một array, object hoặc một class thì mới sử dụng được. PDO cũng cung cấp một số kiểu fetch cơ bản như sau:
Mặc định, NukeViet sử dụng $config_name = 'users2'; $del = $db->prepare('DELETE FROM nv3_config2 WHERE config_name=:config_name'); $del->bindValue(':config_name', $config_name); $del->execute(); 4. $sql = 'SELECT * FROM ' . NV_PREFIXLANG . '_' . $module_data . ' WHERE status=1 AND id=' . $id; $row = $db->query($sql)->fetch(); IV. Thao tác dữ liệu1. Create (insert)$sth = $db->prepare('INSERT INTO ' . NV_PREFIXLANG . '_' . $module_data . ' VALUES(NULL, :name, :birthday, :class)'); $sth->bindParam(':name', $name, PDO::PARAM_STR); $sth->bindParam(':name', $birthday, PDO::PARAM_STR); $sth->bindParam(':class', $class, PDO::PARAM_STR); $sth->execute(); 2. Update$sth = $db->prepare('UPDATE ' . NV_PREFIXLANG . '_' . $module_data . ' SET name = :name, birthday = :birthday, class = :class)'); $sth->bindParam(':name', $name, PDO::PARAM_STR); $sth->bindParam(':name', $birthday, PDO::PARAM_STR); $sth->bindParam(':class', $class, PDO::PARAM_STR); $sth->execute(); 3. Delete$sth = $db>prepare('DELETE FROM ' . NV_PREFIXLANG . '_' . $module_data . ' WHERE id = :id'); $stmt->bindParam(':id', $id); $stmt->execute(); Thực thi nhiều câu lệnh Xem ví dụ: $stmt = $db->prepare('INSERT INTO ' . NV_PREFIXLANG . '_' . $module_data . ' VALUES(:name)'); $stmt->bindParam(':name', $name); First insertion$name = 'Keith'; $stmt->execute(); Second insertion$name = 'Steven'; $stmt->execute(); // Max Weight $sql = 'SELECT max(weight) FROM ' . NV_PREFIXLANG . '' . $module_data . ' WHERE catid=' . $catid; $weight = $db->query($_sql)->fetchColumn(); $weight = intval($weight) + 1; // Fetch Limit $db->sqlreset() $all_page = $db->query($db->sql()) $db->select('*') while ($row = $_query->fetch()) { }V. Các chú ý trong lập trình CSDL với NukeViet1. Đặt tên các bảng và cột
2. Về các câu truy vấn các cộtThường chúng ta viết câu truy vấn chúng ta viết như sau $result = $db->query('select SQL_CALC_FOUND_ROWS * from nv3_config LIMIT 0, 30'); $rs1 = $db->query('SELECT FOUND_ROWS()'); $all_page = $rs1->fetchColumn(); print("all_page $all_page rows"); foreach ($result as $row) { }0 Thì cần viết lại: $result = $db->query('select SQL_CALC_FOUND_ROWS * from nv3_config LIMIT 0, 30'); $rs1 = $db->query('SELECT FOUND_ROWS()'); $all_page = $rs1->fetchColumn(); print("all_page $all_page rows"); foreach ($result as $row) { }1 Tức bỏ dấu ` đi để có thể chạy được trên các loại CSDL khác, Khi đó sẽ không dùng được các tên sau trong bảng và cột của CSDL: add, all, alter, analyze, and, as, asc, before, between, bigint, binary, both, by, call, cascade, case, change, char, character, check, collate, column, comment, condition, constraint, continue, convert, create, cross, current_user, cursor, database, databases, date, day_hour, day_minute, day_second, dec, decimal, declare, default, delayed, delete, desc, describe, distinct, distinctrow, drop, dual, else, elseif, enclosed, escaped, exists, exit, explain, false, fetch, file, float4, float8, for, force, foreign, from, fulltext, get, grant, group, having, high_priority, hour_minute, hour_second, identified, if, ignore, ignore_server_ids, in, index, infile, inner, insert, int1, int2, int3, int4, int8, integer, interval, into, is, iterate, join, key, keys, kill, leading, leave, left, level, like, limit, lines, load, lock, long, loop, low_priority, master_bind, master_heartbeat_period, master_ssl_verify_server_cert, match, middleint, minute_second, mod, mode, modify, natural, no_write_to_binlog, not, null, number, numeric, on, optimize, option, optionally, or, order, outer, outfile, partition, precision, primary, privileges, procedure, public, purge, read, real, references, release, rename, repeat, replace, require, resignal, restrict, return, revoke, right, rlike, rows, schema, schemas, select, separator, session, set, share, show, signal, spatial, sql_after_gtids, sql_before_gtids, sql_big_result, sql_calc_found_rows, sql_small_result, sqlstate, ssl, start, starting, straight_join, table, terminated, then, to, trailing, trigger, true, undo, union, unique, unlock, unsigned, update, usage, use, user, using, values, varcharacter, varying, view, when, where, while, with, write, year_month, zerofill 3. Đặt bí danh cho bảng (Table Allias)Không dùng mệnh đề AS cho bảng (Vẫn có thể dùng Allias cho cột được) Thay vì viết $result = $db->query('select SQL_CALC_FOUND_ROWS * from nv3_config LIMIT 0, 30'); $rs1 = $db->query('SELECT FOUND_ROWS()'); $all_page = $rs1->fetchColumn(); print("all_page $all_page rows"); foreach ($result as $row) { }2 Hãy viết bằng $result = $db->query('select SQL_CALC_FOUND_ROWS * from nv3_config LIMIT 0, 30'); $rs1 = $db->query('SELECT FOUND_ROWS()'); $all_page = $rs1->fetchColumn(); print("all_page $all_page rows"); foreach ($result as $row) { }3 4. Viết câu lệnh và lấy về chỉ số tăng tự độngTrước chúng ta viết $result = $db->query('select SQL_CALC_FOUND_ROWS * from nv3_config LIMIT 0, 30'); $rs1 = $db->query('SELECT FOUND_ROWS()'); $all_page = $rs1->fetchColumn(); print("all_page $all_page rows"); foreach ($result as $row) { }4 Và dùng $result = $db->query('select SQL_CALC_FOUND_ROWS * from nv3_config LIMIT 0, 30'); $rs1 = $db->query('SELECT FOUND_ROWS()'); $all_page = $rs1->fetchColumn(); print("all_page $all_page rows"); foreach ($result as $row) { }5 Thì cần viết lại theo cách $result = $db->query('select SQL_CALC_FOUND_ROWS * from nv3_config LIMIT 0, 30'); $rs1 = $db->query('SELECT FOUND_ROWS()'); $all_page = $rs1->fetchColumn(); print("all_page $all_page rows"); foreach ($result as $row) { }6 5. Khi câu lệnh có Limit cần sử dụng lớp $db để tạo câu lệnh SQL$result = $db->query('select SQL_CALC_FOUND_ROWS * from nv3_config LIMIT 0, 30'); $rs1 = $db->query('SELECT FOUND_ROWS()'); $all_page = $rs1->fetchColumn(); print("all_page $all_page rows"); foreach ($result as $row) { }7 Ngoài ra nếu câu lệnh SQL có sử dụng SQL_CALC_FOUND_ROWS, SELECT FOUND_ROWS() để lấy tổng số kết quả truy vấn (các cách này chỉ chạy trên MySQL). Thì khi đó cần viết thành 2 câu lệnh truy vấn tương tự như trên. 6. Không sử dụng REPLACE INTO trong câu lệnh SQLthay vì đó hãy sử dụng INSERT hay update Nguyên nhân REPLACE INTO chỉ dùng được trên MySQL, ngoài ta REPLACE INTO nếu chạy trên MySQL với Storage Engine InnoDB thực chất cũng dùng hai câu lệnh DELETE và INSERT cùng lúc 7. PDOStatement :: rowCount ()trả về số hàng bị ảnh hưởng bởi cuối cùng DELETE, INSERT, hoặc UPDATE thực hiện bởi các đối tượng PDOStatement tương ứng. Không sử dụng đối với câu lệnh SQL SELECT do trên Oracle không chạy Nếu viết $result = $db->query('select SQL_CALC_FOUND_ROWS * from nv3_config LIMIT 0, 30'); $rs1 = $db->query('SELECT FOUND_ROWS()'); $all_page = $rs1->fetchColumn(); print("all_page $all_page rows"); foreach ($result as $row) { }8 Cần viết thành $result = $db->query('select SQL_CALC_FOUND_ROWS * from nv3_config LIMIT 0, 30'); $rs1 = $db->query('SELECT FOUND_ROWS()'); $all_page = $rs1->fetchColumn(); print("all_page $all_page rows"); foreach ($result as $row) { }9 8. Sử dụng Prepares a statementPDOStatement::bindParam, PDOStatement::bindValue đều dùng để truyền dữ liệu cho Prepares a statement, nhưng chúng khác nhau PDOStatement::bindParam Truyền địa chỉ của biến. PDOStatement::bindValue Truyền giá trị của biến. - Nên nếu dùng trong vòng lặp, mà chưa chạy PDOStatement::execute thì cần dùng PDOStatement::bindValue - Nếu cần gán giá trị > 400 ký tự bắt buộc phải dùng PDOStatement::bindParam và phải có cả độ dài của chuỗi $count = $db->exec("DELETE FROM nv3_config WHERE module = 'khongco'"); print("Deleted $count rows"); 0 VI. INSERT CSDL trong PDO$count = $db->exec("DELETE FROM nv3_config WHERE module = 'khongco'"); print("Deleted $count rows"); 1 VII. Update CSDL trong PDO$count = $db->exec("DELETE FROM nv3_config WHERE module = 'khongco'"); print("Deleted $count rows"); 2 VIII. Xóa CSDLcó 2 cách xóa nhưng có 3 phương thức xóa $count = $db->exec("DELETE FROM nv3_config WHERE module = 'khongco'"); print("Deleted $count rows"); 3 Truy vấn khácTruy vấn phân trang trong Nukeviet 4x$count = $db->exec("DELETE FROM nv3_config WHERE module = 'khongco'"); print("Deleted $count rows"); 4 Truy vấn một số trường trong CSDLcó 2 cách Cách 1:$count = $db->exec("DELETE FROM nv3_config WHERE module = 'khongco'"); print("Deleted $count rows"); 5 Cách 2$count = $db->exec("DELETE FROM nv3_config WHERE module = 'khongco'"); print("Deleted $count rows"); 6 Truy vấn 1 trường csdl lấy 1 record duy nhất$count = $db->exec("DELETE FROM nv3_config WHERE module = 'khongco'"); print("Deleted $count rows"); 7 Truy vấn tính tổng số dòng có trong 1 bảng CSDL $count = $db->exec("DELETE FROM nv3_config WHERE module = 'khongco'"); print("Deleted $count rows"); 8 CSDL có chứa kiểu float để giá trị không bị biến đổiđối với csdl có chứa kiểu float để giá trị không bị biến đổi trong truy vấn bạn cần làm như sau $count = $db->exec("DELETE FROM nv3_config WHERE module = 'khongco'"); print("Deleted $count rows"); 9 Đây là kết quả bạn thu được $module = 'users'; $sth = $db->prepare("select * from nv3_config WHERE module=:module LIMIT 0, 4"); $sth->bindParam(':module', $module); $sth->execute(); $array = $sth->fetchAll(); var_export($array); 1 $config_name = 'users2'; $del = $db->prepare('DELETE FROM nv3_config2 WHERE config_name=:config_name'); $del->bindValue(':config_name', $config_name); $del->execute(); 0 $module = 'users'; $sth = $db->prepare("select * from nv3_config WHERE module=:module LIMIT 0, 4"); $sth->bindParam(':module', $module); $sth->execute(); $array = $sth->fetchAll(); var_export($array); 2 $config_name = 'users2'; $del = $db->prepare('DELETE FROM nv3_config2 WHERE config_name=:config_name'); $del->bindValue(':config_name', $config_name); $del->execute(); 1 Sự an toàn của truy vấn tham số không có hiệu lực khi bạn sử dụng PDO :: ATTR_EMULATE_PREPARES ⇒ true . Ứng dụng của bạn phải đảm bảo rằng các dữ liệu được liên kết với các tham số (s) không chứa mã độc hại Transact-SQL. |