Mahamudul Hasan Rubel
HomeAboutProjectsSkillsExperienceBlogCoursesPhotosContact
Mahamudul Hasan Rubel

Senior Software Engineer crafting high-performance web applications and SaaS platforms.

Navigation

  • Home
  • About
  • Projects
  • Skills
  • Experience
  • Blog
  • Courses
  • Photos
  • Contact

Get in Touch

Available for senior/lead roles and consulting.

bd.mhrubel@gmail.comHire Me

© 2026 Mahamudul Hasan Rubel. All rights reserved.

Built with using Next.js 16 & Tailwind v4

Back to Blog
Lesson 16 of the WordPress Plugin Development: Foundations (PHP & MVC) course
WordPressJune 25, 20263 min read

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.

WordPressPHPSQLDatabasewpdbPlugin Developmentplugin-development

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.

PHP
function 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 %s for strings or %d for integers) to separate the SQL logic from the data. The wpdb::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.

PHP
public 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().

  1. Use global $wpdb;.
  2. Write a query to select the post_title from the {$wpdb->posts} table.
  3. Use a WHERE clause to filter by post_type = 'knowledge-article' and post_status = 'publish'.
  4. Use ORDER BY post_date DESC and LIMIT 1.
  5. Use $wpdb->prepare() to ensure the post_type is passed safely.
  6. 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 skip prepare() 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 $wpdb is powerful, it is often overkill. If you are retrieving post data, prefer using WP_Query or get_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.

Previous lessonSaving Meta DataNext lesson Secure CRUD Operations
Back to Blog

Similar Posts

WordPressJune 25, 20263 min read

Advanced Database Queries: Mastering SQL and Performance in WordPress

Master advanced database queries in WordPress. Learn to write custom SQL JOINs with $wpdb and profile query performance to build scalable, high-speed plugins.

Read more
WordPressWordPressJune 25, 20263 min read

REST API Integration: Exposing Data for External Consumption

Part of the course

WordPress Plugin Development: Foundations (PHP & MVC)

beginner · Lesson 16 of 47

  1. 1

    Plugin Anatomy and File Structure

    3 min
  2. 2

    The Plugin Lifecycle Hooks

    4 min
  3. 3

    Designing for MVC in WordPress

    3 min

Learn to extend the WordPress REST API by registering custom endpoints. We'll show you how to securely serve your Knowledge Base data as structured JSON.

Read more
WordPressWordPressJune 25, 20263 min read

Capability Checks: Securing WordPress Plugins with Authorization

Master WordPress security by implementing capability checks. Learn to use current_user_can to restrict admin features and enforce proper access control.

Read more
4

Defining the Plugin Core Class

4 min
  • 5

    Understanding WordPress Hooks

    4 min
  • 6

    Implementing Custom Action Hooks

    4 min
  • 7

    Managing Hook Priorities

    3 min
  • 8

    Creating Admin Menus

    3 min
  • 9

    The Controller Layer for Admin Pages

    3 min
  • 10

    Registering Custom Post Types

    3 min
  • 11

    Configuring CPT Arguments

    3 min
  • 12

    Introduction to Taxonomies

    3 min
  • 13

    Designing Meta-Boxes

    3 min
  • 14

    Sanitizing User Input

    4 min
  • 15

    Saving Meta Data

    3 min
  • 16

    Database Basics with wpdb

    3 min
  • 17

    Secure CRUD Operations

    3 min
  • 18

    Querying with WP_Query

    3 min
  • 19

    Optimizing Queries

    3 min
  • 20

    The Model Layer for Data

    3 min
  • 21

    Enqueuing Scripts and Styles

    3 min
  • 22

    Plugin Template Hierarchy

    3 min
  • 23

    Creating Frontend Templates

    3 min
  • 24

    Building Shortcodes

    3 min
  • 25

    Advanced Shortcode Logic

    3 min
  • 26

    Introduction to Gutenberg Blocks

    3 min
  • 27

    The Settings API

    3 min
  • 28

    Validating Settings

    3 min
  • 29

    Implementing Nonces

    3 min
  • 30

    Capability Checks

    3 min
  • 31

    Handling Plugin Updates

    3 min
  • 32

    Internationalization (i18n)

    3 min
  • 33

    Debugging WordPress Plugins

    4 min
  • 34

    Unit Testing Foundations

    3 min
  • 35

    Handling AJAX Requests

    3 min
  • 36

    REST API Integration

    3 min
  • 37

    Advanced Database Queries

    3 min
  • 38

    Caching Strategies

    3 min
  • 39

    Plugin Security Best Practices

    Coming soon
  • 40

    Composer for Dependencies

    Coming soon
  • 41

    Theme Integration Hooks

    Coming soon
  • 42

    Managing Assets with Gulp/Webpack

    Coming soon
  • 43

    Documentation Standards

    Coming soon
  • 44

    Plugin Deployment Strategy

    Coming soon
  • 45

    Advanced MVC: Dependency Injection

    Coming soon
  • 46

    Handling Large Datasets

    Coming soon
  • 47

    Error Handling and Logging

    Coming soon
  • View full course