wp-php-toolkit / polyfill
Polyfill component for WordPress.
Requires
- php: >=7.2
- wp-php-toolkit/blockparser: ^0.8
- wp-php-toolkit/html: ^0.8
- dev-trunk
- v0.8.0
- v0.7.9
- v0.7.8
- v0.7.7
- v0.7.6
- v0.7.5
- v0.7.4
- v0.7.3
- v0.7.2
- v0.7.1
- v0.7.0
- v0.6.2
- v0.6.1
- v0.6.0
- v0.5.1
- v0.5.0
- v0.4.1
- v0.4.0
- v0.3.1
- v0.3.0
- v0.2.0
- v0.1.5
- v0.1.4
- v0.1.3
- v0.1.2
- v0.1.1
- v0.1.0
- 0.0.19
- 0.0.18
- 0.0.17
- 0.0.16
- 0.0.15
- v0.0.15-alpha
- 0.0.14
- 0.0.13
- 0.0.12
- 0.0.11
- v0.0.8-alpha
- 0.0.7
- v0.0.7-alpha
- 0.0.6
- v0.0.6-alpha
- v0.0.5-alpha
- v0.0.4-alpha
- v0.0.3-alpha
- v0.0.2-alpha
- v0.0.1-alpha
This package is auto-updated.
Last update: 2026-05-19 20:26:12 UTC
README
| slug | polyfill | ||
|---|---|---|---|
| title | Polyfill | ||
| install | wp-php-toolkit/polyfill | ||
| credit_title | WordPress-shaped compatibility | ||
| credit_body | When WordPress is loaded, every function in this component defers to WordPress. Outside WordPress, the standalone implementations cover the subset toolkit components need from <code>esc_html()</code>, <code>add_filter()</code>, <code>__()</code>, and related helpers. | ||
| see_also |
|
PHP 8 string functions on PHP 7.2+, WordPress hook stubs, and translation/escaping passthroughs so toolkit code runs without booting WordPress.
Why this exists
A lot of WordPress-adjacent code wants to call esc_html(), __(), or apply_filters() without booting WordPress. The polyfill component provides minimal implementations for the subset used by the toolkit, and stays out of the way when WordPress is loaded (every function uses function_exists() guards).
PHP 8 string functions on PHP 7.2
The polyfills define str_contains, str_starts_with, str_ends_with, and array_key_first only when missing.
<?php require '/php-toolkit/vendor/autoload.php'; var_dump( str_starts_with( '/var/www/html', '/var' ) ); var_dump( str_ends_with( 'image.png', '.png' ) ); var_dump( str_contains( 'WordPress Toolkit', 'Toolkit' ) ); $first_key = array_key_first( array( 'alpha' => 1, 'beta' => 2 ) ); echo "first key: {$first_key}\n";
bool(true)
bool(true)
bool(true)
first key: alpha
Escaping and translation stubs
Pass-through implementations let you write code that looks WordPressy and runs anywhere.
<?php require '/php-toolkit/vendor/autoload.php'; echo __( 'Hello, world' ) . "\n"; echo esc_html( '<script>alert("xss")</script>' ) . "\n"; echo esc_attr( 'a "quoted" value' ) . "\n"; echo esc_url( 'https://example.com/?a=1&b=2' ) . "\n";
Hello, world
<script>alert("xss")</script>
a "quoted" value
https://example.com/?a=1&b=2
A simple filter chain
The hook system implements the common filter path: registered callbacks get applied in priority order, and each one transforms the running value.
<?php require '/php-toolkit/vendor/autoload.php'; add_filter( 'sanitize_title', 'trim' ); add_filter( 'sanitize_title', 'strtolower' ); add_filter( 'sanitize_title', function ( $title ) { return preg_replace( '/\s+/', '-', $title ); } ); echo apply_filters( 'sanitize_title', ' My Post Title ' ) . "\n";
my-post-title
Priority ordering and multi-arg passing
Lower priority numbers run first. The fourth argument to add_filter controls how many context values get passed to the callback.
<?php require '/php-toolkit/vendor/autoload.php'; add_filter( 'render_price', function ( $html, $price, $currency ) { return $html . " ({$currency} markup)"; }, 30, 3 ); add_filter( 'render_price', function ( $html, $price ) { return "<strong>{$html}</strong>"; }, 10, 2 ); add_filter( 'render_price', function ( $html, $price, $currency ) { if ( 'EUR' === $currency ) return $html . ' EUR'; return $html . " {$currency}"; }, 20, 3 ); echo apply_filters( 'render_price', '19.99', 19.99, 'EUR' ) . "\n";
<strong>19.99</strong> EUR (EUR markup)
Hook-based extension points in standalone libraries
Use do_action and apply_filters as cheap extension points in your own code, without depending on WordPress.
<?php require '/php-toolkit/vendor/autoload.php'; class ImportPipeline { public function process( array $row ) { $row = apply_filters( 'import_pipeline_normalize', $row ); do_action( 'import_pipeline_row_processed', $row ); return $row; } } add_filter( 'import_pipeline_normalize', function ( $row ) { $row['email'] = strtolower( trim( $row['email'] ) ); return $row; } ); $log = array(); add_action( 'import_pipeline_row_processed', function ( $row ) use ( &$log ) { $log[] = $row['email']; } ); $pipeline = new ImportPipeline(); $pipeline->process( array( 'email' => ' USER@EXAMPLE.COM ' ) ); $pipeline->process( array( 'email' => 'OTHER@example.com' ) ); echo implode( "\n", $log ) . "\n";
user@example.com
other@example.com