Skip to main content

Course Progress

Loading...

PHP Variables, Data Types, and Operators

Duration: 45 minutes
Module 1: Introduction to PHP

Learning Objectives

  • Understand PHP basics
  • Set up PHP development environment
  • Write server-side code
  • Prepare for WordPress development

Understanding the Building Blocks of PHP

Welcome to our exploration of PHP variables, data types, and operators! Today, we'll dive deep into these fundamental concepts that form the foundation of PHP programming. By the end of this lecture, you'll have a solid understanding of how to store, manipulate, and work with different types of data in PHP — essential skills for WordPress development.

Think of variables, data types, and operators as the vocabulary and grammar of the PHP language. Variables are like containers that store information, data types define what kind of information can be stored, and operators are the tools that allow you to work with and manipulate that information. Mastering these concepts is crucial for creating dynamic and interactive WordPress websites.

PHP Building Blocks PHP Building Blocks Variables Data Types Operators Store data Named containers Dynamic typing Scalar Types Compound Types Special Types Arithmetic Comparison Logical Assignment String & Array

PHP Variables: Dynamic Containers for Data

In PHP, variables are used to store data that can be referenced and manipulated throughout your code. Unlike some other programming languages, PHP is loosely typed, meaning you don't need to declare a variable's type before using it.

Variable Naming Rules

When naming variables in PHP, follow these rules:

  • All variable names must start with a dollar sign ($)
  • The first character after the $ must be a letter (a-z, A-Z) or underscore (_)
  • Subsequent characters can be letters, numbers, or underscores
  • Variable names are case-sensitive ($name and $Name are different variables)
  • Variable names cannot contain spaces or special characters
// Valid variable names
$name = "John";
$_count = 10;
$firstName = "Jane";
$last_name = "Doe";
$price1 = 19.99;
$user_id_2 = 42;

// Invalid variable names
// $1price = 29.99;     // Cannot start with a number
// $user-name = "John"; // Cannot contain hyphens
// $product name = "T-shirt"; // Cannot contain spaces
// $my@email = "test@example.com"; // Cannot contain special characters

Naming Convention Best Practices

While PHP allows various naming styles, it's good to follow consistent conventions:

  • camelCase: First word lowercase, subsequent words capitalized (e.g., $firstName, $isLoggedIn)
  • snake_case: All lowercase with underscores between words (e.g., $first_name, $is_logged_in)
  • Descriptive names: Use names that clearly indicate what the variable contains

WordPress primarily uses snake_case for its variables, so this is a good convention to follow for WordPress development.

Variable Assignment and Reassignment

To create a variable in PHP, simply assign a value to it using the assignment operator (=).

// Variable assignment
$username = "admin";
$post_count = 42;
$is_logged_in = true;

// Variables can be reassigned different values
$counter = 1;     // Integer
$counter = 2;     // New integer value
$counter = "two"; // Now it's a string
$counter = false; // Now it's a boolean

// Variables can be assigned values from expressions
$price = 19.99;
$quantity = 3;
$total = $price * $quantity; // $total is 59.97

Think of PHP variables as labeled containers that can hold different types of data. Unlike strongly typed languages where containers are specifically designed for certain types of content, PHP containers are adaptable — they can hold whatever you put into them.

Variables as Containers $name "John" $counter 1 2 "two" false $total $price * $quantity 59.97 Variables can store different types of data

Variable Scope: Where Variables Live

The scope of a variable determines where in your code that variable can be accessed. PHP has several different variable scopes.

Local Scope

Variables declared within a function have local scope and can only be accessed within that function.

function getUserName() {
    $username = "john_doe"; // Local variable
    echo $username;         // Works fine
}

getUserName(); // Outputs: john_doe
// echo $username;   // Error: Undefined variable

Global Scope

Variables declared outside any function have global scope but are not automatically available inside functions.

$site_name = "My WordPress Site"; // Global variable

function displaySiteName() {
    // echo $site_name;  // Error: Undefined variable
    
    // To use a global variable inside a function, use the 'global' keyword
    global $site_name;
    echo $site_name;  // Now works
    
    // Alternative approach using the $GLOBALS array
    echo $GLOBALS['site_name'];  // Also works
}

Static Variables

Static variables retain their value between function calls.

function countVisits() {
    static $count = 0; // Initialized only the first time the function is called
    $count++;
    echo "Visit count: $count";
}

countVisits(); // Outputs: Visit count: 1
countVisits(); // Outputs: Visit count: 2
countVisits(); // Outputs: Visit count: 3

Superglobal Variables

PHP provides several predefined variables that are always available in all scopes. These are called superglobals.

// Common superglobals
$_GET     // Form data sent via URL parameters
$_POST    // Form data sent via HTTP POST
$_REQUEST // Combined $_GET, $_POST, and $_COOKIE
$_SERVER  // Server and execution environment information
$_SESSION // Session variables
$_COOKIE  // HTTP cookie values
$_FILES   // Uploaded files information
$_ENV     // Environment variables

// Example: Getting a URL parameter
echo "Hello, " . $_GET['name']; // If URL is example.com?name=John

Real-World Example: WordPress Variable Scope

WordPress uses variable scope extensively. Here's an example from a theme template:

// In theme's functions.php
function theme_setup() {
    // Local variable, only available in this function
    $theme_features = ['post-thumbnails', 'custom-logo', 'menus'];
    
    // Register theme features
    foreach ($theme_features as $feature) {
        add_theme_support($feature);
    }
}
add_action('after_setup_theme', 'theme_setup');

// In a template file like single.php
global $post; // Access the global $post object
$post_id = $post->ID;
$post_title = get_the_title($post_id);

// Using WordPress superglobals
$current_user_id = $_SESSION['user_id'] ?? 0;
$referrer = $_SERVER['HTTP_REFERER'] ?? '';

// Static variable in a helper function
function get_view_count() {
    static $views = [];
    
    $post_id = get_the_ID();
    
    if (!isset($views[$post_id])) {
        // First time seeing this post in this PHP execution
        $views[$post_id] = get_post_meta($post_id, 'view_count', true) ?: 0;
        $views[$post_id]++;
        update_post_meta($post_id, 'view_count', $views[$post_id]);
    }
    
    return $views[$post_id];
}

Variable Scope Best Practices

  • Limit the use of global variables as they can lead to hard-to-maintain code
  • Pass data between functions using parameters and return values
  • Use static variables sparingly when persistent state between function calls is needed
  • Always sanitize data from superglobals like $_GET and $_POST to prevent security issues
  • In WordPress, follow the WordPress coding standards for variable usage

Variable Output and Interpolation

PHP provides several ways to output variable values and interpolate them into strings.

$user_name = "Alice";
$post_count = 15;

// Basic output
echo $user_name;    // Outputs: Alice
echo $post_count;   // Outputs: 15

// String concatenation
echo "User: " . $user_name . " has " . $post_count . " posts.";
// Outputs: User: Alice has 15 posts.

// String interpolation (inside double quotes)
echo "User: $user_name has $post_count posts.";
// Outputs: User: Alice has 15 posts.

// Complex variable interpolation with curly braces
$product = "WordPress theme";
echo "The {$product}s are on sale.";  // Disambiguates the variable name
// Outputs: The WordPress themes are on sale.

// Escaping the $ character
echo "The cost is \$19.99";  // Outputs: The cost is $19.99

String Interpolation Best Practices

  • Use double quotes when interpolating variables into strings
  • Use curly braces {$variable} for complex variable names or when embedding variables in strings without spaces
  • For simple concatenation or when not using variables, single quotes are more efficient
  • In WordPress template files, consider using functions like esc_html() to secure output

WordPress Template Example

// Safe variable output in WordPress
$post_title = get_the_title();
$post_date = get_the_date();
$author_id = get_the_author_meta('ID');
$author_name = get_the_author_meta('display_name');

// Unsafe output (avoid this)
echo "Posted by $author_name on $post_date";

// Safe output (use this)
echo esc_html("Posted by $author_name on $post_date");
// or
echo sprintf(
    esc_html__('Posted by %s on %s', 'my-theme-textdomain'),
    esc_html($author_name),
    esc_html($post_date)
);

PHP Data Types: Understanding What You're Working With

PHP supports several data types that define what kind of data can be stored in a variable. Understanding these types is essential for effective PHP programming, especially in WordPress development.

PHP Data Type Categories

PHP Data Type Categories PHPDataTypes + Scalar Types + Compound Types + Special Types ScalarTypes + String + Integer + Float + Boolean CompoundTypes + Array + Object SpecialTypes + NULL + Resource

Checking Variable Types

PHP provides several functions to check a variable's type:

$name = "John";
$age = 30;
$height = 6.2;
$is_admin = true;
$skills = ["PHP", "WordPress", "JavaScript"];
$user = null;

// Check type with gettype()
echo gettype($name);     // string
echo gettype($age);      // integer
echo gettype($height);   // double (float)
echo gettype($is_admin); // boolean
echo gettype($skills);   // array
echo gettype($user);     // NULL

// Check type with specific functions
var_dump(is_string($name));     // bool(true)
var_dump(is_int($age));         // bool(true)
var_dump(is_float($height));    // bool(true)
var_dump(is_bool($is_admin));   // bool(true)
var_dump(is_array($skills));    // bool(true)
var_dump(is_null($user));       // bool(true)

// Get detailed information with var_dump()
var_dump($name);  // string(4) "John"
var_dump($age);   // int(30)
var_dump($skills);  // array(3) { [0]=> string(3) "PHP" [1]=> string(9) "WordPress" [2]=> string(10) "JavaScript" }

Scalar Types: Single Values

String

A string is a sequence of characters, enclosed in single ('') or double ("") quotes.

// String creation
$single_quoted = 'Hello, World!';  // Single quotes
$double_quoted = "Hello, World!";  // Double quotes

// String length
$length = strlen($single_quoted);  // 13

// String functions
$uppercase = strtoupper($single_quoted);  // HELLO, WORLD!
$lowercase = strtolower($single_quoted);  // hello, world!
$replaced = str_replace("World", "PHP", $single_quoted);  // Hello, PHP!
$position = strpos($single_quoted, "World");  // 7 (position where "World" starts)

// Accessing characters by index
$first_char = $single_quoted[0];  // H
$fifth_char = $single_quoted[4];  // o

// Substring
$substring = substr($single_quoted, 0, 5);  // Hello

// Multiline strings with heredoc syntax
$heredoc = <<&ltEOT
This is a multiline string
using the heredoc syntax.
Variables like $length are interpolated.
EOT;

// Multiline strings with nowdoc syntax (no interpolation)
$nowdoc = <<<'EOT'
This is a multiline string
using the nowdoc syntax.
Variables like $length are NOT interpolated.
EOT;
WordPress String Usage Example
// Processing post content in WordPress
function custom_excerpt($content, $length = 55) {
    // Strip HTML tags
    $text = strip_tags($content);
    
    // Trim to specified length
    $text = wp_trim_words($text, $length, '...');
    
    // Wrap in paragraph tags
    return '

' . $text . '

'; } // Create a sanitized slug function create_slug($title) { // Convert to lowercase $slug = strtolower($title); // Replace spaces with hyphens $slug = str_replace(' ', '-', $slug); // Remove special characters $slug = preg_replace('/[^a-z0-9\-]/', '', $slug); // Remove multiple hyphens $slug = preg_replace('/-+/', '-', $slug); return $slug; } // Later in template file $post_content = get_the_content(); echo custom_excerpt($post_content, 25);

Integer

An integer is a whole number without a decimal point.

// Integer literals
$decimal = 42;       // Decimal (base 10)
$octal = 052;        // Octal (base 8) - starts with 0
$hexadecimal = 0x2A; // Hexadecimal (base 16) - starts with 0x
$binary = 0b101010;  // Binary (base 2) - starts with 0b

// All the above equal 42 in decimal

// Integer operations
$sum = 5 + 3;          // 8
$difference = 10 - 7;   // 3
$product = 4 * 2;       // 8
$quotient = 20 / 5;     // 4 (this actually returns a float in PHP)
$remainder = 10 % 3;    // 1 (modulus - remainder after division)
$power = 2 ** 3;        // 8 (exponentiation)

// Integer functions
$absolute = abs(-42);      // 42
$maximum = max(10, 5, 20); // 20
$minimum = min(10, 5, 20); // 5

// Integer overflow (PHP 7.4+)
$max_int = PHP_INT_MAX;       // Largest possible integer
$overflow = $max_int + 1;     // Becomes a float on overflow
WordPress Integer Usage Example
// Pagination calculations in WordPress
function custom_pagination() {
    global $wp_query;
    
    // Get total number of pages
    $total_pages = $wp_query->max_num_pages;
    
    // Exit if only one page
    if ($total_pages <= 1) {
        return;
    }
    
    // Get current page
    $current_page = max(1, get_query_var('paged'));
    
    // Build pagination arguments
    $args = array(
        'base' => get_pagenum_link(1) . '%_%',
        'format' => 'page/%#%',
        'current' => $current_page,
        'total' => $total_pages,
        'prev_text' => '« Previous',
        'next_text' => 'Next »',
    );
    
    return paginate_links($args);
}

// Post view counter
function increment_post_views() {
    $post_id = get_the_ID();
    $view_count = (int) get_post_meta($post_id, 'post_views', true);
    $view_count++;
    update_post_meta($post_id, 'post_views', $view_count);
    return $view_count;
}

Float (Double)

Floats (also called doubles) are numbers with a decimal point or in exponential form.

// Float literals
$regular = 3.14;
$scientific = 2.1e3;  // 2100 (2.1 × 10³)
$scientific_negative = 7e-3;  // 0.007 (7 × 10⁻³)

// Float operations
$sum = 0.1 + 0.2;              // Approximately 0.3
$area = 3.14 * (2.5 ** 2);     // Area of circle with radius 2.5

// Float precision issues
echo (0.1 + 0.2) == 0.3;  // Returns false due to precision issues!
echo abs((0.1 + 0.2) - 0.3) < 0.000001;  // Better comparison for floats

// Float functions
$rounded = round(3.14159, 2);     // 3.14 (rounded to 2 decimal places)
$ceiling = ceil(4.3);             // 5 (next highest integer)
$floor = floor(4.8);              // 4 (next lowest integer)
$formatted = number_format(1234.56, 2, '.', ',');  // "1,234.56"
WordPress Float Usage Example
// WooCommerce price calculation
function calculate_discounted_price($product_id, $discount_percentage) {
    // Get product price
    $product = wc_get_product($product_id);
    $original_price = (float) $product->get_price();
    
    // Calculate discount
    $discount_amount = $original_price * ($discount_percentage / 100);
    $discounted_price = $original_price - $discount_amount;
    
    // Round to 2 decimal places
    $discounted_price = round($discounted_price, 2);
    
    return $discounted_price;
}

// Display with currency symbol
function format_price($price) {
    return get_woocommerce_currency_symbol() . number_format($price, 2, '.', ',');
}

// Usage
$sale_price = calculate_discounted_price(123, 15);  // 15% discount
echo 'Sale price: ' . format_price($sale_price);

Boolean

Booleans represent truth values. They can be either true or false.

// Boolean literals
$is_logged_in = true;
$is_admin = false;

// Boolean from comparisons
$is_valid = ($age >= 18);           // true if $age is 18 or more
$has_permission = ($role == 'admin'); // true if $role equals 'admin'

// Logical operators
$can_edit = $is_logged_in && $is_admin;            // AND - true only if both are true
$should_display = $is_logged_in || $is_public;    // OR - true if either is true
$is_not_admin = !$is_admin;                      // NOT - inverts the value

// If statements with booleans
if ($is_logged_in) {
    echo "Welcome back!";
} else {
    echo "Please log in.";
}

// Truthy and falsy values
// The following are considered false:
// - false
// - 0 and 0.0
// - '' (empty string)
// - '0' (string containing zero)
// - [] (empty array)
// - null
// Everything else is considered true
WordPress Boolean Usage Example
// Conditional content display in WordPress
function display_content_based_on_user() {
    // Check if user is logged in
    $is_logged_in = is_user_logged_in();
    
    // Check user role
    $is_admin = current_user_can('administrator');
    $is_editor = current_user_can('editor');
    
    // Check post conditions
    $is_single_post = is_single();
    $comments_open = comments_open();
    
    // Display different content based on conditions
    if ($is_admin || $is_editor) {
        // Show admin controls
        echo '
Admin/Editor content here
'; } if ($is_logged_in) { // Show content for logged-in users echo '
Logged-in user content
'; } else { // Show content for guests echo '
Guest content
'; } if ($is_single_post && $comments_open) { // Show comments form comments_template(); } // Using boolean return values if (has_post_thumbnail()) { the_post_thumbnail('medium'); } }

Compound Types: Multiple Values

Array

An array is an ordered map that stores multiple values under a single variable name.

// Indexed arrays (numeric keys)
$fruits = ["apple", "banana", "cherry"];  // Current syntax
$colors = array("red", "green", "blue");  // Old syntax

// Accessing array elements
echo $fruits[0];  // apple
echo $colors[2];  // blue

// Associative arrays (string keys)
$user = [
    "name" => "John Doe",
    "email" => "john@example.com",
    "age" => 30
];

// Accessing associative array elements
echo $user["name"];  // John Doe

// Multidimensional arrays
$blog_posts = [
    [
        "title" => "Getting Started with WordPress",
        "author" => "Jane Smith",
        "comments" => 15
    ],
    [
        "title" => "Custom Post Types Explained",
        "author" => "John Doe",
        "comments" => 7
    ]
];

// Accessing multidimensional array elements
echo $blog_posts[0]["title"];  // Getting Started with WordPress
echo $blog_posts[1]["author"]; // John Doe

// Array functions
$count = count($fruits);               // 3 (number of elements)
$exists = in_array("banana", $fruits); // true

// Adding elements
$fruits[] = "dragonfruit";             // Add to the end
array_push($fruits, "elderberry");     // Also adds to the end
array_unshift($fruits, "apricot");     // Add to the beginning

// Removing elements
$last = array_pop($fruits);            // Remove from the end
$first = array_shift($fruits);         // Remove from the beginning

// Combining arrays
$more_fruits = ["fig", "grape"];
$all_fruits = array_merge($fruits, $more_fruits);

// Sorting arrays
sort($fruits);                // Sort indexed array (ascending)
rsort($fruits);               // Sort indexed array (descending)
asort($user);                 // Sort associative array by value
ksort($user);                 // Sort associative array by key

// Looping through arrays
foreach ($fruits as $fruit) {
    echo "$fruit
"; } // Looping with keys foreach ($user as $key => $value) { echo "$key: $value
"; }
WordPress Array Usage Example
// Register custom post type in WordPress
function register_project_post_type() {
    $labels = [
        'name'               => 'Projects',
        'singular_name'      => 'Project',
        'menu_name'          => 'Projects',
        'add_new'            => 'Add New',
        'add_new_item'       => 'Add New Project',
        'edit_item'          => 'Edit Project',
        'new_item'           => 'New Project',
        'view_item'          => 'View Project',
        'search_items'       => 'Search Projects',
        'not_found'          => 'No projects found',
        'not_found_in_trash' => 'No projects found in Trash'
    ];
    
    $args = [
        'labels'             => $labels,
        'public'             => true,
        'publicly_queryable' => true,
        'show_ui'            => true,
        'show_in_menu'       => true,
        'query_var'          => true,
        'rewrite'            => ['slug' => 'project'],
        'capability_type'    => 'post',
        'has_archive'        => true,
        'hierarchical'       => false,
        'menu_position'      => null,
        'supports'           => ['title', 'editor', 'thumbnail', 'excerpt']
    ];
    
    register_post_type('project', $args);
}
add_action('init', 'register_project_post_type');

// Loop through posts in a template
$recent_posts = get_posts([
    'post_type'      => 'post',
    'posts_per_page' => 5,
    'orderby'        => 'date',
    'order'          => 'DESC'
]);

foreach ($recent_posts as $post) {
    setup_postdata($post);
    ?>
    <article>
        <h2><?php the_title(); ?></h2>
        <div class="meta">
            Posted on <?php the_date(); ?> by <?php the_author(); ?>
        </div>
        <?php the_excerpt(); ?>
    </article>
    <?php
}
wp_reset_postdata();

Object

Objects are instances of classes, which encapsulate both data (properties) and behaviors (methods).

// Defining a class
class Post {
    // Properties
    public $title;
    public $content;
    public $author;
    private $published_date;
    
    // Constructor
    public function __construct($title, $content, $author) {
        $this->title = $title;
        $this->content = $content;
        $this->author = $author;
        $this->published_date = date('Y-m-d H:i:s');
    }
    
    // Methods
    public function getExcerpt($length = 55) {
        $excerpt = strip_tags($this->content);
        if (strlen($excerpt) > $length) {
            $excerpt = substr($excerpt, 0, $length) . '...';
        }
        return $excerpt;
    }
    
    public function getPublishedDate($format = 'F j, Y') {
        return date($format, strtotime($this->published_date));
    }
}

// Creating an object
$blog_post = new Post(
    'Learning PHP Objects',
    'This is a post about PHP objects and how to use them effectively.',
    'Jane Doe'
);

// Accessing properties
echo $blog_post->title;   // Learning PHP Objects
echo $blog_post->author;  // Jane Doe

// Calling methods
echo $blog_post->getExcerpt(20);      // This is a post abou...
echo $blog_post->getPublishedDate();  // April 27, 2025
WordPress Object Usage Example
// Working with WordPress post objects
$post_id = 123;
$post = get_post($post_id);  // Returns a WP_Post object

// Accessing post properties
echo $post->ID;             // 123
echo $post->post_title;     // Post title
echo $post->post_content;   // Post content
echo $post->post_status;    // publish, draft, etc.
echo $post->post_author;    // Author ID

// Using WordPress user objects
$current_user = wp_get_current_user();

if ($current_user->exists()) {
    echo 'Welcome, ' . $current_user->display_name;
    echo 'Your email is ' . $current_user->user_email;
    
    // Check user roles
    if (in_array('administrator', $current_user->roles)) {
        echo 'You are an administrator';
    }
}

// Custom class for extending WordPress functionality
class CustomWidget extends WP_Widget {
    public function __construct() {
        parent::__construct(
            'custom_widget',
            'Custom Widget',
            ['description' => 'A custom widget for demonstration']
        );
    }
    
    public function widget($args, $instance) {
        // Output the widget content
        echo $args['before_widget'];
        echo $args['before_title'] . $instance['title'] . $args['after_title'];
        echo '
' . $instance['content'] . '
'; echo $args['after_widget']; } public function form($instance) { // Widget admin form $title = isset($instance['title']) ? $instance['title'] : 'Default Title'; $content = isset($instance['content']) ? $instance['content'] : ''; ?> <p> <label for="<?php echo $this->get_field_id('title'); ?>">Title:</label> <input class="widefat" id="<?php echo $this->get_field_id('title'); ?>" name="<?php echo $this->get_field_name('title'); ?>" type="text" value="<?php echo esc_attr($title); ?>"> </p> <p> <label for="<?php echo $this->get_field_id('content'); ?>">Content:</label> <textarea class="widefat" id="<?php echo $this->get_field_id('content'); ?>" name="<?php echo $this->get_field_name('content'); ?>"><?php echo esc_textarea($content); ?></textarea> </p> <?php } } // Register the widget function register_custom_widget() { register_widget('CustomWidget'); } add_action('widgets_init', 'register_custom_widget');

Special Types

NULL

The NULL data type represents a variable with no value.

// NULL value
$var = null;  // Case-insensitive, can also be written as NULL or Null

// Checking for NULL
if ($var === null) {
    echo "Variable is null";
}

if (is_null($var)) {
    echo "Variable is null";
}

// Nullish coalescing operator (PHP 7+)
$username = $_GET['username'] ?? 'Guest';  // 'Guest' if $_GET['username'] is null or not set
WordPress NULL Usage Example
// Using null in WordPress functions
function get_custom_meta($post_id, $meta_key, $default = null) {
    $value = get_post_meta($post_id, $meta_key, true);
    
    // If empty and not explicitly set to '0', return default
    if (empty($value) && $value !== '0') {
        return $default;
    }
    
    return $value;
}

// Usage
$subtitle = get_custom_meta(get_the_ID(), 'subtitle', 'No subtitle available');

// Checking if a function returned null
$post = get_post(999999);  // Non-existent post
if (is_null($post)) {
    echo "Post not found";
}

// Null coalescing with WordPress options
$logo_url = get_option('custom_logo_url') ?? get_template_directory_uri() . '/images/default-logo.png';

Resource

The resource type is a special data type that holds references to external resources, such as database connections or file handles.

// File resource
$file = fopen('example.txt', 'r');  // Returns a file handle resource

// Check if it's a resource
if (is_resource($file)) {
    // Read from the file
    $content = fread($file, filesize('example.txt'));
    
    // Close the resource when done
    fclose($file);
}

// Database resource (using MySQLi)
$connection = mysqli_connect('localhost', 'username', 'password', 'database');

// Check connection
if (!$connection) {
    die("Connection failed: " . mysqli_connect_error());
}

// Use the connection
$result = mysqli_query($connection, "SELECT * FROM users");

// Close the connection
mysqli_close($connection);
WordPress Resource Usage Example
// WordPress database connection
global $wpdb;  // WordPress database object

// The $wpdb object handles the resource internally
$results = $wpdb->get_results("SELECT ID, post_title FROM {$wpdb->posts} WHERE post_status = 'publish' LIMIT 10");

// File operations in WordPress
function log_custom_actions($message) {
    $log_file = WP_CONTENT_DIR . '/debug.log';
    
    // Open the file for appending
    $file_handle = fopen($log_file, 'a');
    
    if (is_resource($file_handle)) {
        // Write to the log
        fwrite($file_handle, date('[Y-m-d H:i:s] ') . $message . PHP_EOL);
        
        // Close the file
        fclose($file_handle);
        return true;
    }
    
    return false;
}

// Usage
log_custom_actions('User logged in: user123');

Type Juggling and Type Casting

PHP automatically converts between data types as needed (type juggling), but you can also explicitly convert types (type casting).

// Type juggling (automatic conversion)
$sum = "10" + 20;      // 30 (integer) - string converted to integer
$concat = "10" . 20;   // "1020" (string) - integer converted to string

// Type casting (explicit conversion)
$int_val = (int)"42";          // 42 (integer)
$float_val = (float)"3.14";    // 3.14 (float)
$string_val = (string)42;      // "42" (string)
$bool_val = (bool)1;           // true (boolean)
$array_val = (array)"abc";     // ["abc"] (array with one element)

// Alternative casting syntax
$int_val = intval("42");       // 42
$float_val = floatval("3.14"); // 3.14
$string_val = strval(42);      // "42"

// Special cases
$int_from_string = (int)"Hello";  // 0 (non-numeric string converts to 0)
$int_from_float = (int)3.99;      // 3 (decimal part is truncated)
$bool_from_string = (bool)"";     // false (empty string converts to false)
$bool_from_number = (bool)0;      // false (0 converts to false)

// Type checking in conditions
$value = "42";
if ($value == 42) {    // true (loose comparison, type juggling happens)
    echo "Equal (==)";
}
if ($value === 42) {   // false (strict comparison, types must match)
    echo "Identical (===)";
}

Type Conversion Best Practices

  • Use strict comparison (=== and !==) when types must match
  • Explicitly cast variables when you need to ensure a specific type
  • Be cautious when converting from strings to numbers
  • When working with forms, always validate and sanitize input
  • In WordPress, use helper functions like absint() and floatval() for type conversion
WordPress Type Conversion Example
// Form data processing in WordPress
function process_product_form() {
    // Check if form was submitted
    if (!isset($_POST['submit_product'])) {
        return;
    }
    
    // Get and sanitize form data
    $product_name = sanitize_text_field($_POST['product_name']);
    $product_price = floatval($_POST['product_price']);  // Convert to float
    $product_quantity = absint($_POST['product_quantity']);  // Convert to positive integer
    $product_featured = isset($_POST['product_featured']) ? 1 : 0;  // Convert checkbox to 1/0
    
    // Validate data
    $errors = [];
    
    if (empty($product_name)) {
        $errors[] = 'Product name is required.';
    }
    
    if ($product_price <= 0) {
        $errors[] = 'Product price must be greater than zero.';
    }
    
    if ($product_quantity <= 0) {
        $errors[] = 'Product quantity must be greater than zero.';
    }
    
    // If there are errors, return them
    if (!empty($errors)) {
        return $errors;
    }
    
    // All good, save the product
    $product_data = [
        'post_title'   => $product_name,
        'post_type'    => 'product',
        'post_status'  => 'publish'
    ];
    
    $product_id = wp_insert_post($product_data);
    
    // Save product meta
    update_post_meta($product_id, '_price', $product_price);
    update_post_meta($product_id, '_stock', $product_quantity);
    update_post_meta($product_id, '_featured', $product_featured);
    
    return $product_id;
}

PHP Operators: Performing Operations

Operators are symbols that tell PHP to perform specific operations. PHP provides a rich set of operators for various purposes.

Operator Types

PHP Operator Types PHP Operators Arithmetic Assignment Comparison Logical Bitwise String Array Type Execution Increment/Decrement Error Control

Arithmetic Operators

Used for performing basic mathematical operations.

$a = 10;
$b = 3;

echo $a + $b;  // 13 (Addition)
echo $a - $b;  // 7 (Subtraction)
echo $a * $b;  // 30 (Multiplication)
echo $a / $b;  // 3.3333333333333 (Division)
echo $a % $b;  // 1 (Modulus - remainder after division)
echo $a ** $b; // 1000 (Exponentiation - 10^3)
WordPress Arithmetic Example
// Calculate discount percentage
function calculate_discount_percentage($original_price, $sale_price) {
    $discount_amount = $original_price - $sale_price;
    $discount_percentage = ($discount_amount / $original_price) * 100;
    return round($discount_percentage);
}

// Usage
$regular_price = 49.99;
$sale_price = 39.99;
$discount = calculate_discount_percentage($regular_price, $sale_price);
echo "Save {$discount}%"; // "Save 20%"

// Calculate average rating
function get_average_rating($post_id) {
    $ratings = get_post_meta($post_id, 'ratings', true);
    
    if (empty($ratings) || !is_array($ratings)) {
        return 0;
    }
    
    $total = array_sum($ratings);
    $count = count($ratings);
    
    return $count > 0 ? round($total / $count, 1) : 0;
}

Assignment Operators

Used to assign values to variables, often combined with other operations.

$a = 10;      // Basic assignment

// Combined assignment operators
$a += 5;      // Same as: $a = $a + 5;    (now $a is 15)
$a -= 3;      // Same as: $a = $a - 3;    (now $a is 12)
$a *= 2;      // Same as: $a = $a * 2;    (now $a is 24)
$a /= 6;      // Same as: $a = $a / 6;    (now $a is 4)
$a %= 3;      // Same as: $a = $a % 3;    (now $a is 1)
$a **= 3;     // Same as: $a = $a ** 3;   (now $a is 1)

// String concatenation assignment
$str = "Hello";
$str .= " World";  // Same as: $str = $str . " World";  (now $str is "Hello World")
WordPress Assignment Example
// Building HTML output
function get_featured_posts() {
    $args = [
        'post_type'      => 'post',
        'posts_per_page' => 3,
        'meta_key'       => 'featured',
        'meta_value'     => '1'
    ];
    
    $featured_posts = get_posts($args);
    $output = '';
    
    foreach ($featured_posts as $post) {
        setup_postdata($post);
        
        $output .= '<article class="featured-post">';
        $output .= '<h3>' . get_the_title() . '</h3>';
        
        if (has_post_thumbnail()) {
            $output .= get_the_post_thumbnail($post->ID, 'thumbnail');
        }
        
        $output .= '<div class="excerpt">' . get_the_excerpt() . '</div>';
        $output .= '<a href="' . get_permalink() . '" class="read-more">Read More</a>';
        $output .= '</article>';
        
    }
    
    wp_reset_postdata();
    return $output;
}

// Incrementing counters
function increment_custom_counter($counter_name) {
    $current_value = get_option($counter_name, 0);
    $current_value += 1;
    update_option($counter_name, $current_value);
    return $current_value;
}

Comparison Operators

Used to compare two values in conditional expressions.

$a = 10;
$b = 5;
$c = "10";

// Equal
var_dump($a == $b);    // bool(false) - values not equal
var_dump($a == $c);    // bool(true) - values equal (loose comparison)

// Identical
var_dump($a === $c);   // bool(false) - values equal but different types

// Not equal
var_dump($a != $b);    // bool(true)
var_dump($a <> $b);    // bool(true) (alternative)

// Not identical
var_dump($a !== $c);   // bool(true)

// Greater than / less than
var_dump($a > $b);     // bool(true)
var_dump($a < $b);     // bool(false)

// Greater than or equal to / less than or equal to
var_dump($a >= $b);    // bool(true)
var_dump($a <= $b);    // bool(false)

// Spaceship operator (PHP 7+)
// Returns -1 if left is less, 0 if equal, 1 if greater
var_dump($a <=> $b);   // int(1) (10 is greater than 5)
var_dump($b <=> $a);   // int(-1) (5 is less than 10)
var_dump($a <=> 10);   // int(0) (10 is equal to 10)

Comparison Operator Best Practices

  • Use strict comparison (=== and !==) when type matters
  • Be careful with loose comparisons (== and !=) as they can cause unexpected behavior
  • When comparing strings, consider case sensitivity and use strcasecmp() for case-insensitive comparisons
  • For floating-point number comparison, don't use direct equality checks
WordPress Comparison Example
// Conditional content display
function custom_content_display() {
    global $post;
    
    // Get current user
    $current_user = wp_get_current_user();
    $user_id = $current_user->ID;
    
    // Check if this is a specific post type
    if ($post->post_type === 'product') {
        // Product-specific content
    } elseif ($post->post_type === 'course') {
        // Course-specific content
    } else {
        // Default content
    }
    
    // Check if user is logged in and has purchased this product
    if ($user_id !== 0 && has_user_purchased($user_id, $post->ID)) {
        // Show content for customers
        echo '
Premium content here
'; } else { // Show teaser for non-customers echo '
Preview content here
'; echo 'Purchase to unlock full content'; } // Compare dates $publish_date = strtotime($post->post_date); $thirty_days_ago = strtotime('-30 days'); if ($publish_date >= $thirty_days_ago) { echo 'New!'; } }

Logical Operators

Used to combine conditional statements.

$a = true;
$b = false;

// AND
var_dump($a && $b);    // bool(false)
var_dump($a and $b);   // bool(false) (alternative syntax)

// OR
var_dump($a || $b);    // bool(true)
var_dump($a or $b);    // bool(true) (alternative syntax)

// XOR (exclusive OR - true if either is true, but not both)
var_dump($a xor $b);   // bool(true)

// NOT
var_dump(!$a);         // bool(false)

// Logical operators in conditional statements
$age = 25;
$has_membership = true;

if ($age >= 18 && $has_membership) {
    echo "Access granted to all content";
}

if ($age < 18 || !$has_membership) {
    echo "Access restricted";
}

Logical Operator Best Practices

  • Be aware of operator precedence. The && and || operators have higher precedence than and and or
  • Use parentheses to make complex conditions more readable
  • Prefer && and || over and and or for consistency
  • Break complex conditionals into multiple steps for clarity when needed
WordPress Logical Operator Example
// Conditional content display with logical operators
function should_display_banner() {
    // Only show for logged in users who haven't dismissed it
    if (is_user_logged_in() && !get_user_meta(get_current_user_id(), 'dismissed_banner', true)) {
        return true;
    }
    
    // Also show for first-time visitors (no cookie set)
    if (!isset($_COOKIE['visited_before']) && !is_user_logged_in()) {
        // Set cookie for 30 days
        setcookie('visited_before', '1', time() + (30 * 24 * 60 * 60), '/');
        return true;
    }
    
    // Don't show on certain pages
    if (is_page('checkout') || is_page('thank-you') || is_page('login')) {
        return false;
    }
    
    // Special campaign period
    $current_date = current_time('timestamp');
    $campaign_start = strtotime('2025-05-01');
    $campaign_end = strtotime('2025-05-15');
    
    if ($current_date >= $campaign_start && $current_date <= $campaign_end) {
        return true;
    }
    
    return false;
}

// Usage
if (should_display_banner()) {
    echo get_template_part('template-parts/promo-banner');
}

String Operators

Used to concatenate strings.

$first_name = "John";
$last_name = "Doe";

// Concatenation
$full_name = $first_name . " " . $last_name;  // "John Doe"

// Concatenation assignment
$greeting = "Hello, ";
$greeting .= $full_name;  // "Hello, John Doe"
WordPress String Operator Example
// Building custom CSS
function custom_theme_styles() {
    $primary_color = get_theme_mod('primary_color', '#3498db');
    $secondary_color = get_theme_mod('secondary_color', '#2ecc71');
    $font_size = get_theme_mod('base_font_size', '16');
    
    $custom_css = '';
    
    // Build CSS rules
    $custom_css .= "body { font-size: {$font_size}px; }
";
    $custom_css .= "a { color: {$primary_color}; }
";
    $custom_css .= "a:hover { color: {$secondary_color}; }
";
    $custom_css .= ".button { background-color: {$primary_color}; }
";
    $custom_css .= ".button:hover { background-color: {$secondary_color}; }
";
    
    // Output the CSS
    wp_add_inline_style('theme-styles', $custom_css);
}
add_action('wp_enqueue_scripts', 'custom_theme_styles');

// Building SQL queries
function get_filtered_posts($category = '', $tag = '', $author = '') {
    global $wpdb;
    
    $query = "SELECT ID, post_title FROM {$wpdb->posts} WHERE post_status = 'publish' AND post_type = 'post'";
    
    if (!empty($category)) {
        $query .= $wpdb->prepare(" AND ID IN (
            SELECT object_id FROM {$wpdb->term_relationships}
            WHERE term_taxonomy_id IN (
                SELECT term_taxonomy_id FROM {$wpdb->term_taxonomy}
                WHERE term_id IN (
                    SELECT term_id FROM {$wpdb->terms}
                    WHERE slug = %s
                )
            )
        )", $category);
    }
    
    if (!empty($author)) {
        $query .= $wpdb->prepare(" AND post_author = %d", $author);
    }
    
    $query .= " ORDER BY post_date DESC LIMIT 10";
    
    return $wpdb->get_results($query);
}

Array Operators

Used to compare and manipulate arrays.

$array1 = ["a" => "apple", "b" => "banana"];
$array2 = ["c" => "cherry", "d" => "date"];
$array3 = ["a" => "apricot", "e" => "elderberry"];

// Union (+)
// Adds elements from right array to left, but doesn't overwrite existing keys
$union = $array1 + $array2;
// Result: ["a" => "apple", "b" => "banana", "c" => "cherry", "d" => "date"]

// Union with overlapping keys
$overlap = $array1 + $array3;
// Result: ["a" => "apple", "b" => "banana", "e" => "elderberry"]
// Note: $array1's "a" value is kept because the left operand has priority

// Equality (==)
var_dump($array1 == $array3);  // bool(false) - same keys, different values
var_dump($array1 == ["b" => "banana", "a" => "apple"]);  // bool(true) - order doesn't matter

// Identity (===)
var_dump($array1 === ["b" => "banana", "a" => "apple"]);  // bool(false) - order matters
var_dump($array1 === ["a" => "apple", "b" => "banana"]);  // bool(true) - same order, keys, values

// Inequality
var_dump($array1 != $array3);  // bool(true)
var_dump($array1 !== $array3);  // bool(true)
WordPress Array Operator Example
// Merging default arguments with user-provided arguments
function display_posts($args = []) {
    // Default arguments
    $defaults = [
        'post_type'      => 'post',
        'posts_per_page' => 5,
        'orderby'        => 'date',
        'order'          => 'DESC',
        'category'       => ''
    ];
    
    // Merge user arguments with defaults
    // User arguments take precedence over defaults
    $args = $args + $defaults;
    
    // Or use WordPress's wp_parse_args function (which uses array_merge)
    // $args = wp_parse_args($args, $defaults);
    
    // Use arguments in query
    $query = new WP_Query($args);
    
    // Display posts
    if ($query->have_posts()) {
        while ($query->have_posts()) {
            $query->the_post();
            echo '<h2>' . get_the_title() . '</h2>';

            echo get_the_excerpt();
        }
        wp_reset_postdata();
    }
}

// Compare theme features supported
function theme_supports_all_features() {
    $required_features = ['post-thumbnails', 'custom-logo', 'widgets'];
    $supported_features = [];
    
    foreach ($required_features as $feature) {
        if (current_theme_supports($feature)) {
            $supported_features[] = $feature;
        }
    }
    
    // Check if arrays are identical (same values)
    return $supported_features === $required_features;
}

Other Important PHP Operators

Ternary Operator

A shorthand way to write if-else statements.

// Syntax: condition ? value_if_true : value_if_false
$age = 20;
$status = ($age >= 18) ? "adult" : "minor";  // "adult"

// Nested ternary (use with caution for readability)
$age = 15;
$status = ($age >= 21) ? "adult (21+)" : (($age >= 18) ? "adult" : "minor");  // "minor"

// Ternary shorthand (PHP 5.3+)
// Returns the left operand if it evaluates to true, otherwise returns the right operand
$username = $_GET['username'] ?: "Guest";  // "Guest" if $_GET['username'] is falsy
WordPress Ternary Example
// Conditional class assignment
function get_header_class() {
    return is_admin_bar_showing() ? 'has-admin-bar' : 'no-admin-bar';
}

echo '

Null Coalescing Operator (PHP 7+)

Returns the first operand if it exists and is not null, otherwise returns the second operand.

// Syntax: expr1 ?? expr2
// Return expr1 if it exists and is not null, otherwise expr2

// Without null coalescing
$username = isset($_GET['username']) ? $_GET['username'] : "Guest";

// With null coalescing
$username = $_GET['username'] ?? "Guest";

// Can be chained
$username = $_GET['username'] ?? $_POST['username'] ?? $default_username ?? "Guest";
WordPress Null Coalescing Example
// Get user preferences
function get_user_preference($key, $default = '') {
    $user_id = get_current_user_id();
    
    if ($user_id === 0) {
        return $default;
    }
    
    return get_user_meta($user_id, $key, true) ?? $default;
}

// Theme settings with fallbacks
$theme_mode = $_COOKIE['theme_mode'] ?? get_user_preference('theme_mode') ?? get_theme_mod('default_theme_mode') ?? 'light';

// Form processing
function process_contact_form() {
    $name = $_POST['name'] ?? '';
    $email = $_POST['email'] ?? '';
    $message = $_POST['message'] ?? '';
    
    // Validate
    if (empty($name) || empty($email) || empty($message)) {
        return 'All fields are required.';
    }
    
    // Process form...
}

Nullsafe Operator (PHP 8+)

Allows you to access object properties and methods even if the object might be null.

// Without nullsafe operator
$country = null;
if ($user !== null) {
    if ($user->getAddress() !== null) {
        $country = $user->getAddress()->getCountry();
    }
}

// With nullsafe operator
$country = $user?->getAddress()?->getCountry();

// Also works with array access
$first_item = $items?->get(0)?->name;
WordPress Nullsafe Example (PHP 8+)
// Get post author data safely
function get_author_location() {
    global $post;
    
    // Without nullsafe (PHP < 8)
    if ($post && isset($post->post_author)) {
        $author = get_userdata($post->post_author);
        if ($author && isset($author->location)) {
            return $author->location;
        }
    }
    return 'Unknown';
    
    // With nullsafe (PHP 8+)
    return get_userdata($post?->post_author)?->location ?? 'Unknown';
}

// Access term meta safely
function get_term_image_url($term_id) {
    $term = get_term($term_id);
    $image_id = get_term_meta($term?->term_id, 'image', true);
    $image_url = wp_get_attachment_url($image_id);
    
    return $image_url ?: get_template_directory_uri() . '/images/default-category.jpg';
}

Execution Operator

Executes the given command and returns the output as a string.

// Execution operator (backticks)
$output = `ls -la`;  // Executes "ls -la" command and returns output
echo $output;

// Safer alternative using shell_exec()
$output = shell_exec('ls -la');

// With error checking
$command = 'ping -c 4 example.com';
$output = [];
$return_var = 0;
exec($command, $output, $return_var);

if ($return_var === 0) {
    // Command executed successfully
    echo implode("
", $output);
} else {
    // Command failed
    echo "Error executing command.";
}
Security Warning

The execution operator and related functions can be dangerous if used with unvalidated input. Never use them with user-supplied data to avoid command injection vulnerabilities. In WordPress development, these are rarely needed and generally discouraged for security reasons.

Error Control Operator

Suppresses error messages that might be generated by an expression.

// Error control operator (@)
$file = @file_get_contents('non_existent_file.txt');
// No warning is displayed if the file doesn't exist

// Better alternative with proper error handling
if (file_exists('non_existent_file.txt')) {
    $file = file_get_contents('non_existent_file.txt');
} else {
    $file = '';
    // Handle the error appropriately
}
Error Control Best Practices

The error control operator (@) should be used sparingly. It's generally better to use proper error handling techniques:

  • Check conditions before operations that might fail
  • Use try-catch blocks for exceptions
  • Log errors rather than suppressing them
  • In WordPress, check if functions exist before calling them

Operator Precedence

Operator precedence determines the order in which operators are evaluated in an expression.

// Precedence example
$result = 5 + 3 * 2;  // 11, not 16 because * has higher precedence than +

// Using parentheses to override precedence
$result = (5 + 3) * 2;  // 16, because the addition is performed first

// Complex example
$a = 10;
$b = 5;
$c = 2;

$result = $a + $b * $c - $a / $c;  // 10 + 10 - 5 = 15
$result_with_parentheses = (($a + $b) * $c) - ($a / $c);  // 30 - 5 = 25

Precedence Best Practices

  • Use parentheses to make your code more readable, even when not strictly necessary
  • Don't rely on operator precedence for complex expressions
  • Break complex expressions into multiple steps for better readability
  • When in doubt, use parentheses to make your intentions clear

Practical Applications in WordPress Development

Theme Customization

WordPress themes use variables, data types, and operators extensively for customization.

// Theme customization in functions.php
function theme_customization_register($wp_customize) {
    // Add a section
    $wp_customize->add_section('theme_color_options', [
        'title'       => 'Color Options',
        'description' => 'Customize your theme colors',
        'priority'    => 30
    ]);
    
    // Add a setting
    $wp_customize->add_setting('primary_color', [
        'default'           => '#3498db',
        'sanitize_callback' => 'sanitize_hex_color'
    ]);
    
    // Add a control
    $wp_customize->add_control(new WP_Customize_Color_Control($wp_customize, 'primary_color', [
        'label'    => 'Primary Color',
        'section'  => 'theme_color_options',
        'settings' => 'primary_color'
    ]));
}
add_action('customize_register', 'theme_customization_register');

// Using the customization in templates
function custom_inline_styles() {
    $primary_color = get_theme_mod('primary_color', '#3498db');
    $brightness = hexdec(substr($primary_color, 1, 2)) + 
                  hexdec(substr($primary_color, 3, 2)) + 
                  hexdec(substr($primary_color, 5, 2));
    
    // Determine text color based on background brightness
    $text_color = ($brightness > 382) ? '#333333' : '#ffffff';
    
    $css = "
        .button {
            background-color: {$primary_color};
            color: {$text_color};
        }
        .header {
            border-bottom: 3px solid {$primary_color};
        }
    ";
    
    wp_add_inline_style('theme-style', $css);
}
add_action('wp_enqueue_scripts', 'custom_inline_styles');

Custom Post Type Registration

Using arrays and operator for registering custom post types.

// Register a custom post type
function register_event_post_type() {
    $labels = [
        'name'               => 'Events',
        'singular_name'      => 'Event',
        'menu_name'          => 'Events',
        'add_new'            => 'Add New',
        'add_new_item'       => 'Add New Event',
        'edit_item'          => 'Edit Event',
        'new_item'           => 'New Event',
        'view_item'          => 'View Event',
        'search_items'       => 'Search Events',
        'not_found'          => 'No events found',
        'not_found_in_trash' => 'No events found in Trash'
    ];
    
    $supports = ['title', 'editor', 'thumbnail'];
    
    // Check if we should support comments based on option
    if (get_option('event_comments_enabled', false)) {
        $supports[] = 'comments';
    }
    
    $args = [
        'labels'              => $labels,
        'public'              => true,
        'publicly_queryable'  => true,
        'show_ui'             => true,
        'show_in_menu'        => true,
        'query_var'           => true,
        'rewrite'             => ['slug' => 'event'],
        'capability_type'     => 'post',
        'has_archive'         => true,
        'hierarchical'        => false,
        'menu_position'       => 5,
        'menu_icon'           => 'dashicons-calendar',
        'supports'            => $supports,
        'show_in_rest'        => true  // Enable Gutenberg editor
    ];
    
    register_post_type('event', $args);
    
    // Register a taxonomy for event categories
    $tax_labels = [
        'name'              => 'Event Categories',
        'singular_name'     => 'Event Category',
        'search_items'      => 'Search Event Categories',
        'all_items'         => 'All Event Categories',
        'parent_item'       => 'Parent Event Category',
        'parent_item_colon' => 'Parent Event Category:',
        'edit_item'         => 'Edit Event Category',
        'update_item'       => 'Update Event Category',
        'add_new_item'      => 'Add New Event Category',
        'new_item_name'     => 'New Event Category Name',
        'menu_name'         => 'Categories'
    ];
    
    $tax_args = [
        'hierarchical'      => true,
        'labels'            => $tax_labels,
        'show_ui'           => true,
        'show_admin_column' => true,
        'query_var'         => true,
        'rewrite'           => ['slug' => 'event-category'],
        'show_in_rest'      => true
    ];
    
    register_taxonomy('event_category', ['event'], $tax_args);
}
add_action('init', 'register_event_post_type');

Custom Meta Boxes

Creating and handling custom meta boxes with different data types.

// Add a meta box
function add_event_details_meta_box() {
    add_meta_box(
        'event_details_meta_box',
        'Event Details',
        'display_event_details_meta_box',
        'event',
        'normal',
        'high'
    );
}
add_action('add_meta_boxes', 'add_event_details_meta_box');

// Display the meta box content
function display_event_details_meta_box($post) {
    // Retrieve current values
    $event_date = get_post_meta($post->ID, 'event_date', true);
    $event_time = get_post_meta($post->ID, 'event_time', true);
    $event_location = get_post_meta($post->ID, 'event_location', true);
    $event_price = get_post_meta($post->ID, 'event_price', true);
    $is_featured = get_post_meta($post->ID, 'is_featured', true) === '1';
    
    // Add nonce for security
    wp_nonce_field('event_details_meta_box', 'event_details_meta_box_nonce');
    
    // Output the form fields
    ?>
    <p>
    <label for="event_date">Date:</label>
    <input type="date" id="event_date" name="event_date" value="<?php echo esc_attr($event_date); ?>">
</p>
<p>
    <label for="event_time">Time:</label>
    <input type="time" id="event_time" name="event_time" value="<?php echo esc_attr($event_time); ?>">
</p>
<p>
    <label for="event_location">Location:</label>
    <input type="text" id="event_location" name="event_location" value="<?php echo esc_attr($event_location); ?>" style="width: 100%;">
</p>
<p>
    <label for="event_price">Price:</label>
    <input type="number" id="event_price" name="event_price" value="<?php echo esc_attr($event_price); ?>" step="0.01" min="0">
</p>
<p>
    <label for="is_featured">
        <input type="checkbox" id="is_featured" name="is_featured" value="1" <?php checked($is_featured, true); ?>>
        Featured Event
    </label>
</p>

<?php
}

// Save meta box data
function save_event_details_meta_box($post_id) {
    // Check nonce
    if (!isset($_POST['event_details_meta_box_nonce']) || 
        !wp_verify_nonce($_POST['event_details_meta_box_nonce'], 'event_details_meta_box')) {
        return;
    }
    
    // Don't save on autosave
    if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
        return;
    }
    
    // Check permissions
    if (!current_user_can('edit_post', $post_id)) {
        return;
    }
    
    // Save the fields
    $fields = [
        'event_date',
        'event_time',
        'event_location',
        'event_price'
    ];
    
    foreach ($fields as $field) {
        if (isset($_POST[$field])) {
            update_post_meta($post_id, $field, sanitize_text_field($_POST[$field]));
        }
    }
    
    // Checkbox handling (will only be set if checked)
    $is_featured = isset($_POST['is_featured']) ? '1' : '0';
    update_post_meta($post_id, 'is_featured', $is_featured);
}
add_action('save_post_event', 'save_event_details_meta_box');

Common Pitfalls and How to Avoid Them

Type Juggling Issues

PHP's automatic type conversion can sometimes lead to unexpected results.

// Equality vs. Identity
$a = 0;
$b = "0";
$c = "";
$d = null;

// These will all evaluate to true
var_dump($a == $b);  // true - numeric string converted to number
var_dump($b == $c);  // true - empty string evaluates to 0
var_dump($c == $d);  // true - null and empty string both evaluate to falsy

// Use strict comparison to avoid these issues
var_dump($a === $b);  // false - different types
var_dump($b === $c);  // false - different values
var_dump($c === $d);  // false - different types

Best Practices

  • Use strict comparison (=== and !==) when type is important
  • Validate and sanitize input from users or external sources
  • Be explicit about type conversions when needed
  • Be aware of truthy and falsy values in PHP

Variable Scope Confusion

Misunderstanding variable scope can lead to hard-to-find bugs.

// Common scope mistake
$global_var = "This is global";

function test_function() {
    // This creates a new local variable, not accessing the global one
    $global_var = "This is local";
    echo $global_var;  // Outputs: "This is local"
}

test_function();
echo $global_var;  // Outputs: "This is global" (unchanged)

// To access the global variable
function correct_function() {
    global $global_var;  // Now accessing the global variable
    $global_var = "This has been changed";
    echo $global_var;  // Outputs: "This has been changed"
}

correct_function();
echo $global_var;  // Outputs: "This has been changed" (modified)

Best Practices

  • Minimize the use of global variables
  • Use function parameters and return values to pass data
  • Be explicit about accessing globals with the global keyword
  • In WordPress, use appropriate functions to access global variables (like $wpdb)

Reference Assignment Confusion

PHP allows assigning variables by reference, which can lead to unexpected behavior.

// Regular assignment - creates a copy
$a = 10;
$b = $a;
$b = 20;
echo $a;  // 10 - unchanged

// Reference assignment - creates a reference to the same value
$a = 10;
$b = &$a;  // Note the & symbol
$b = 20;
echo $a;  // 20 - changed because $b is a reference to $a

// References in foreach loops
$numbers = [1, 2, 3, 4, 5];

// With reference
foreach ($numbers as &$number) {
    $number *= 2;
}
// Now $numbers is [2, 4, 6, 8, 10]

// IMPORTANT: $number is still a reference to the last element!
$number = 0;
// Now $numbers is [2, 4, 6, 8, 0]

// Best practice: unset the reference after the loop
foreach ($numbers as &$number) {
    $number += 1;
}
unset($number);  // Important - breaks the reference

Best Practices

  • Use references only when necessary (e.g., for performance with large data structures)
  • Always unset reference variables after using them in loops
  • Document when you're using references to avoid confusion
  • Be careful with functions that return references

String vs. Numeric Keys in Arrays

Array keys can be either strings or integers, but there are some important differences.

// Numeric keys
$array = [10 => "apple", 20 => "banana"];
$array[] = "cherry";  // Adds at index 21 (next available integer)
var_dump($array);

// String keys that look like numbers
$array = ["10" => "apple", "20" => "banana"];  // String keys
$array[] = "cherry";  // Adds at index 0 (next available integer)
var_dump($array);

// Mixing types
$array = [
    10 => "apple",   // Integer key
    "10" => "orange"  // String key that looks like an integer
];
// The second entry overwrites the first because PHP converts numeric strings to integers for array keys
var_dump($array);  // Only contains "orange" at key 10

Best Practices

  • Be consistent with key types in arrays
  • Use string keys for associative arrays and integer keys for indexed arrays
  • Be aware that PHP will convert numeric strings to integers for array keys
  • When working with user input as array keys, consider the type implications

What's Next?

Now that you understand variables, data types, and operators in PHP, we'll continue building your PHP knowledge with:

  • Control structures (if statements, loops, switch statements)
  • Functions and function definitions
  • Working with forms and user input
  • More advanced array operations
  • Object-oriented programming in PHP
  • MySQL database integration
  • WordPress theme and plugin development

Homework Assignment

Create a PHP script that demonstrates your understanding of variables, data types, and operators by building a "Product Manager" script that:

  1. Creates an array of at least five products with the following properties:
    • ID (integer)
    • Name (string)
    • Price (float)
    • Categories (array of strings)
    • In stock (boolean)
    • Features (associative array with at least three key-value pairs)
  2. Implements the following functions:
    • Format product price with currency symbol
    • Calculate discounted price based on percentage
    • Check if a product belongs to a specific category
    • Get the average price of all products
    • Find the most expensive product
  3. Displays all products in an HTML table with the following requirements:
    • Out-of-stock products should have a different background color
    • Products over a certain price should be marked as "Premium"
    • Display both original and 15% discounted price
    • Categories should be displayed as a comma-separated list
  4. Uses proper PHP tags, comments, and error handling

Submit your PHP file to the course learning management system.

Additional Resources