Cách truy vấn CSDL SQL trong WordPress , Bookmark để xem trong trường hợp cần nhanh
Chào mọi người bởi việc làm theme, plugin … wordpress thì cũng cần sự nhanh nhạy chứ những cái mình đã hiểu rồi mà ngồi code từng dòng lại thì cũng khá lâu và mệt mỏi. Mình cũng chưa thấy editor nào mà nó hỗ trợ các phím tắt hay các lệnh tắt đối với WordPress cả 🙂 cao lắm thì PHP là ngon rồi. Chính vì vậy có những cái mình cần copy nhanh và sửa lại theo ý mình thôi mà đôi lúc tìm cũng không thấy.
Thôi thì lâu lâu mình sưu tầm các đoạn code đó về bỏ lên Blog của mình để sử dụng trong quá trình code nếu cần, và AE có ai cần thì Bookmark lại của mình để sử dụng nhanh khi cần nhé.
Nội Dung Bài Viết
- Hôm nay sẽ là Bookmark về các lệnh truy vấn CSDL SQL trong WordPress.
- Về Class WPDB của WordPress
- Các bảng cơ sở dữ liệu mặc định
- Cách thức gọi cơ sở dữ liệu
- Mọi thứ cần được an toàn
- Query chung
- Lấy giá trị của một biến nào đó trong bảng
- Lấy giá trị của một hàng
- Lấy hàng loạt giá trị
- Insert giá trị vào bảng
- Thay thế một trường trong bảng
- Update trong dữ liệu
- Xóa một dữ liệu
- Chống hacker hack vào cơ sở dữ liệu
Hôm nay sẽ là Bookmark về các lệnh truy vấn CSDL SQL trong WordPress.
Về Class WPDB của WordPress
Class WPDB của WordPress sử dụng thư viện EzSQL của Justin Vincent và được phát triển phù hợp hơn với WordPress nhưng vẫn giữ phong cách của EzSQL.
* Lưu ý: vì vấn đề bảo mật cho nên các bạn không được gọi trực tiếp class::WPDB mà hãy sử dụng object qua global $wpdb.
* Lưu ý tiếp: Vì vấn đề bảo mật, bạn cần phải escape toàn bộ các dữ liệu trước khi thêm vào cơ sở dữ liệu, các hàm escape bao gồm:
- esc_html: escape toàn bộ các mã html, ví dụ dấu < sẽ là >
- esc_attr: escape toàn bộ các giá trị trong form !
- esc_sql: escape các text cho SQL, tuy nhiên không nên dùng mà thay vào đó sử dụng hàm $wpdb->prepare !
- esc_textarea: Mã hóa các thẻ html !
Các bảng cơ sở dữ liệu mặc định
Bảng mặc định:
$posts $postmeta $comments $commentmeta $terms $term_taxonomy $term_relationships $users $usermeta $links $options
Các bảng trong WordPress Multisite:
$blogs $signups $site $sitemeta $sitecategories $registration_log $blog_versions
Cách thức gọi cơ sở dữ liệu
Các bạn không nên gọi trực tiếp, hãy gọi theo biến toàn cục global như sau:
global $wpdb;
Mọi thứ cần được an toàn
Theo thứ tự về mức độ quan trọng, Jam sẽ viết hàm quan trọng lên gần đầu để các bạn tiện theo dõi, và để an toàn với các cuộc tấn công SQL Injection cực kì phổ thông, các bạn cần phải chạy các lệnh của SQL qua hàm prepare, sau đây là ví dụ:
global $wpdb; $wpdb->prepare('select * from %s where user_id = %d', $wbdb->users, 5);
Trong hàm này ta thấy cách thức hoạt động của nó hoàn toàn giống hàm sprintf() trong PHP !
%f: Float – dữ liệu float ( ví dụ 1,234 )
%d: Decima – số ( ví dụ: 1220 )
%s: String – chuỗi kí tự ( ví dụ “chào các bạn tôi là string”)
Và nếu như Input vào mà sai so với mệnh đề thứ nhất, thì dữ liệu sẽ bị ép kiểu, các bạn để ý lần lượt ở câu lệnh trên là:
select * from %s <!-- string // --> where user_id = %d <!-- số // -->, %s <!-- string // -->, %d <!-- sẽ bị ép kiểu là số -->
Khi mọi lệnh chạy qua hàm Prepare thì các biến, câu lệnh và các giá trị của người dùng sẽ được lọc an toàn, các bạn lưu ý như sau, nếu trong câu lệnh mà không có giá trị nào người dùng thêm vào, ta không cần sử dụng hàm này, vì chỉ có người dùng input vào thì dữ liệu mới không an toàn, hoặc là sẽ bị báo lỗi, trường hợp sau sẽ bị báo lỗi:
$wpdb->prepare("select * from {$wbdb->users}");
Khi câu lệnh tuyệt đối an toàn như trên, chẳng có lý do gì bạn chạy qua hàm Prepare nữa, mà chạy thẳng qua $wpdb->query luôn !
Query chung
Các bạn có thể chạy bất kì câu lệnh nào với $wpdb->query, dùng để chạy các lệnh rất cơ bản mà không cần trả về kết quả như SELECT, INSERT, DELETE, UPDATE như sau:
$wpdb->query( $wpdb->prepare( " DELETE FROM $wpdb->postmeta WHERE post_id = %d AND meta_key = %s ", 13, 'gargle' ) );
Hay như thế này:
$wpdb->query( " UPDATE $wpdb->posts SET post_parent = 7 WHERE ID = 15 AND post_status = 'static' " );
* Kinh nghiệm: Các câu lệnh an toàn, do hệ thống chạy và không có trường nào do người dùng Input thì có thể chạy lệnh query trực tiếp như vậy, các câu lệnh thường không cần phải trả về một kết quả xác thực nào mà chỉ cần trả về đúng hoặc sai, hoặc ID của row bị ảnh hưởng …
* Ví dụ như sau:
Đếm số thành viên trên trang:
global $wpdb; echo inval( $wpdb->query("select count(*) from $wpdb->users") );
Lấy giá trị của một biến nào đó trong bảng
Để lấy giá trị của một biến, một giá trị đơn nào đó trong bảng, hoặc đếm số recode, ta có thể sử dụng hàm get_var trong WordPress, ví dụ như sau:
<?php $wpdb->get_var( 'query', column_offset, row_offset ); ?>
Câu lệnh ví dụ về đếm thành viên trên trang:
$user_count = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->users" );
Hoặc câu lệnh sau đây tính tổng giá trị trong bảng meta của Post, đếm giá tiền chẳng hạn:
$meta_key = '_price'; $allmiles = $wpdb->get_var( $wpdb->prepare( " SELECT sum(meta_value) FROM $wpdb->postmeta WHERE meta_key = %s ", $meta_key ) );
Lấy giá trị của một hàng
Để lấy toàn bộ giá trị của một hàng, chúng ta có thể sử dụng hàm get_row, code mẫu như sau:
<?php $wpdb->get_row('query'); ?>
Câu lệnh trên sẽ trả về Object theo mặc định, các bạn xem code ví dụ như sau:
$mylink = $wpdb->get_row( "SELECT * FROM $wpdb->links WHERE link_id = 10" );
Lệnh trên lấy toàn bộ các giá trị trong một hàng với link_id là 10, trường hợp khác, bạn muốn lấy toàn bộ giá trị của Post ID là 10 thì sao ? Xem code sau:
$postdata = $wpdb->get_row( "SELECT * FROM $wpdb->posts WHERE post_id = 10" );
Và bạn có thể lấy giá trị của Post_content một cách dễ dàng:
echo $content = $postdata->post_content;
Lấy hàng loạt giá trị
Để lấy một giá trị đơn, các bạn sử dụng hàm get_var hoặc get_row, nhưng để lấy hàng loạt các giá trị thỏa mãn điều kiện thì bạn cần phải sử dụng hàm get_results nhé, xem code mẫu sau đây:
$wpdb->get_results( 'query');
Trả về sẽ là mặc định một array có chứa các Object khác nhau, ví dụ trong trường hợp cụ thể, tôi muốn lấy toàn bộ các bài đăng của User 1 thì làm thế nào ?
$user_id = 1; $data = $wpdb->get_results( $wpdb->prepare( 'select * from %s where user_id = %d LIMIT 99', $wpdb->posts, $user_id )); foreach ( $data as $k ) { echo $k->post_title; }
Trong hầu hết các trường hợp, bạn sẽ sử dụng get_var và get_results để lấy kết quả ? và trong các vòng lặp của WordPress, người ta cũng sử dụng hàm get_results này nhé các bạn !
Insert giá trị vào bảng
Để Insert một giá trị nào đó vào bảng, các bạn sử dụng hàm insert sau đây để thêm nhé, tuyệt đối không thêm bằng cách sử dụng $wpdb->query, trừ trường hợp rất an toàn, các bạn xem mẫu code sau:
$wpdb->insert( $table, $data, $format );
Code ví dụ như sau, các bạn cần chèn thêm dữ liệu trong bảng posts trong WordPress chẳng hạn, làm như sau:
$wpdb->insert( $wpdb->posts, array('ID' => $wpdb->insert_id, 'post_content' => $content), array('%d', '%s') );
Nếu Insert thành công, bạn sẽ được hàm trả về giá trị là 1, nếu không sẽ là False hoặc 0.
Thay thế một trường trong bảng
Để thay thế trường, cột nào đó trong bảng dữ liệu, các bạn cũng làm tương tự như Insert, nhưng dùng hàm Replace nhé:
$wpdb->replace( $table, $data, $format )
Ví dụ như sau:
$wpdb->replace( 'table', array( 'indexed_id' => 1, 'column1' => 'value1', 'column2' => 123 ), array( '%d', '%s', '%d' ) );
Hàm này cũng trả về true hoặc false nếu thực hiện được hoặc không thực hiện được !
Update trong dữ liệu
Để update một hàng hay một giá trị trong hàng ta thực hiện bằng lệnh update, code như sau:
$wpdb->update( $table, $data, $where, $format = null, $where_format = null );
Ví dụ, ta cần thay thế Post_title có Post ID 10 bằng Post_title mới, ta làm như sau:
$wpdb->update( $wpdb->posts, array('post_title' => 'Thân chào các bạn'), array('ID' => 10), );
Xóa một dữ liệu
Để xóa hàng, trường dữ liệu nào đó ta có thể sử dụng hàm delete như sau:
$wpdb->delete( $table, $where, $where_format = null );
Ví dụ bạn muốn xóa bài đăng có ID là 2, bạn làm như sau:
$wpdb->delete( $wpdb->posts, array('ID' => 2));
Câu lệnh trả về ID bị xóa hoặc false;
Chống hacker hack vào cơ sở dữ liệu
Các bạn nên sử dụng Sprintf hoặc hàm Prepare để giảm thiểu rủi ro bị tấn công SQL injection, trường hợp khác, các bạn có thể sử dụng các hàm đã có sẵn trong WordPress để sử dụng, tôi lấy ví dụ như sau:
Sử dụng Sprinf:
$wpdb->query( sprinf('select * from %s where user_id = %d ', $wpdb->users, 12) );
Sử dụng hàm mặc định:
- wp_delete_post( postID );
- wp_delete_user( $userID );
- Delete_option( $name );
- Wp_trash_post( $postID );
… Và còn nhiều thứ khác nữa các bạn có thể tham khảo thêm trên Codex của WordPress.org nhé.
“Chúng ta hoàn toàn có thể viết truy vấn bình thường như code thuần PHP trong wordpress nhưng để đúng chuẩn và vấn đề bảo mật hãy tuân thủ theo tiêu chuẩn của WordPress”.