Database Basics with wpdb: Secure Queries for WordPress
Learn to use the $wpdb object for direct database interaction. Master the difference between raw and prepared queries to keep your plugin secure and performant.
Previously in this course, we explored saving meta data, which provided a high-level way to interact with post attributes. In this lesson, we drop down a layer to interact directly with the WordPress database using the $wpdb object.
Accessing the $wpdb Object
In WordPress, the $wpdb object is a global instance of the wpdb class. It serves as the primary interface for executing SQL queries against your WordPress database. Because it is a global variable, you must explicitly declare it within your methods before you can use it.
PHPfunction get_article_count() { global $wpdb; #6A9955">// Now you can access $wpdb methods }
Think of $wpdb as your bridge to the database. It handles connection management, prefixing table names (so your queries work regardless of the user's table prefix), and providing helper methods for CRUD operations.
Prepared vs. Raw Queries
The most critical rule in WordPress development is: never trust user input. If you take a value from a URL parameter or a form field and inject it directly into an SQL string, you open your site to SQL injection attacks.
- Raw Queries: These are standard SQL strings. Using variables directly inside them is dangerous because a malicious user could craft an input that alters the structure of your query.
- Prepared Queries: These use placeholders (like
%sfor strings or%dfor integers) to separate the SQL logic from the data. Thewpdb::prepare()method then safely binds the values, ensuring they are escaped and treated strictly as data, not as executable code.
Performing a Simple SELECT Query
Let's look at a concrete example. Suppose we want to fetch the count of all published posts in our Knowledge Base plugin. We use $wpdb->get_var() to retrieve a single scalar value.
PHPpublic function get_published_article_count() { global $wpdb; #6A9955">// Use the prepare method even for simple queries to stay in the habit $query = $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->posts} WHERE post_type = %s AND post_status = %s", 'knowledge-article', 'publish' ); return $wpdb->get_var($query); }
Notice how we used {$wpdb->posts}. You should always use the table properties provided by the $wpdb object rather than hardcoding wp_posts, as site administrators often change their database prefix for security.
Hands-on Exercise
In your KnowledgeBaseModel class, create a method named get_latest_article_title().
- Use
global $wpdb;. - Write a query to select the
post_titlefrom the{$wpdb->posts}table. - Use a
WHEREclause to filter bypost_type = 'knowledge-article'andpost_status = 'publish'. - Use
ORDER BY post_date DESCandLIMIT 1. - Use
$wpdb->prepare()to ensure thepost_typeis passed safely. - Return the result using
$wpdb->get_var().
Common Pitfalls
- Hardcoding Prefixes: Never assume the table is named
wp_posts. Always use$wpdb->posts,$wpdb->postmeta, or other built-in properties. - Forgetting
prepare(): It is tempting to skipprepare()for simple static queries. Don't. It's a defensive programming habit that prevents future bugs when you eventually decide to make that query dynamic. - Over-querying: While
$wpdbis powerful, it is often overkill. If you are retrieving post data, prefer usingWP_Queryorget_posts()first. We will cover those in later lessons, but for now, remember that direct SQL is for when the WordPress abstraction layer doesn't fit your needs. - Security Risks: For a deeper look at why these practices matter, review WordPress Database Queries: Securely Using $wpdb and Preparing SQL.
Recap
We have successfully accessed the $wpdb object, learned the vital importance of prepare() to prevent SQL injection, and executed a simple SELECT query. Mastering these database basics is essential for building performant plugins that handle data structures beyond standard WordPress posts. As you grow more comfortable, you can eventually explore advanced topics like WP_Meta_Query to handle complex filtering.
Up next: Secure CRUD Operations with $wpdb.
Work with me

Custom WordPress Plugin Development
Custom WordPress & WooCommerce plugins built to standard โ by the developer behind a plugin with 5,000+ active installs and a SaaS with 10,000+ users.

Laravel REST API Development
Clean, secure, well-documented Laravel REST APIs โ the backend engine for your app, mobile client, or SaaS. Built by an API specialist.