Skip to content
  1. Home
  2. Fishbone Talk

how-to · · 9 min read

how to add custom php code to wordpress without breaking your site

Where custom PHP belongs in WordPress: a site plugin, a child theme, mu-plugins or a snippets plugin. Which to use, the paste mistakes, and how to undo one.

By Big Bad Agency

Most of our how-tos end the same way: paste the code into a small plugin or your child theme’s functions.php. That sentence assumes you know how to do either, and that you know which one to pick. Most people don’t, and the usual answer they find, “add it to your theme’s functions.php”, is the one that quietly loses the code a few months later.

So here’s the whole thing: the four places custom PHP can live in WordPress, which one we’d use, the mistakes that turn a working snippet into a white screen, and how to get the site back when it happens anyway.

the short answer

Put it in a small plugin of your own. One folder, one PHP file, a five-line header. It survives theme updates and theme switches, you can switch it off from the Plugins screen, and when something breaks you know exactly which file to look at.

Everything below is the reasoning, plus the cases where another place is genuinely better.

option 1: a small plugin you own (what we use)

A plugin is nothing more than a PHP file with a comment at the top that WordPress recognises. You don’t need to publish it anywhere, and it doesn’t need a settings page.

1. Make the file. Create a folder called my-site-tweaks and inside it a file called my-site-tweaks.php:

<?php
/**
 * Plugin Name: My Site Tweaks
 * Description: Small custom changes for this site.
 * Version:     1.0.0
 */

defined( 'ABSPATH' ) || exit;

// Your code goes below this line.

The Plugin Name: line is the only part WordPress strictly needs. The defined( 'ABSPATH' ) || exit; line stops the file doing anything if someone requests it directly in a browser instead of through WordPress.

2. Get it onto the site. Either zip the folder and upload it under Plugins → Add New → Upload Plugin, or copy the folder into wp-content/plugins/ with SFTP or your host’s file manager.

3. Activate it on the Plugins screen. It shows up like any other plugin, under the name you gave it.

4. Add code below the line. Paste the snippet in, save, and test the thing the snippet changes.

Name it after what it does once you have more than one job in it. A plugin called “Engraving Field” that only does the engraving field is easy to switch off on its own when you need to rule it out. A single 900-line “site tweaks” file that does fourteen things isn’t.

option 2: your child theme’s functions.php

This is fine for code that’s genuinely about the look of the site, like registering a menu location, adding an image size, or changing how the theme prints something.

Two rules:

  • Never the parent theme. If you edit functions.php in a theme you downloaded or bought, the next update to that theme replaces the file and your code is gone. No warning and no backup. That’s the classic way a store’s custom checkout field disappears overnight. Use a child theme, whose functions.php is loaded alongside the parent’s and left alone by parent updates.
  • Not for store logic. Code in a theme only runs while that theme is active. Switch themes for a redesign and every snippet in the old child theme stops, including the one that saves your engraving text on orders. Anything that changes what the store does (prices, checkout, order data, emails) belongs in a plugin, so it outlives the design.

option 3: mu-plugins, for code that must never be switched off

WordPress also loads “must-use” plugins: PHP files placed directly in wp-content/mu-plugins/ (create the folder if it doesn’t exist). They run automatically, before normal plugins, and they can’t be deactivated from the admin. They’re listed under a separate Must-Use tab on the Plugins screen.

That makes them right for a small set of things you never want a person to switch off by accident, like a security rule or a fix the whole site depends on. It also makes them awkward for everything else:

  • WordPress only loads PHP files sitting directly in that folder. A plugin dropped in as a subfolder is ignored unless a top-level file loads it.
  • There’s no activate or deactivate, so activation hooks never fire. Code that sets something up “on activation” won’t run there.
  • To switch one off, you delete or rename the file on the server. That’s fine for you, and a surprise for whoever inherits the site.

option 4: a code snippets plugin

Plugins like Code Snippets and WPCode give you an admin screen where you paste PHP, name it and toggle it on and off. For a site where nobody can reach the files, that’s a real convenience, and it’s a reasonable choice.

Know the trade before you rely on one:

  • The code lives in the database, not in a file. It isn’t in your version control or your file backups, and it moves with the database.
  • Every snippet depends on that one plugin. Deactivate it, and every snippet in it stops at once.
  • Code is being saved and run from an admin screen, so who can reach that screen matters. Check which roles can edit snippets.
  • Before you trust one with checkout code, find out how it recovers when a snippet breaks the site.

A plugin file you own does the same job with one fewer moving part, which is why we prefer it. We don’t sell a snippets plugin, or anything else in this post.

what about the theme file editor?

Appearance → Theme File Editor (and Plugins → Plugin File Editor) let you edit PHP straight from the admin. WordPress tries to catch a fatal error when you save there, and refuses the edit if it finds one. That’s a real safety net, but it doesn’t catch everything. A change can save cleanly and still break a page only some visitors reach, like checkout.

Many hosts and security setups switch these editors off entirely with define( 'DISALLOW_FILE_EDIT', true ); in wp-config.php. That’s a sensible default. Edit a copy of the file locally, upload it, and keep the old version until you’ve tested the new one.

the five paste mistakes that break a site

Almost every “I pasted a snippet and the site went white” comes down to one of these.

1. A second <?php. A plugin file starts with <?php once. Snippets online often start with their own <?php, so pasting one into a file that’s already in PHP produces a parse error. Paste everything after the snippet’s opening tag.

2. A closing ?> at the end. Leave it off. Anything after a closing tag, even a blank line, is sent to the browser as output. That can cause “headers already sent” errors, broken redirects and failed downloads. WordPress’s own coding standards omit it.

3. Two functions with the same name. PHP refuses to define a function twice. If two snippets both declare function add_custom_field(), the site stops with “Cannot redeclare”. Give your functions a prefix nobody else will use (we use bb_), or pass an anonymous function straight to the hook the way our how-tos do:

add_filter( 'woocommerce_get_item_data', function ( $item_data, $cart_item ) {
	// ...
	return $item_data;
}, 10, 2 );

4. Calling things before they exist. Plugins load one after another, so when your file runs, WooCommerce or another plugin may not have loaded yet. Code that calls wc_get_product() at the top of the file can fail on one site and work on another, depending on load order. Put your code inside a hook (add_action, add_filter) and it runs later, when everything it needs is there. Every snippet in our posts is already written that way.

5. Pasting straight into the live site. Test on a staging copy if your host gives you one, and take a backup first if it doesn’t. A snippet that touches checkout gets a real test order before you trust it.

when it breaks anyway

If a plugin or theme causes a fatal error, WordPress shows “There has been a critical error on this website” instead of the page. It also emails the site admin a link to recovery mode, which lets you log in with the broken plugin paused so you can fix or deactivate it.

Don’t count on that email. If the site’s mail isn’t set up properly it never arrives. The way back that always works is file access:

  • A plugin: rename its folder in wp-content/plugins/ (for example, my-site-tweaks → my-site-tweaks-off). WordPress can’t find the plugin any more and deactivates it. The site comes back, and you fix the file before renaming it back.
  • An mu-plugin: rename or move the file out of wp-content/mu-plugins/.
  • A child theme’s functions.php: remove the code you added, or restore the previous copy of the file.

This is the strongest argument for option 1. When the broken code is in a plugin of its own, the fix is renaming one folder. When it’s buried in a theme file with everything else, it’s a careful edit under pressure.

the snippets this is for

Every one of these is written to drop straight into a small plugin like the one above:

If a snippet grows past what a small plugin should carry, with settings, a screen for staff, or other people depending on it, that’s when it’s worth a real plugin. That’s most of what our plugins are.

Disagree? Good.

Write to a person: hello@bigbad.agency. We answer within a business day.

Start a project