[ Index ] |
PHP Cross Reference of WordPress Trunk (Updated Daily) |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * WordPress implementation for PHP functions either missing from older PHP versions or not included by default. 4 * 5 * This file is loaded extremely early and the functions can be relied upon by drop-ins. 6 * Ergo, please ensure you do not rely on external functions when writing code for this file. 7 * Only use functions built into PHP or are defined in this file and have adequate testing 8 * and error suppression to ensure the file will run correctly and not break websites. 9 * 10 * @package PHP 11 * @access private 12 */ 13 14 // If gettext isn't available. 15 if ( ! function_exists( '_' ) ) { 16 /** 17 * Compat function to mimic _(), an alias of gettext(). 18 * 19 * @since 0.71 20 * 21 * @see https://php.net/manual/en/function.gettext.php 22 * 23 * @param string $message The message being translated. 24 * @return string 25 */ 26 function _( $message ) { 27 return $message; 28 } 29 } 30 31 /** 32 * Returns whether PCRE/u (PCRE_UTF8 modifier) is available for use. 33 * 34 * @ignore 35 * @since 4.2.2 36 * @since 6.9.0 Deprecated the `$set` argument. 37 * @access private 38 * 39 * @param bool $set Deprecated. This argument is no longer used for testing purposes. 40 */ 41 function _wp_can_use_pcre_u( $set = null ) { 42 static $utf8_pcre = null; 43 44 if ( isset( $set ) ) { 45 _deprecated_argument( __FUNCTION__, '6.9.0' ); 46 } 47 48 if ( isset( $utf8_pcre ) ) { 49 return $utf8_pcre; 50 } 51 52 $utf8_pcre = true; 53 set_error_handler( 54 function ( $errno, $errstr ) use ( &$utf8_pcre ) { 55 if ( str_starts_with( $errstr, 'preg_match():' ) ) { 56 $utf8_pcre = false; 57 return true; 58 } 59 60 return false; 61 }, 62 E_WARNING 63 ); 64 65 /* 66 * Attempt to compile a PCRE pattern with the PCRE_UTF8 flag. For 67 * systems lacking Unicode support this will trigger a warning 68 * during compilation, which the error handler will intercept. 69 */ 70 preg_match( '//u', '' ); 71 restore_error_handler(); 72 73 return $utf8_pcre; 74 } 75 76 /** 77 * Indicates if a given slug for a character set represents the UTF-8 text encoding. 78 * 79 * A charset is considered to represent UTF-8 if it is a case-insensitive match 80 * of "UTF-8" with or without the hyphen. 81 * 82 * Example: 83 * 84 * true === _is_utf8_charset( 'UTF-8' ); 85 * true === _is_utf8_charset( 'utf8' ); 86 * false === _is_utf8_charset( 'latin1' ); 87 * false === _is_utf8_charset( 'UTF 8' ); 88 * 89 * // Only strings match. 90 * false === _is_utf8_charset( [ 'charset' => 'utf-8' ] ); 91 * 92 * `is_utf8_charset` should be used outside of this file. 93 * 94 * @ignore 95 * @since 6.6.1 96 * 97 * @param string $charset_slug Slug representing a text character encoding, or "charset". 98 * E.g. "UTF-8", "Windows-1252", "ISO-8859-1", "SJIS". 99 * 100 * @return bool Whether the slug represents the UTF-8 encoding. 101 */ 102 function _is_utf8_charset( $charset_slug ) { 103 if ( ! is_string( $charset_slug ) ) { 104 return false; 105 } 106 107 return ( 108 0 === strcasecmp( 'UTF-8', $charset_slug ) || 109 0 === strcasecmp( 'UTF8', $charset_slug ) 110 ); 111 } 112 113 if ( ! function_exists( 'mb_substr' ) ) : 114 /** 115 * Compat function to mimic mb_substr(). 116 * 117 * @ignore 118 * @since 3.2.0 119 * 120 * @see _mb_substr() 121 * 122 * @param string $string The string to extract the substring from. 123 * @param int $start Position to being extraction from in `$string`. 124 * @param int|null $length Optional. Maximum number of characters to extract from `$string`. 125 * Default null. 126 * @param string|null $encoding Optional. Character encoding to use. Default null. 127 * @return string Extracted substring. 128 */ 129 function mb_substr( $string, $start, $length = null, $encoding = null ) { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.stringFound 130 return _mb_substr( $string, $start, $length, $encoding ); 131 } 132 endif; 133 134 /** 135 * Internal compat function to mimic mb_substr(). 136 * 137 * Only supports UTF-8 and non-shifting single-byte encodings. For all other encodings 138 * expect the substrings to be misaligned. When the given encoding (or the `blog_charset` 139 * if none is provided) isn’t UTF-8 then the function returns the output of {@see \substr()}. 140 * 141 * @ignore 142 * @since 3.2.0 143 * 144 * @param string $str The string to extract the substring from. 145 * @param int $start Character offset at which to start the substring extraction. 146 * @param int|null $length Optional. Maximum number of characters to extract from `$str`. 147 * Default null. 148 * @param string|null $encoding Optional. Character encoding to use. Default null. 149 * @return string Extracted substring. 150 */ 151 function _mb_substr( $str, $start, $length = null, $encoding = null ) { 152 if ( null === $str ) { 153 return ''; 154 } 155 156 // The solution below works only for UTF-8; treat all other encodings as byte streams. 157 if ( ! _is_utf8_charset( $encoding ?? get_option( 'blog_charset' ) ) ) { 158 return is_null( $length ) ? substr( $str, $start ) : substr( $str, $start, $length ); 159 } 160 161 $total_length = ( $start < 0 || $length < 0 ) 162 ? _wp_utf8_codepoint_count( $str ) 163 : 0; 164 165 $normalized_start = $start < 0 166 ? max( 0, $total_length + $start ) 167 : $start; 168 169 /* 170 * The starting offset is provided as characters, which means this needs to 171 * find how many bytes that many characters occupies at the start of the string. 172 */ 173 $starting_byte_offset = _wp_utf8_codepoint_span( $str, 0, $normalized_start ); 174 175 $normalized_length = $length < 0 176 ? max( 0, $total_length - $normalized_start + $length ) 177 : $length; 178 179 /* 180 * This is the main step. It finds how many bytes the given length of code points 181 * occupies in the input, starting at the byte offset calculated above. 182 */ 183 $byte_length = isset( $normalized_length ) 184 ? _wp_utf8_codepoint_span( $str, $starting_byte_offset, $normalized_length ) 185 : ( strlen( $str ) - $starting_byte_offset ); 186 187 // The result is a normal byte-level substring using the computed ranges. 188 return substr( $str, $starting_byte_offset, $byte_length ); 189 } 190 191 if ( ! function_exists( 'mb_strlen' ) ) : 192 /** 193 * Compat function to mimic mb_strlen(). 194 * 195 * @ignore 196 * @since 4.2.0 197 * 198 * @see _mb_strlen() 199 * 200 * @param string $string The string to retrieve the character length from. 201 * @param string|null $encoding Optional. Character encoding to use. Default null. 202 * @return int String length of `$string`. 203 */ 204 function mb_strlen( $string, $encoding = null ) { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.stringFound 205 return _mb_strlen( $string, $encoding ); 206 } 207 endif; 208 209 /** 210 * Internal compat function to mimic mb_strlen(). 211 * 212 * Only supports UTF-8 and non-shifting single-byte encodings. For all other 213 * encodings expect the counts to be wrong. When the given encoding (or the 214 * `blog_charset` if none is provided) isn’t UTF-8 then the function returns 215 * the byte-count of the provided string. 216 * 217 * @ignore 218 * @since 4.2.0 219 * 220 * @param string $str The string to retrieve the character length from. 221 * @param string|null $encoding Optional. Count characters according to this encoding. 222 * Default is to consult `blog_charset`. 223 * @return int Count of code points if UTF-8, byte length otherwise. 224 */ 225 function _mb_strlen( $str, $encoding = null ) { 226 return _is_utf8_charset( $encoding ?? get_option( 'blog_charset' ) ) 227 ? _wp_utf8_codepoint_count( $str ) 228 : strlen( $str ); 229 } 230 231 if ( ! function_exists( 'utf8_encode' ) ) : 232 if ( extension_loaded( 'mbstring' ) ) : 233 /** 234 * Converts a string from ISO-8859-1 to UTF-8. 235 * 236 * @deprecated Use {@see \mb_convert_encoding()} instead. 237 * 238 * @since 6.9.0 239 * 240 * @param string $iso_8859_1_text Text treated as ISO-8859-1 (latin1) bytes. 241 * @return string Text converted into a UTF-8. 242 */ 243 function utf8_encode( $iso_8859_1_text ): string { 244 _deprecated_function( __FUNCTION__, '6.9.0', 'mb_convert_encoding' ); 245 246 return mb_convert_encoding( $iso_8859_1_text, 'UTF-8', 'ISO-8859-1' ); 247 } 248 249 else : 250 /** 251 * @ignore 252 * @private 253 * 254 * @since 6.9.0 255 */ 256 function utf8_encode( $iso_8859_1_text ): string { 257 _deprecated_function( __FUNCTION__, '6.9.0', 'mb_convert_encoding' ); 258 259 return _wp_utf8_encode_fallback( $iso_8859_1_text ); 260 } 261 262 endif; 263 endif; 264 265 if ( ! function_exists( 'utf8_decode' ) ) : 266 if ( extension_loaded( 'mbstring' ) ) : 267 /** 268 * Converts a string from UTF-8 to ISO-8859-1. 269 * 270 * @deprecated Use {@see \mb_convert_encoding()} instead. 271 * 272 * @since 6.9.0 273 * 274 * @param string $utf8_text Text treated as UTF-8. 275 * @return string Text converted into ISO-8859-1. 276 */ 277 function utf8_decode( $utf8_text ): string { 278 _deprecated_function( __FUNCTION__, '6.9.0', 'mb_convert_encoding' ); 279 280 return mb_convert_encoding( $utf8_text, 'ISO-8859-1', 'UTF-8' ); 281 } 282 283 else : 284 /** 285 * @ignore 286 * @private 287 * 288 * @since 6.9.0 289 */ 290 function utf8_decode( $utf8_text ): string { 291 _deprecated_function( __FUNCTION__, '6.9.0', 'mb_convert_encoding' ); 292 293 return _wp_utf8_decode_fallback( $utf8_text ); 294 } 295 296 endif; 297 endif; 298 299 // sodium_crypto_box() was introduced in PHP 7.2. 300 if ( ! function_exists( 'sodium_crypto_box' ) ) { 301 require ABSPATH . WPINC . '/sodium_compat/autoload.php'; 302 } 303 304 if ( ! function_exists( 'is_countable' ) ) { 305 /** 306 * Polyfill for is_countable() function added in PHP 7.3. 307 * 308 * Verify that the content of a variable is an array or an object 309 * implementing the Countable interface. 310 * 311 * @since 4.9.6 312 * 313 * @param mixed $value The value to check. 314 * @return bool True if `$value` is countable, false otherwise. 315 */ 316 function is_countable( $value ) { 317 return ( is_array( $value ) 318 || $value instanceof Countable 319 || $value instanceof SimpleXMLElement 320 || $value instanceof ResourceBundle 321 ); 322 } 323 } 324 325 if ( ! function_exists( 'array_key_first' ) ) { 326 /** 327 * Polyfill for array_key_first() function added in PHP 7.3. 328 * 329 * Get the first key of the given array without affecting 330 * the internal array pointer. 331 * 332 * @since 5.9.0 333 * 334 * @param array $array An array. 335 * @return string|int|null The first key of array if the array 336 * is not empty; `null` otherwise. 337 */ 338 function array_key_first( array $array ) { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.arrayFound 339 if ( empty( $array ) ) { 340 return null; 341 } 342 343 foreach ( $array as $key => $value ) { 344 return $key; 345 } 346 } 347 } 348 349 if ( ! function_exists( 'array_key_last' ) ) { 350 /** 351 * Polyfill for `array_key_last()` function added in PHP 7.3. 352 * 353 * Get the last key of the given array without affecting the 354 * internal array pointer. 355 * 356 * @since 5.9.0 357 * 358 * @param array $array An array. 359 * @return string|int|null The last key of array if the array 360 *. is not empty; `null` otherwise. 361 */ 362 function array_key_last( array $array ) { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.arrayFound 363 if ( empty( $array ) ) { 364 return null; 365 } 366 367 end( $array ); 368 369 return key( $array ); 370 } 371 } 372 373 if ( ! function_exists( 'array_is_list' ) ) { 374 /** 375 * Polyfill for `array_is_list()` function added in PHP 8.1. 376 * 377 * Determines if the given array is a list. 378 * 379 * An array is considered a list if its keys consist of consecutive numbers from 0 to count($array)-1. 380 * 381 * @see https://github.com/symfony/polyfill-php81/tree/main 382 * 383 * @since 6.5.0 384 * 385 * @param array<mixed> $arr The array being evaluated. 386 * @return bool True if array is a list, false otherwise. 387 */ 388 function array_is_list( $arr ) { 389 if ( ( array() === $arr ) || ( array_values( $arr ) === $arr ) ) { 390 return true; 391 } 392 393 $next_key = -1; 394 395 foreach ( $arr as $k => $v ) { 396 if ( ++$next_key !== $k ) { 397 return false; 398 } 399 } 400 401 return true; 402 } 403 } 404 405 if ( ! function_exists( 'str_contains' ) ) { 406 /** 407 * Polyfill for `str_contains()` function added in PHP 8.0. 408 * 409 * Performs a case-sensitive check indicating if needle is 410 * contained in haystack. 411 * 412 * @since 5.9.0 413 * 414 * @param string $haystack The string to search in. 415 * @param string $needle The substring to search for in the `$haystack`. 416 * @return bool True if `$needle` is in `$haystack`, otherwise false. 417 */ 418 function str_contains( $haystack, $needle ) { 419 if ( '' === $needle ) { 420 return true; 421 } 422 423 return false !== strpos( $haystack, $needle ); 424 } 425 } 426 427 if ( ! function_exists( 'str_starts_with' ) ) { 428 /** 429 * Polyfill for `str_starts_with()` function added in PHP 8.0. 430 * 431 * Performs a case-sensitive check indicating if 432 * the haystack begins with needle. 433 * 434 * @since 5.9.0 435 * 436 * @param string $haystack The string to search in. 437 * @param string $needle The substring to search for in the `$haystack`. 438 * @return bool True if `$haystack` starts with `$needle`, otherwise false. 439 */ 440 function str_starts_with( $haystack, $needle ) { 441 if ( '' === $needle ) { 442 return true; 443 } 444 445 return 0 === strpos( $haystack, $needle ); 446 } 447 } 448 449 if ( ! function_exists( 'str_ends_with' ) ) { 450 /** 451 * Polyfill for `str_ends_with()` function added in PHP 8.0. 452 * 453 * Performs a case-sensitive check indicating if 454 * the haystack ends with needle. 455 * 456 * @since 5.9.0 457 * 458 * @param string $haystack The string to search in. 459 * @param string $needle The substring to search for in the `$haystack`. 460 * @return bool True if `$haystack` ends with `$needle`, otherwise false. 461 */ 462 function str_ends_with( $haystack, $needle ) { 463 if ( '' === $haystack ) { 464 return '' === $needle; 465 } 466 467 $len = strlen( $needle ); 468 469 return substr( $haystack, -$len, $len ) === $needle; 470 } 471 } 472 473 if ( ! function_exists( 'array_find' ) ) { 474 /** 475 * Polyfill for `array_find()` function added in PHP 8.4. 476 * 477 * Searches an array for the first element that passes a given callback. 478 * 479 * @since 6.8.0 480 * 481 * @param array $array The array to search. 482 * @param callable $callback The callback to run for each element. 483 * @return mixed|null The first element in the array that passes the `$callback`, otherwise null. 484 */ 485 function array_find( array $array, callable $callback ) { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.arrayFound 486 foreach ( $array as $key => $value ) { 487 if ( $callback( $value, $key ) ) { 488 return $value; 489 } 490 } 491 492 return null; 493 } 494 } 495 496 if ( ! function_exists( 'array_find_key' ) ) { 497 /** 498 * Polyfill for `array_find_key()` function added in PHP 8.4. 499 * 500 * Searches an array for the first key that passes a given callback. 501 * 502 * @since 6.8.0 503 * 504 * @param array $array The array to search. 505 * @param callable $callback The callback to run for each element. 506 * @return int|string|null The first key in the array that passes the `$callback`, otherwise null. 507 */ 508 function array_find_key( array $array, callable $callback ) { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.arrayFound 509 foreach ( $array as $key => $value ) { 510 if ( $callback( $value, $key ) ) { 511 return $key; 512 } 513 } 514 515 return null; 516 } 517 } 518 519 if ( ! function_exists( 'array_any' ) ) { 520 /** 521 * Polyfill for `array_any()` function added in PHP 8.4. 522 * 523 * Checks if any element of an array passes a given callback. 524 * 525 * @since 6.8.0 526 * 527 * @param array $array The array to check. 528 * @param callable $callback The callback to run for each element. 529 * @return bool True if any element in the array passes the `$callback`, otherwise false. 530 */ 531 function array_any( array $array, callable $callback ): bool { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.arrayFound 532 foreach ( $array as $key => $value ) { 533 if ( $callback( $value, $key ) ) { 534 return true; 535 } 536 } 537 538 return false; 539 } 540 } 541 542 if ( ! function_exists( 'array_all' ) ) { 543 /** 544 * Polyfill for `array_all()` function added in PHP 8.4. 545 * 546 * Checks if all elements of an array pass a given callback. 547 * 548 * @since 6.8.0 549 * 550 * @param array $array The array to check. 551 * @param callable $callback The callback to run for each element. 552 * @return bool True if all elements in the array pass the `$callback`, otherwise false. 553 */ 554 function array_all( array $array, callable $callback ): bool { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.arrayFound 555 foreach ( $array as $key => $value ) { 556 if ( ! $callback( $value, $key ) ) { 557 return false; 558 } 559 } 560 561 return true; 562 } 563 } 564 565 if ( ! function_exists( 'array_first' ) ) { 566 /** 567 * Polyfill for `array_first()` function added in PHP 8.5. 568 * 569 * Returns the first element of an array. 570 * 571 * @since 6.9.0 572 * 573 * @param array $array The array to get the first element from. 574 * @return mixed|null The first element of the array, or null if the array is empty. 575 */ 576 function array_first( array $array ) { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.arrayFound 577 if ( empty( $array ) ) { 578 return null; 579 } 580 581 foreach ( $array as $value ) { 582 return $value; 583 } 584 } 585 } 586 587 if ( ! function_exists( 'array_last' ) ) { 588 /** 589 * Polyfill for `array_last()` function added in PHP 8.5. 590 * 591 * Returns the last element of an array. 592 * 593 * @since 6.9.0 594 * 595 * @param array $array The array to get the last element from. 596 * @return mixed|null The last element of the array, or null if the array is empty. 597 */ 598 function array_last( array $array ) { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.arrayFound 599 if ( empty( $array ) ) { 600 return null; 601 } 602 603 return $array[ array_key_last( $array ) ]; 604 } 605 } 606 607 // IMAGETYPE_AVIF constant is only defined in PHP 8.x or later. 608 if ( ! defined( 'IMAGETYPE_AVIF' ) ) { 609 define( 'IMAGETYPE_AVIF', 19 ); 610 } 611 612 // IMG_AVIF constant is only defined in PHP 8.x or later. 613 if ( ! defined( 'IMG_AVIF' ) ) { 614 define( 'IMG_AVIF', IMAGETYPE_AVIF ); 615 } 616 617 // IMAGETYPE_HEIC constant is not yet defined in PHP as of PHP 8.3. 618 if ( ! defined( 'IMAGETYPE_HEIC' ) ) { 619 define( 'IMAGETYPE_HEIC', 99 ); 620 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated : Thu Oct 23 08:20:05 2025 | Cross-referenced by PHPXref |