Learn to perform secure CRUD operations in WordPress using $wpdb. Prevent SQL injection with prepared statements in your custom plugin database interactions.
Previously in this course, we covered the database basics with wpdb, where you learned how to access the $wpdb object and perform simple SELECT queries. In this lesson, we move beyond reading data to writing it safely.
To maintain the integrity of our Knowledge Base plugin, we must ensure every "Create, Read, Update, and Delete" (CRUD) operation is immune to SQL injection. By leveraging built-in WordPress helper methods, we can abstract away the complexity of manual query construction and minimize human error.
When you write raw SQL queries, you are responsible for escaping every variable. If you forget even one, an attacker can manipulate your query to drop tables or leak sensitive user information. While preventing SQL injection in modern frameworks is standard practice, WordPress provides specific methods that handle this automatically.
We will focus on $wpdb->insert, $wpdb->update, and $wpdb->delete. These methods take arrays of data and handle the formatting and quoting for you, provided you use them correctly.
$wpdb->insertTo add a new entry to a custom table, we pass the table name, an associative array of data, and an optional array of formats.
PHPglobal $wpdb; $table_name = $wpdb->prefix . 'kb_articles'; $data = [ 'title' => 'How to use hooks', 'content' => 'Hooks allow you to modify WordPress...', 'status' => 'published' ]; $wpdb->insert($table_name, $data, ['%s', '%s', '%s']);
The third argument specifies the format: %s for strings, %d for integers, and %f for floats. Always define these to ensure the database engine treats your data as the correct type.
$wpdb->updateUpdating follows a similar pattern, but requires a WHERE clause to ensure you don't accidentally update the entire table.
PHP$wpdb->update( $table_name, ['status' => 'archived'], #6A9955">// Data to update ['id' => 5], #6A9955">// WHERE clause ['%s'], #6A9955">// Format of data ['%d'] #6A9955">// Format of WHERE );
$wpdb->prepareWhile insert and update handle their own security, SELECT queries (the "Read" in CRUD) require explicit protection. You must use $wpdb->prepare() to sanitize your input before it reaches the database.
PHP$article_id = 5; #6A9955">// Suppose this came from $_GET['id'] $query = $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}kb_articles WHERE id = %d", $article_id ); $article = $wpdb->get_row($query);
By using %d as a placeholder, prepare() ensures that $article_id is treated strictly as an integer, rendering SQL injection attempts harmless.
Deletion is the most dangerous operation. Always ensure you have a specific WHERE clause to avoid catastrophic data loss.
PHP$wpdb->delete( $table_name, ['id' => 5], ['%d'] );
In your Knowledge Base plugin, create a method within your KnowledgeBaseModel class that deletes an article by its ID.
$id as an argument.$wpdb->delete to remove the row from your custom table."SELECT * FROM table WHERE id = $id"). This is the primary vector for SQL injection.wpdb::prepare: Every time you use $wpdb->get_results, get_row, or get_var with variables, you must use prepare().CRUD operations are the lifeblood of your plugin's data management. By standardizing your database interactions through $wpdb->insert, $wpdb->update, and $wpdb->prepare, you protect your plugin against common security vulnerabilities. Always treat user-supplied data as untrusted until it has been properly formatted and prepared for the database engine.
Up next: We will transition from raw SQL to the powerful WP_Query class, which simplifies complex data retrieval in WordPress.
Master WordPress security by implementing capability checks. Learn to use current_user_can to restrict admin features and enforce proper access control.
Read moreMaster advanced database queries in WordPress. Learn to write custom SQL JOINs with $wpdb and profile query performance to build scalable, high-speed plugins.
Secure CRUD Operations
Plugin Security Best Practices
Composer for Dependencies
Theme Integration Hooks
Managing Assets with Gulp/Webpack
Documentation Standards
Plugin Deployment Strategy
Advanced MVC: Dependency Injection
Handling Large Datasets
Error Handling and Logging