All skills
Skillintermediate

Performance & Security

```php <?php declare(strict_types=1);

Claude Code Knowledge Pack7/10/2026

Overview

Performance & Security


Performance Optimization

Database Query Optimization

<?php
declare(strict_types=1);

/**
 * Efficient database queries
 */

// BAD: Query inside loop
foreach ($post_ids as $post_id) {
    $meta = get_post_meta($post_id, 'my_key', true); // N+1 queries!
}

// GOOD: Batch query with caching
function get_posts_with_meta(array $post_ids): array {
    global $wpdb;

    $ids = implode(',', array_map('intval', $post_ids));

    // Single query for all meta
    $results = $wpdb->get_results($wpdb->prepare("
        SELECT post_id, meta_value
        FROM {$wpdb->postmeta}
        WHERE post_id IN ({$ids})
        AND meta_key = %s
    ", 'my_key'));

    $meta_map = [];
    foreach ($results as $row) {
        $meta_map[$row->post_id] = $row->meta_value;
    }

    return $meta_map;
}

/**
 * Use proper $wpdb methods with prepared statements
 */
function get_custom_data(int $user_id, string $status): array {
    global $wpdb;

    $table = $wpdb->prefix . 'custom_table';

    // GOOD: Prepared statement prevents SQL injection
    return $wpdb->get_results($wpdb->prepare("
        SELECT id, title, created_at
        FROM {$table}
        WHERE user_id = %d
        AND status = %s
        ORDER BY created_at DESC
        LIMIT 100
    ", $user_id, $status));
}

/**
 * Optimize WP_Query
 */
$optimized_query = new WP_Query([
    'post_type'              => 'product',
    'posts_per_page'         => 10,
    'no_found_rows'          => true,  // Skip SQL_CALC_FOUND_ROWS for pagination
    'update_post_meta_cache' => false, // Skip meta cache if not needed
    'update_post_term_cache' => false, // Skip term cache if not needed
    'fields'                 => 'ids', // Only get IDs if that's all you need
]);

/**
 * Use transients for expensive queries
 */
function get_popular_posts(): array {
    $cache_key = 'popular_posts_week';
    $posts = get_transient($cache_key);

    if ($posts === false) {
        $posts = get_posts([
            'post_type'      => 'post',
            'posts_per_page' => 10,
            'meta_key'       => 'views_count',
            'orderby'        => 'meta_value_num',
            'order'          => 'DESC',
            'date_query'     => [
                ['after' => '1 week ago'],
            ],
        ]);

        set_transient($cache_key, $posts, HOUR_IN_SECONDS);
    }

    return $posts;
}

/**
 * Invalidate cache when data changes
 */
add_action('save_post', function(int $post_id): void {
    delete_transient('popular_posts_week');
    delete_transient('featured_posts');
});

Object Caching

<?php
/**
 * WordPress object cache (works with Redis, Memcached)
 */

// Set cache
wp_cache_set('my_data', $data, 'my_plugin', 3600);

// Get cache
$data = wp_cache_get('my_data', 'my_plugin');
if ($data === false) {
    // Cache miss - fetch and set
    $data = expensive_operation();
    wp_cache_set('my_data', $data, 'my_plugin', 3600);
}

// Delete cache
wp_cache_delete('my_data', 'my_plugin');

// Cache with automatic handling
function get_expensive_data(int $id): mixed {
    $cache_key = 'expensive_data_' . $id;
    $cache_group = 'my_plugin';

    $data = wp_cache_get($cache_key, $cache_group);

    if ($data === false) {
        $data = perform_expensive_operation($id);
        wp_cache_set($cache_key, $data, $cache_group, HOUR_IN_SECONDS);
    }

    return $data;
}

/**
 * Fragment caching for expensive HTML
 */
function render_sidebar_widget(): void {
    $cache_key = 'sidebar_widget_html';
    $html = get_transient($cache_key);

    if ($html === false) {
        ob_start();
        // Expensive rendering
        include plugin_dir_path(__FILE__) . 'templates/widget.php';
        $html = ob_get_clean();

        set_transient($cache_key, $html, 15 * MINUTE_IN_SECONDS);
    }

    echo $html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}

Asset Optimization

<?php
/**
 * Efficient script and style loading
 */

// Conditional loading
add_action('wp_enqueue_scripts', function(): void {
    // Only load on specific pages
    if (!is_page('contact')) {
        return;
    }

    wp_enqueue_script('contact-form', ...);
});

// Defer non-critical scripts
add_filter('script_loader_tag', function(string $tag, string $handle): string {
    $defer_scripts = ['analytics', 'social-share', 'comments'];

    if (in_array($handle, $defer_scripts, true)) {
        return str_replace(' src', ' defer src', $tag);
    }

    return $tag;
}, 10, 2);

// Async scripts
add_filter('script_loader_tag', function(string $tag, string $handle): string {
    if ($handle === 'my-async-script') {
        return str_replace(' src', ' async src', $tag);
    }
    return $tag;
}, 10, 2);

// Preload critical assets
add_action('wp_head', function(): void {
    $font_url = get_template_directory_uri() . '/assets/fonts/inter.woff2';
    echo '<link rel="preload" href="' . esc_url($font_url) . '" as="font" type="font/woff2" crossorigin>';
}, 1);

// Remove unused scripts/styles
add_action('wp_enqueue_scripts', function(): void {
    // Remove block library CSS if not using blocks
    if (!is_singular()) {
        wp_dequeue_style('wp-block-library');
        wp_dequeue_style('wp-block-library-theme');
        wp_dequeue_style('global-styles');
    }

    // Remove emoji scripts
    remove_action('wp_head', 'print_emoji_detection_script', 7);
    remove_action('wp_print_styles', 'print_emoji_styles');
}, 100);

/**
 * Combine/minify inline styles
 */
add_action('wp_footer', function(): void {
    // Add critical CSS inline
    $critical_css = file_get_contents(get_template_directory() . '/assets/css/critical.css');
    if ($critical_css) {
        echo '<style id="critical-css">' . $critical_css . '</style>'; // phpcs:ignore
    }
}, 1);

Image Optimization

<?php
/**
 * Image optimization techniques
 */

// Add custom image sizes
add_action('after_setup_theme', function(): void {
    add_image_size('card-thumbnail', 400, 300, true);
    add_image_size('hero-image', 1600, 900, true);
});

// Lazy load images
add_filter('wp_get_attachment_image_attributes', function(array $attr): array {
    $attr['loading'] = 'lazy';
    $attr['decoding'] = 'async';
    return $attr;
});

// Add srcset for responsive images
add_filter('wp_calculate_image_srcset_meta', function(array $image_meta): array {
    // Ensure srcset is calculated
    return $image_meta;
});

// WebP support (requires server-side conversion)
add_filter('wp_generate_attachment_metadata', function(array $metadata, int $attachment_id): array {
    $file = get_attached_file($attachment_id);
    $mime = mime_content_type($file);

    if (in_array($mime, ['image/jpeg', 'image/png'], true)) {
        // Convert to WebP (requires Imagick or GD)
        my_plugin_create_webp_version($file);
    }

    return $metadata;
}, 10, 2);

// Serve WebP with fallback
function get_webp_image_url(string $url): string {
    $webp_url = preg_replace('/\\.(jpe?g|png)$/i', '.webp', $url);
    $webp_path = str_replace(
        wp_upload_dir()['baseurl'],
        wp_upload_dir()['basedir'],
        $webp_url
    );

    if (file_exists($webp_path)) {
        return $webp_url;
    }

    return $url;
}

Database Cleanup

<?php
/**
 * Database maintenance
 */

// Clean up revisions (run via WP-CLI or cron)
function cleanup_post_revisions(int $keep = 5): int {
    global $wpdb;

    $deleted = 0;

    $posts = $wpdb->get_col("
        SELECT ID FROM {$wpdb->posts}
        WHERE post_type = 'revision'
        AND post_parent IN (
            SELECT ID FROM {$wpdb->posts} WHERE post_type IN ('post', 'page')
        )
    ");

    // Group by parent
    $by_parent = [];
    foreach ($posts as $revision_id) {
        $parent = wp_get_post_parent_id($revision_id);
        $by_parent[$parent][] = $revision_id;
    }

    foreach ($by_parent as $parent_id => $revisions) {
        // Keep most recent $keep revisions
        $to_delete = array_slice($revisions, $keep);
        foreach ($to_delete as $revision_id) {
            wp_delete_post_revision($revision_id);
            $deleted++;
        }
    }

    return $deleted;
}

// Clean up orphaned meta
function cleanup_orphaned_postmeta(): int {
    global $wpdb;

    return $wpdb->query("
        DELETE pm FROM {$wpdb->postmeta} pm
        LEFT JOIN {$wpdb->posts} p ON pm.post_id = p.ID
        WHERE p.ID IS NULL
    ");
}

// Clean up transients
function cleanup_expired_transients(): int {
    global $wpdb;

    $time = time();

    return $wpdb->query($wpdb->prepare("
        DELETE a, b FROM {$wpdb->options} a
        INNER JOIN {$wpdb->options} b ON b.option_name = CONCAT('_transient_timeout_', SUBSTRING(a.option_name, 12))
        WHERE a.option_name LIKE %s
        AND b.option_value < %d
    ", '_transient_%', $time));
}

// Schedule cleanup
add_action('init', function(): void {
    if (!wp_next_scheduled('my_plugin_db_cleanup')) {
        wp_schedule_event(time(), 'weekly', 'my_plugin_db_cleanup');
    }
});

add_action('my_plugin_db_cleanup', function(): void {
    cleanup_post_revisions(3);
    cleanup_orphaned_postmeta();
    cleanup_expired_transients();
});

Security Hardening

Input Sanitization

<?php
declare(strict_types=1);

/**
 * Always sanitize user input
 */

// Text fields
$title = sanitize_text_field($_POST['title'] ?? '');
$email = sanitize_email($_POST['email'] ?? '');
$url = esc_url_raw($_POST['url'] ?? '');

// Textarea (allows line breaks)
$content = sanitize_textarea_field($_POST['content'] ?? '');

// HTML content (with allowed tags)
$html = wp_kses_post($_POST['html_content'] ?? '');

// Custom allowed HTML
$allowed_html = [
    'a'      => ['href' => [], 'title' => [], 'target' => []],
    'strong' => [],
    'em'     => [],
    'p'      => ['class' => []],
];
$safe_html = wp_kses($_POST['custom_html'] ?? '', $allowed_html);

// File names
$filename = sanitize_file_name($_POST['filename'] ?? '');

// Keys (alphanumeric, dashes, underscores)
$key = sanitize_key($_POST['key'] ?? '');

// Arrays
$ids = array_map('absint', (array) ($_POST['ids'] ?? []));
$tags = array_map('sanitize_text_field', (array) ($_POST['tags'] ?? []));

// Numbers
$id = absint($_POST['id'] ?? 0);
$price = (float) filter_var($_POST['price'] ?? 0, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);

/**
 * Database-safe queries
 */
global $wpdb;

// ALWAYS use prepared statements
$results = $wpdb->get_results($wpdb->prepare("
    SELECT * FROM {$wpdb->prefix}custom_table
    WHERE user_id = %d
    AND status = %s
    AND created_at > %s
", $user_id, $status, $date));

// Insert with proper escaping
$wpdb->insert(
    $wpdb->prefix . 'custom_table',
    [
        'user_id' => $user_id,
        'title'   => $title,
        'content' => $content,
    ],
    ['%d', '%s', '%s']
);

// Update with proper escaping
$wpdb->update(
    $wpdb->prefix . 'custom_table',
    ['title' => $new_title],
    ['id' => $id],
    ['%s'],
    ['%d']
);

Output Escaping

<?php
/**
 * Always escape output
 */

// HTML context
echo '<h1>' . esc_html($title) . '</h1>';
echo '<p>' . esc_html__('Welcome', 'my-plugin') . '</p>';

// Attributes
echo '<input type="text" value="' . esc_attr($value) . '" />';
echo '<div class="' . esc_attr($class) . '">';
echo '<div data-config="' . esc_attr(wp_json_encode($config)) . '">';

// URLs
echo '<a href="' . esc_url($url) . '">' . esc_html($text) . '</a>';
echo '<img src="' . esc_url($image_url) . '" alt="' . esc_attr($alt) . '" />';

// JavaScript
echo '<script>var config = ' . wp_json_encode($config) . ';</script>';

// Textarea content
echo '<textarea>' . esc_textarea($content) . '</textarea>';

// Allow specific HTML
echo wp_kses_post($html_content);

// Translation with escaping
printf(
    /* translators: %s: user name */
    esc_html__('Hello, %s!', 'my-plugin'),
    esc_html($user_name)
);

/**
 * When outputting large blocks of HTML
 */
?>
<div class="card">
    <h2><?php echo esc_html($card_title); ?></h2>
    <p><?php echo wp_kses_post($card_content); ?></p>
    <a href="<?php echo esc_url($card_link); ?>" class="<?php echo esc_attr($card_class); ?>">
        <?php echo esc_html($card_cta); ?>
    </a>
</div>
<?php

Nonce Verification

<?php
/**
 * Nonces prevent CSRF attacks
 */

// In form
function render_settings_form(): void {
    ?>
    <form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>">
        <?php wp_nonce_field('my_plugin_save_settings', 'my_plugin_nonce'); ?>
        <input type="hidden" name="action" value="my_plugin_save_settings" />

        

        <?php submit_button(__('Save Settings', 'my-plugin')); ?>
    </form>
    <?php
}

// Verify nonce on submission
add_action('admin_post_my_plugin_save_settings', function(): void {
    // Verify nonce
    if (!wp_verify_nonce($_POST['my_plugin_nonce'] ?? '', 'my_plugin_save_settings')) {
        wp_die(
            esc_html__('Security check failed.', 'my-plugin'),
            esc_html__('Error', 'my-plugin'),
            ['response' => 403]
        );
    }

    // Verify capability
    if (!current_user_can('manage_options')) {
        wp_die(
            esc_html__('You do not have permission to perform this action.', 'my-plugin'),
            esc_html__('Error', 'my-plugin'),
            ['response' => 403]
        );
    }

    // Process form
    $settings = [
        'option_1' => sanitize_text_field($_POST['option_1'] ?? ''),
        'option_2' => absint($_POST['option_2'] ?? 0),
    ];

    update_option('my_plugin_settings', $settings);

    wp_safe_redirect(add_query_arg('updated', 'true', wp_get_referer()));
    exit;
});

/**
 * AJAX with nonce
 */

// Localize script with nonce
wp_localize_script('my-script', 'myPluginData', [
    'ajaxUrl' => admin_url('admin-ajax.php'),
    'nonce'   => wp_create_nonce('my_plugin_ajax'),
]);

// JavaScript
// fetch(myPluginData.ajaxUrl, {
//     method: 'POST',
//     headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
//     body: new URLSearchParams({
//         action: 'my_plugin_action',
//         nonce: myPluginData.nonce,
//         data: 'value'
//     })
// });

// Handle AJAX
add_action('wp_ajax_my_plugin_action', function(): void {
    check_ajax_referer('my_plugin_ajax', 'nonce');

    if (!current_user_can('edit_posts')) {
        wp_send_json_error(['message' => 'Unauthorized'], 403);
    }

    $data = sanitize_text_field($_POST['data'] ?? '');

    // Process request
    $result = process_data($data);

    wp_send_json_success(['result' => $result]);
});

Capability Checks

<?php
/**
 * Always verify user capabilities
 */

// Check before displaying admin page
function render_admin_page(): void {
    if (!current_user_can('manage_options')) {
        wp_die(__('You do not have permission to access this page.', 'my-plugin'));
    }

    // Render p