3v4l.org

run code in 300+ PHP versions simultaneously
<?php // All of the code needed for this test. function __( $text ) { return $text; } /** * Webfonts Schema Validator. * * Validates the webfont schema. */ class WP_Webfonts_Schema_Validator { /** * Valid font styles. * * @since 5.9.0 * * @var string[] */ const VALID_FONT_STYLE = array( 'normal', 'italic', 'oblique', 'inherit', 'initial', 'revert', 'unset' ); /** * Valid font display values. * * @since 5.9.0 * * @var string[] */ const VALID_FONT_DISPLAY = array( 'auto', 'block', 'fallback', 'swap' ); /** * Valid font weight values. * * @since 5.9.0 * * @var string[] */ const VALID_FONT_WEIGHT = array( 'normal', 'bold', 'bolder', 'lighter', 'inherit' ); /** * An array of valid CSS properties for @font-face. * * @since 5.9.0 * * @var string[] */ protected $font_face_properties = array( 'ascend-override', 'descend-override', 'font-display', 'font-family', 'font-stretch', 'font-style', 'font-weight', 'font-variant', 'font-feature-settings', 'font-variation-settings', 'line-gap-override', 'size-adjust', 'src', 'unicode-range', ); /** * Basic schema structure. * * @since 5.9.0 * * @var array */ protected $basic_schema = array( 'provider' => '', 'font-family' => '', 'font-style' => 'normal', 'font-weight' => '400', 'font-display' => 'fallback', ); /** * Webfont being validated. * * Set as a property for performance. * * @var array */ private $webfont = array(); /** * Checks if the given webfont schema is valid. * * @since 5.9.0 * * @param array $webfont Webfont to validate. * @return bool True when valid. False when invalid. */ public function is_valid_schema( array $webfont ) { $is_valid = ( $this->is_valid_provider( $webfont ) && $this->is_valid_font_family( $webfont ) ); if ( ! $is_valid ) { return false; } if ( 'local' === $webfont['provider'] || array_key_exists( 'src', $webfont ) ) { $is_valid = $this->is_src_valid( $webfont ); } return $is_valid; } /** * Checks if the provider is validate. * * @since 5.9.0 * * @param array $webfont Webfont to validate. * @return bool True if valid. False if invalid. */ private function is_valid_provider( array $webfont ) { // @todo check if provider is registered. if ( empty( $webfont['provider'] ) || ! is_string( $webfont['provider'] ) ) { trigger_error( __( 'Webfont provider must be a non-empty string.' ) ); return false; } return true; } /** * Checks if the font family is validate. * * @since 5.9.0 * * @param array $webfont Webfont to validate. * @return bool True when valid. False when invalid. */ private function is_valid_font_family( array $webfont ) { if ( empty( $webfont['font-family'] ) || ! is_string( $webfont['font-family'] ) ) { trigger_error( __( 'Webfont font family must be a non-empty string.' ) ); return false; } return true; } /** * Checks if the "src" value is valid. * * @since 5.9.0 * * @param array $webfont Webfont to validate. * @return bool True if valid. False if invalid. */ private function is_src_valid( $webfont ) { if ( empty( $webfont['src'] ) || ( ! is_string( $webfont['src'] ) && ! is_array( $webfont['src'] ) ) ) { trigger_error( __( 'Webfont src must be a non-empty string or an array of strings.' ) ); return false; } foreach ( (array) $webfont['src'] as $src ) { if ( ! is_string( $src ) ) { trigger_error( __( 'Each webfont src must be a non-empty string.' ) ); return false; } if ( ! $this->is_src_value_valid( $src ) ) { trigger_error( __( 'Webfont src must be a valid URL or a data URI.' ) ); return false; } } return true; } /** * Checks if the given `src` value is valid. * * @since 5.9.0 * * @param string $src Source to validate. * @return bool True when valid. False when invalid. */ private function is_src_value_valid( $src ) { // Validate data URLs. if ( preg_match( '/^data:.+;base64/', $src ) ) { return true; } // Validate URLs. if ( filter_var( $src, FILTER_VALIDATE_URL ) ) { return true; } // Check if it's a URL starting with "//" (omitted protocol). if ( 0 === strpos( $src, '//' ) ) { return true; } // Check if it's a relative URL. if ( 0 === strpos( $src, 'file:./' ) ) { return true; } return false; } /** * Sets valid properties. * * @since 5.9.0 * * @param array $webfont Webfont definition. * @return array Updated webfont. */ public function set_valid_properties( array $webfont ) { $this->webfont = array_merge( $this->basic_schema, $webfont ); $this->set_valid_font_face_property(); $this->set_valid_font_style(); $this->set_valid_font_weight(); $this->set_valid_font_display(); $webfont = $this->webfont; $this->webfont = array(); // Reset property. return $webfont; } /** * Checks if the CSS property is valid for @font-face. * * @since 5.9.0 */ private function set_valid_font_face_property() { foreach ( array_keys( $this->webfont ) as $property ) { /* * Skip valid configuration parameters (these are configuring the webfont * but are not @font-face properties. */ if ( 'provider' === $property ) { continue; } if ( ! in_array( $property, $this->font_face_properties, true ) ) { unset( $this->webfont[ $property ] ); } } } /** * Checks if the font style is validate. * * @since 5.9.0 */ private function set_valid_font_style() { // If empty or not a string, trigger an error and then set the default value. if ( empty( $this->webfont['font-style'] ) || ! is_string( $this->webfont['font-style'] ) ) { trigger_error( __( 'Webfont font style must be a non-empty string.' ) ); } elseif ( // Bail out if the font-weight is a valid value. in_array( $this->webfont['font-style'], self::VALID_FONT_STYLE, true ) || preg_match( '/^oblique\s+(\d+)%/', $this->webfont['font-style'] ) ) { return; } $this->webfont['font-style'] = 'normal'; } /** * Sets a default font weight if invalid. * * @since 5.9.0 */ private function set_valid_font_weight() { // If empty or not a string, trigger an error and then set the default value. if ( empty( $this->webfont['font-weight'] ) || ! is_string( $this->webfont['font-weight'] ) ) { trigger_error( __( 'Webfont font weight must be a non-empty string.' ) ); } elseif ( // Bail out if the font-weight is a valid value. // Check if value is a single font-weight, formatted as a number. in_array( $this->webfont['font-weight'], self::VALID_FONT_WEIGHT, true ) || // Check if value is a single font-weight, formatted as a number. preg_match( '/^(\d+)$/', $this->webfont['font-weight'], $matches ) || // Check if value is a range of font-weights, formatted as a number range. preg_match( '/^(\d+)\s+(\d+)$/', $this->webfont['font-weight'], $matches ) ) { return; } // Not valid. Set the default value. $this->webfont['font-weight'] = '400'; } /** * Sets a default font display if invalid. * * @since 5.9.0 */ private function set_valid_font_display() { if ( ! empty( $this->webfont['font-display'] ) && in_array( $this->webfont['font-display'], self::VALID_FONT_DISPLAY, true ) ) { return; } $this->webfont['font-display'] = 'fallback'; } } class Profiler { private $validator; private $total_in_microseconds = 0.0; private $cycles = 0; public function __construct( $validator ) { $this->validator = $validator; } public function register( array $webfont ) { $webfont = $this->convert_to_kabeb_case( $webfont ); $this->cycles++; $start_time = microtime( true ); // Validate schema. if ( ! $this->validator->is_valid_schema( $webfont ) ) { // return ''; // Skip for this test. } $webfont = $this->validator->set_valid_properties( $webfont ); // Do the registration. // Get stats. $end_time = microtime( true ); $this->total_in_microseconds += ( $end_time - $start_time ) * 1000000.0; // store in microseconds. } private function convert_to_kabeb_case( array $webfont ) { $kebab_case = preg_replace( '/(?<!^)[A-Z]/', '-$0', array_keys( $webfont ) ); $kebab_case = array_map( 'strtolower', $kebab_case ); return array_combine( $kebab_case, array_values( $webfont ) ); } public function get_avg_microseconds() { return $this->total_in_microseconds / $this->cycles; } } // Let's Go! $profiler = new Profiler( new WP_Webfonts_Schema_Validator() ); $webfont = array( 'fontFamily' => 'Source Serif Pro', 'fontWeight' => '200 900', 'fontStyle' => 'normal', 'fontStretch' => 'normal', 'src' => 'file:./assets/fonts/source-serif-pro/SourceSerif4Variable-Roman.ttf.woff2', 'provider' => 'local', ); /** * Benchmark the average time the Validator takes to validate a single webfont. * The profiler is set to 10,000 cycles to get a fair sampling and distribution. */ $num_time_to_run_validator = 10000; // do work. for ( $i = 1; $i <= $num_time_to_run_validator; $i++ ) { $profiler->register( $webfont ); } printf( "Ran %d in %s microseconds", $num_time_to_run_validator, number_format( $profiler->get_avg_microseconds(), 4 ) );
Output for 8.3.6
Ran 10000 in 4.1990 microseconds
Output for 8.3.5
Warning: PHP Startup: Unable to load dynamic library 'sodium.so' (tried: /usr/lib/php/8.3.5/modules/sodium.so (libsodium.so.23: cannot open shared object file: No such file or directory), /usr/lib/php/8.3.5/modules/sodium.so.so (/usr/lib/php/8.3.5/modules/sodium.so.so: cannot open shared object file: No such file or directory)) in Unknown on line 0 Ran 10000 in 3.0553 microseconds
Output for 8.3.4
Ran 10000 in 2.9318 microseconds
Output for 8.3.3
Ran 10000 in 3.3287 microseconds
Output for 8.3.2
Ran 10000 in 1.6985 microseconds
Output for 8.3.1
Ran 10000 in 3.1882 microseconds
Output for 8.3.0
Ran 10000 in 1.7071 microseconds
Output for 8.2.18
Ran 10000 in 3.9805 microseconds
Output for 8.2.17
Ran 10000 in 3.0434 microseconds
Output for 8.2.16
Ran 10000 in 2.9504 microseconds
Output for 8.2.15
Ran 10000 in 3.4366 microseconds
Output for 8.2.14
Ran 10000 in 1.6483 microseconds
Output for 8.2.13
Ran 10000 in 2.7213 microseconds
Output for 8.2.12
Ran 10000 in 1.6361 microseconds
Output for 8.2.11
Ran 10000 in 2.8729 microseconds
Output for 8.2.10
Ran 10000 in 3.1891 microseconds
Output for 8.1.28
Ran 10000 in 3.1056 microseconds
Output for 8.1.27
Ran 10000 in 1.5858 microseconds
Output for 8.1.26
Ran 10000 in 1.6865 microseconds
Output for 8.1.25
Ran 10000 in 1.8417 microseconds
Output for 8.1.24
Ran 10000 in 2.7932 microseconds
Output for 8.1.23
Ran 10000 in 2.7701 microseconds
Output for 8.0.11
Ran 10000 in 2.9277 microseconds
Output for 7.4.24
Ran 10000 in 2.9567 microseconds

preferences:
91.17 ms | 401 KiB | 29 Q