WordPress Development
WordPress Snippet Safety Checklist: Write, Test, Ship, and Recover
A practical checklist for every stage of a WordPress snippet's life — how to write it defensively, test it before activation, ship it without surprises, and recover in minutes when it breaks.
Updated 5 min read Mark Ashton
- wordpress
- security
- workflow
Most snippet incidents are not exotic. A function is declared twice. A WooCommerce call runs before WooCommerce loads. Output is not escaped. A snippet meant for checkout runs on every request. Each of these is preventable with a habit you apply at one stage of the snippet's life.
This is the checklist we use, organized by stage. Print it, paste it into your team wiki, or turn it into a pull-request template.
Stage 1: Write it defensively
Guard against direct access and double loading.
<?php
defined( 'ABSPATH' ) || exit;
if ( ! function_exists( 'acme_hide_company_field' ) ) {
function acme_hide_company_field( array $fields ): array {
unset( $fields['billing']['billing_company'] );
return $fields;
}
}
add_filter( 'woocommerce_checkout_fields', 'acme_hide_company_field' );A second copy of the same snippet — from an import, a restore, or a second plugin — then does nothing instead of throwing "Cannot redeclare function."
Check dependencies before using them. class_exists( 'WooCommerce' ), function_exists( 'acf' ), defined( 'ELEMENTOR_VERSION' ). A deactivated plugin should make your snippet do nothing, not fatal.
Hook at the right time. Code that needs WordPress fully loaded goes in init, wp, or a later hook — not at the top level of the snippet. Most "undefined function" fatals are load-order bugs.
Prefix everything. Functions, constants, options, and CSS classes get a project prefix. Every snippet shares one PHP request with every plugin on the site; generic names collide. There is more on sharing values between snippets in functions.php alternatives.
Handle data safely:
- Sanitize input:
sanitize_text_field(),absint(),sanitize_email() - Escape output:
esc_html(),esc_attr(),esc_url(),wp_kses_post() - Check permissions and intent before changing data:
current_user_can()plus a nonce - Never concatenate SQL: use
$wpdb->prepare()
Avoid work on every request. Remote HTTP calls, uncached queries, and file writes in a global snippet run on every page view. Cache with transients, or scope the snippet to where it is needed.
Document why. One line at the top: what it does, why it exists, who owns it, what it requires. "Hide company field — client request, Sept 2026 — needs WooCommerce 9+" answers the question someone will ask in a year.
Stage 2: Test before you activate
- Parse check. Run
php -lon the file, or let your snippet plugin validate syntax on save. A parse error is the easiest outage to prevent. - Match production's PHP version. Code that works on PHP 8.4 locally can fail on a host running 8.1, and deprecated patterns fail the other way. Test against the oldest version you run.
- Run it somewhere disposable first. WordPress Playground is ideal for quick hook and syntax tests; a staging copy of the site is the right place for anything involving checkout, logins, or third-party plugins.
- Security scan. Look for
eval, unescaped output, raw SQL, and unsanitized superglobals. SnipVault's Security Audit Center scores each snippet and lists findings with line numbers. - Exercise the actual pages. A snippet that parses can still break the one template it touches. Load it.
Stage 3: Ship it without surprises
- Scope it. Use conditional loading so the snippet runs only on the pages, roles, or post types it is for.
- Activate during working hours, not at 6pm on a Friday.
- Change one thing at a time. If three snippets go live together and something breaks, you now have three suspects.
- Keep the previous version. Revision history in your snippet plugin, or Git, means rollback is a click, not a rewrite.
- Verify after activating. Front end, the specific pages the snippet targets,
wp-admin, and — for stores — a test checkout.
Stage 4: Monitor it
- Watch the error log for a day after any PHP change. Enable logging without showing errors to visitors:
// wp-config.php
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'WP_DEBUG_DISPLAY', false );- Review the library quarterly. Plugin updates and WordPress releases make snippets redundant or broken. WordPress 7.1 alone made a whole class of CSS snippets unnecessary.
- Rescan after major updates. A PHP version bump or a WooCommerce major is a good moment for a bulk security audit.
- Delete what you no longer need. Inactive snippets are code nobody is reviewing.
Stage 5: Recover when it breaks anyway
Have the plan before you need it:
- Know your plugin's recovery path. Most snippet plugins offer a safe-mode URL or keep their own admin screen snippet-free. SnipVault never runs snippets on its own admin page, so
/wp-admin/options-general.php?page=snipvaultstays reachable when a snippet breaks the rest of the site. - Know the file-level fallback. With file-based storage, renaming one snippet file over SFTP disables it. With database storage, you need phpMyAdmin or WP-CLI.
- Disable first, debug second. Get the site up, then read the error log on staging.
- Write down what happened and which checklist item would have caught it.
The full step-by-step is in how to recover from a fatal PHP error in a WordPress snippet.
Choosing a snippet plugin that makes this easier
The checklist works with any tool, but some make it much easier to follow:
- Per-snippet error isolation, so one fatal deactivates one snippet, not the site
- File-based storage you can inspect, back up, and disable from the filesystem
- Revision history or Git sync, so rollback is instant
- Conditions, so scope is visible rather than buried in code
- A security scan before activation
- A recovery path that does not depend on the front end working
If you are comparing tools on these points, best WordPress snippet plugins in 2026 goes through each option.
The one-page version
- Guard:
ABSPATH,function_exists, dependency checks - Hook late enough; prefix everything
- Sanitize in, escape out, check capabilities and nonces, prepare SQL
- Lint, match PHP versions, test on staging, scan
- Scope with conditions; ship one change at a time; keep the previous version
- Watch the log; review quarterly; delete dead code
- Know your recovery URL and file-level fallback before you need them