Top 17 PHP Best Practices Every Backend Developer Should Follow
This article presents a comprehensive list of 17 essential PHP best‑practice tips—ranging from using absolute paths and custom loaders to proper output buffering, character encoding, session handling, and file permission management—to help developers write cleaner, more maintainable, and secure backend code.
1. Avoid Relative Paths
Using relative paths like require_once('../../lib/some_class.php'); causes excessive path checks, can break when scripts are included from other directories, and fails under scheduled tasks; define an absolute path instead, e.g., define('ROOT', '/var/www/project/'); and include files with require_once(ROOT . 'lib/some_class.php');.
For a more flexible solution, use define('ROOT', pathinfo(__FILE__, PATHINFO_DIRNAME)); so the script works after moving directories.
2. Do Not Use Direct require / include Calls
Instead of multiple raw require_once statements, create a helper function such as:
function load_class($class_name) {
$path = ROOT . '/lib/' . $class_name . '.php';
if (file_exists($path)) {
require_once($path);
}
}
load_class('Database');
load_class('Mail');This improves readability and allows future extensions like searching multiple directories.
3. Keep Debug Code in the Application
Define an ENVIRONMENT constant and conditionally output debug information only in development, while showing generic error messages in production:
define('ENVIRONMENT', 'development');
if (! $db->query($query)) {
if (ENVIRONMENT == 'development') {
echo "$query failed";
} else {
echo "Database error. Please contact administrator";
}
}4. Use Cross‑Platform Command Execution
Wrap system functions ( system, passthru, exec, shell_exec) in a single helper that picks the first available one:
function terminal($command) {
if (function_exists('system')) {
ob_start();
system($command, $return_var);
$output = ob_get_clean();
} elseif (function_exists('passthru')) {
ob_start();
passthru($command, $return_var);
$output = ob_get_clean();
} elseif (function_exists('exec')) {
exec($command, $output, $return_var);
$output = implode("
", $output);
} elseif (function_exists('shell_exec')) {
$output = shell_exec($command);
$return_var = 0;
} else {
$output = 'Command execution not possible on this system';
$return_var = 1;
}
return ['output' => $output, 'status' => $return_var];
}
terminal('ls');5. Write Flexible Functions
Design functions that accept both scalar and array arguments, e.g., a cart‑adding function that handles a single item or a list of items.
function add_to_cart($item_id, $qty) {
if (!is_array($item_id)) {
$_SESSION['cart'][$item_id] = $qty;
} else {
foreach ($item_id as $i_id => $qty) {
$_SESSION['cart'][$i_id] = $qty;
}
}
}6. Omit the Closing PHP Tag
Leaving out ?> prevents accidental whitespace or characters from being sent, which can cause "Headers already sent" errors.
7. Collect Output in One Place (Output Buffering)
Instead of echoing directly throughout the code, return strings from functions and output them after all processing, or use ob_start() / ob_get_clean() to capture and modify output before sending it to the browser.
8. Send Correct MIME Types
When outputting non‑HTML content, set the appropriate header, e.g., header("Content-Type: text/xml"); for XML, header("Content-Type: application/x-javascript"); for JavaScript, or header("Content-Type: text/css"); for CSS.
9. Set Proper MySQL Connection Charset
$c = mysqli_connect($host, $user, $pass);
if (!mysqli_set_charset($c, 'utf8')) {
die('mysqli_set_charset() failed');
}10. Use htmlentities with Correct Encoding
$value = htmlentities($value, ENT_QUOTES, 'UTF-8');11. Let Apache Handle Gzip Compression
Do not use ob_gzhandler in PHP; enable mod_gzip or mod_deflate at the server level.
12. Output Dynamic JavaScript with json_encode
$images = ['myself.png','friends.png','colleagues.png'];
$js_code = 'var images = ' . json_encode($images) . ';';
echo $js_code;13. Check Directory Write Permissions Before Writing Files
if (is_writable($dir)) {
file_put_contents($file_path, $contents);
} else {
die("Directory $dir is not writable or does not exist.");
}14. Set Correct Permissions on Created Files
chmod('/somedir/somefile', 0644); // owner read/write, others read
chmod('/somedir/somefile', 0755); // owner read/write/execute, others read/execute15. Do Not Rely on Submit Button Values
Check the request method and the presence of the submit field instead of its literal value.
if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_POST['submit'])) {
// process form
}16. Use Static Variables for Invariant Values
function delay() {
static $sync_delay = null;
if ($sync_delay === null) {
$sync_delay = get_option('sync_delay');
}
echo "Delaying for $sync_delay seconds...";
sleep($sync_delay);
echo "Done";
}17. Avoid Direct Access to $_SESSION
Wrap session access with application‑specific keys to prevent collisions across multiple apps on the same domain.
define('APP_ID', 'abc_corp_ecommerce');
function session_get($key) {
$k = APP_ID . '.' . $key;
return $_SESSION[$k] ?? false;
}
function session_set($key, $value) {
$k = APP_ID . '.' . $key;
$_SESSION[$k] = $value;
return true;
}Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
21CTO
21CTO (21CTO.com) offers developers community, training, and services, making it your go‑to learning and service platform.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
