Skip to main content

Strings, Numbers, Dates, and Formatting

String Literals and Concatenation

$single = 'No interpolation';
$double = "Hello {$name}";
$message = 'Hello, ' . $name . '!';

When outputting in WordPress, escape the final value.

echo esc_html($message);
strlen($value);
mb_strlen($value, 'UTF-8');
str_contains($haystack, $needle); // PHP 8+
strpos($haystack, $needle);

When using strpos(), compare strictly.

if (false !== strpos($url, 'example.com')) {
// Found.
}

Replace, Trim, Case

$clean = str_replace(' ', '-', $title);
trim($value);
strtolower($value);
strtoupper($value);
ucfirst($value);

For WordPress slugs, prefer WordPress helpers.

$slug = sanitize_title($title);

Split and Join

$parts = explode(',', $csv);
$csv = implode(',', $parts);

Sanitize after splitting request values.

$tags = array_map('sanitize_key', explode(',', $raw_tags));

sprintf and Translations

$message = sprintf('Found %d items for %s.', $count, $name);
printf(
esc_html__('Found %1$d items for %2$s.', 'my-plugin'),
absint($count),
esc_html($name)
);

Numbers

abs($value);
round($value, 2);
floor($value);
ceil($value);
min($value, 100);
max($value, 1);

WordPress helpers:

absint($raw_id);
number_format_i18n($count);

In WooCommerce, prefer WooCommerce helpers for prices.

wc_price($amount);

Dates and Time

time();
strtotime('+1 day');
date('Y-m-d H:i:s');

In WordPress, prefer site-aware functions.

current_time('mysql');
wp_date(get_option('date_format'), time());

DateTime

$date = new DateTimeImmutable('now', new DateTimeZone('UTC'));
$next = $date->modify('+1 day');

Escaping Strings by Context

ContextFunction
HTML textesc_html()
HTML attributeesc_attr()
URLesc_url()
Textareaesc_textarea()
JavaScript datawp_json_encode()
Allowed post HTMLwp_kses_post()

Sanitizing Strings

GoalFunction
Plain textsanitize_text_field()
Multiline textsanitize_textarea_field()
Emailsanitize_email()
Keysanitize_key()
Slugsanitize_title()
File namesanitize_file_name()
URL for databaseesc_url_raw()

Regular Expressions

if (preg_match('/^[a-z0-9_-]+$/', $key)) {
// Valid key-like value.
}

Use WordPress sanitizers for common web data instead of writing regexes for everything.

Common Pitfalls

  • Using strlen() for user-facing multibyte character counts.
  • Using strpos() without strict comparison.
  • Formatting translated strings by concatenating sentence fragments.
  • Escaping for HTML text when the value is used in an attribute or URL.
  • Using server timezone assumptions instead of WordPress date functions.
  • Displaying raw remote API strings.