Skip to main content

PHP Syntax and Runtime

PHP Tags

<?php
$name = 'WordPress';

Use <?php in normal PHP files. Avoid short tags like <? because they may be disabled. In PHP-only files, omit the closing tag to prevent accidental whitespace output.

<?php
function myplugin_boot(): void {
// Code here.
}

In mixed templates, PHP can be embedded in HTML.

<h1><?php echo esc_html(get_the_title()); ?></h1>

Comments

// Single-line comment

/*
* Multi-line comment.
*/

Use comments to explain intent, constraints, and non-obvious behavior. Do not comment every assignment.

Statements and Semicolons

Most PHP statements end with ;.

$count = 10;
echo $count;

Control structures use braces.

if ($count > 0) {
echo 'Has items';
}

Variables and Constants

$title = 'Hello';
$count = 3;
$enabled = true;

define('MYPLUGIN_VERSION', '1.0.0');
const DEFAULT_LIMIT = 10;

In WordPress plugins, constants are often used for paths, URLs, and versions.

define('MYPLUGIN_FILE', __FILE__);
define('MYPLUGIN_DIR', plugin_dir_path(__FILE__));
define('MYPLUGIN_URL', plugin_dir_url(__FILE__));

Output

echo 'Hello';
print 'Hello';

In WordPress, escape before output.

echo esc_html($title);

Control Flow

if ($score >= 90) {
$grade = 'A';
} elseif ($score >= 80) {
$grade = 'B';
} else {
$grade = 'C';
}
switch ($status) {
case 'draft':
$label = 'Draft';
break;
case 'publish':
$label = 'Published';
break;
default:
$label = 'Unknown';
}

match is strict and returns a value. It requires PHP 8+.

$label = match ($status) {
'draft' => 'Draft',
'publish' => 'Published',
default => 'Unknown',
};

Loops

foreach ($posts as $post) {
echo esc_html($post->post_title);
}
for ($i = 0; $i < 10; $i++) {
echo esc_html((string) $i);
}
while ($query->have_posts()) {
$query->the_post();
the_title('<h2>', '</h2>');
}

Alternative Template Syntax

Common in WordPress templates.

<?php if (have_posts()) : ?>
<?php while (have_posts()) : the_post(); ?>
<h2><?php the_title(); ?></h2>
<?php endwhile; ?>
<?php endif; ?>

Operators

OperatorMeaning
+, -, *, /, %Arithmetic
.String concatenation
=Assignment
==, !=Loose comparison
===, !==Strict comparison
&&, `
??Null coalescing
?:Ternary shorthand

Prefer strict comparisons unless type coercion is intentional.

Includes

StatementBehavior
requireFatal error if missing
includeWarning if missing
require_onceRequire only once
include_onceInclude only once

Use require_once for required plugin files.

require_once MYPLUGIN_DIR . 'includes/settings.php';

Magic Constants

ConstantMeaning
__FILE__Current file path
__DIR__Current directory path
__LINE__Current line number
__FUNCTION__Current function name
__CLASS__Current class name
__METHOD__Current class method
__NAMESPACE__Current namespace

Runtime Settings

SettingPurpose
memory_limitMax memory per request
max_execution_timeMax request runtime
upload_max_filesizeMax uploaded file size
post_max_sizeMax POST body size
display_errorsWhether errors are printed
log_errorsWhether errors are logged

In WordPress, use debug constants.

define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);

Headers and Redirects

Headers must be sent before output.

header('Content-Type: application/json');

In WordPress, prefer helpers.

wp_safe_redirect(admin_url('options-general.php'));
exit;

Common Pitfalls

  • Missing semicolon or mismatched braces.
  • Echoing before redirect or header changes.
  • Closing PHP tags in plugin files and producing whitespace.
  • Using a PHP feature unsupported by the server version.
  • Calling WordPress conditional tags before the main query exists.
  • Registering post types after init.
  • Running expensive code on every request.