| [ 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_chr' ) ) : 114 /** 115 * Compat function to mimic mb_chr(). 116 * 117 * @ignore 118 * @since 7.1.0 119 * 120 * @see _mb_ord() 121 * 122 * @param int $codepoint A Unicode codepoint value, e.g. 128024 for U+1F418 ELEPHANT 123 * @param "UTF-8"|null $encoding Must be 'UTF-8' or null. 124 * @return string|false A string containing the requested character, if it can be represented in the specified encoding or false on failure. 125 */ 126 function mb_chr( $codepoint, $encoding = null ) { 127 return _mb_chr( $codepoint, $encoding ); 128 } 129 endif; 130 131 /** 132 * Internal compat function to mimic mb_chr(). 133 * 134 * @ignore 135 * @since 7.1.0 136 * 137 * @param int $codepoint A Unicode codepoint value, e.g. 128024 for U+1F418 ELEPHANT 138 * @param "UTF-8"|null $encoding Must be 'UTF-8' or null. 139 * @return string|false A string containing the requested character, if it can be represented in the specified encoding or false on failure. 140 */ 141 function _mb_chr( $codepoint, $encoding = null ) { 142 if ( ! is_int( $codepoint ) || ( isset( $encoding ) && 'UTF-8' !== $encoding ) ) { 143 return false; 144 } 145 146 // Pre-check to ensure a valid code point. 147 if ( 148 $codepoint < 0 || 149 ( $codepoint >= 0xD800 && $codepoint <= 0xDFFF ) || 150 $codepoint > 0x10FFFF 151 ) { 152 return false; 153 } 154 155 if ( $codepoint <= 0x7F ) { 156 return chr( $codepoint ); 157 } 158 159 if ( $codepoint <= 0x7FF ) { 160 $byte1 = chr( ( $codepoint >> 6 ) | 0xC0 ); 161 $byte2 = chr( $codepoint & 0x3F | 0x80 ); 162 163 return "{$byte1}{$byte2}"; 164 } 165 166 if ( $codepoint <= 0xFFFF ) { 167 $byte1 = chr( ( $codepoint >> 12 ) | 0xE0 ); 168 $byte2 = chr( ( $codepoint >> 6 ) & 0x3F | 0x80 ); 169 $byte3 = chr( $codepoint & 0x3F | 0x80 ); 170 171 return "{$byte1}{$byte2}{$byte3}"; 172 } 173 174 // Any values above U+10FFFF are eliminated above in the pre-check. 175 $byte1 = chr( ( $codepoint >> 18 ) | 0xF0 ); 176 $byte2 = chr( ( $codepoint >> 12 ) & 0x3F | 0x80 ); 177 $byte3 = chr( ( $codepoint >> 6 ) & 0x3F | 0x80 ); 178 $byte4 = chr( $codepoint & 0x3F | 0x80 ); 179 180 return "{$byte1}{$byte2}{$byte3}{$byte4}"; 181 } 182 183 if ( ! function_exists( 'mb_ord' ) ) : 184 /** 185 * Compat function to mimic mb_ord(). 186 * 187 * @ignore 188 * @since 7.1.0 189 * 190 * @see _mb_ord() 191 * 192 * @param string $string Return the code point at the start of this string. 193 * @param "UTF-8"|null $encoding Must be 'UTF-8' or null. 194 * @return int|false The Unicode code point for the first character of string or false on failure. 195 */ 196 function mb_ord( $string, $encoding = null ) { 197 return _mb_ord( $string, $encoding ); 198 } 199 endif; 200 201 /** 202 * Internal compat function to mimic mb_ord(). 203 * 204 * @ignore 205 * @since 7.1.0 206 * 207 * @param string $string Return the code point at the start of this string. 208 * @param "UTF-8"|null $encoding Must be 'UTF-8' or null. 209 * @return int|false The Unicode code point for the first character of string or false on failure. 210 */ 211 function _mb_ord( $string, $encoding = null ) { 212 if ( ! is_string( $string ) || '' === $string || ( isset( $encoding ) && 'UTF-8' !== $encoding ) ) { 213 return false; 214 } 215 216 $byte_length = 0; 217 $invalid_length = 0; 218 $found_count = _wp_scan_utf8( $string, $byte_length, $invalid_length, null, 1 ); 219 220 if ( 1 !== $found_count ) { 221 return false; 222 } 223 224 // These are valid code points, so no further validation is required. 225 $b0 = ord( $string[0] ); 226 227 switch ( $byte_length ) { 228 case 1: 229 return $b0; 230 231 case 2: 232 return ( 233 ( ( $b0 & 0x1F ) << 6 ) | 234 ( ( ord( $string[1] ) & 0x3F ) ) 235 ); 236 237 case 3: 238 return ( 239 ( ( $b0 & 0x0F ) << 12 ) | 240 ( ( ord( $string[1] ) & 0x3F ) << 6 ) | 241 ( ( ord( $string[2] ) & 0x3F ) ) 242 ); 243 244 case 4: 245 return ( 246 ( ( $b0 & 0x07 ) << 18 ) | 247 ( ( ord( $string[1] ) & 0x3F ) << 12 ) | 248 ( ( ord( $string[2] ) & 0x3F ) << 6 ) | 249 ( ( ord( $string[3] ) & 0x3F ) ) 250 ); 251 } 252 253 return false; 254 } 255 256 if ( ! function_exists( 'mb_substr' ) ) : 257 /** 258 * Compat function to mimic mb_substr(). 259 * 260 * @ignore 261 * @since 3.2.0 262 * 263 * @see _mb_substr() 264 * 265 * @param string $string The string to extract the substring from. 266 * @param int $start Position to being extraction from in `$string`. 267 * @param int|null $length Optional. Maximum number of characters to extract from `$string`. 268 * Default null. 269 * @param string|null $encoding Optional. Character encoding to use. Default null. 270 * @return string Extracted substring. 271 */ 272 function mb_substr( $string, $start, $length = null, $encoding = null ) { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.stringFound 273 return _mb_substr( $string, $start, $length, $encoding ); 274 } 275 endif; 276 277 /** 278 * Internal compat function to mimic mb_substr(). 279 * 280 * Only supports UTF-8 and non-shifting single-byte encodings. For all other encodings 281 * expect the substrings to be misaligned. When the given encoding (or the `blog_charset` 282 * if none is provided) isn’t UTF-8 then the function returns the output of {@see \substr()}. 283 * 284 * @ignore 285 * @since 3.2.0 286 * 287 * @param string $str The string to extract the substring from. 288 * @param int $start Character offset at which to start the substring extraction. 289 * @param int|null $length Optional. Maximum number of characters to extract from `$str`. 290 * Default null. 291 * @param string|null $encoding Optional. Character encoding to use. Default null. 292 * @return string Extracted substring. 293 */ 294 function _mb_substr( $str, $start, $length = null, $encoding = null ) { 295 if ( null === $str ) { 296 return ''; 297 } 298 299 // The solution below works only for UTF-8; treat all other encodings as byte streams. 300 if ( ! _is_utf8_charset( $encoding ?? get_option( 'blog_charset' ) ) ) { 301 return is_null( $length ) ? substr( $str, $start ) : substr( $str, $start, $length ); 302 } 303 304 $total_length = ( $start < 0 || $length < 0 ) 305 ? _wp_utf8_codepoint_count( $str ) 306 : 0; 307 308 $normalized_start = $start < 0 309 ? max( 0, $total_length + $start ) 310 : $start; 311 312 /* 313 * The starting offset is provided as characters, which means this needs to 314 * find how many bytes that many characters occupies at the start of the string. 315 */ 316 $starting_byte_offset = _wp_utf8_codepoint_span( $str, 0, $normalized_start ); 317 318 $normalized_length = $length < 0 319 ? max( 0, $total_length - $normalized_start + $length ) 320 : $length; 321 322 /* 323 * This is the main step. It finds how many bytes the given length of code points 324 * occupies in the input, starting at the byte offset calculated above. 325 */ 326 $byte_length = isset( $normalized_length ) 327 ? _wp_utf8_codepoint_span( $str, $starting_byte_offset, $normalized_length ) 328 : ( strlen( $str ) - $starting_byte_offset ); 329 330 // The result is a normal byte-level substring using the computed ranges. 331 return substr( $str, $starting_byte_offset, $byte_length ); 332 } 333 334 if ( ! function_exists( 'mb_strlen' ) ) : 335 /** 336 * Compat function to mimic mb_strlen(). 337 * 338 * @ignore 339 * @since 4.2.0 340 * 341 * @see _mb_strlen() 342 * 343 * @param string $string The string to retrieve the character length from. 344 * @param string|null $encoding Optional. Character encoding to use. Default null. 345 * @return int String length of `$string`. 346 */ 347 function mb_strlen( $string, $encoding = null ) { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.stringFound 348 return _mb_strlen( $string, $encoding ); 349 } 350 endif; 351 352 /** 353 * Internal compat function to mimic mb_strlen(). 354 * 355 * Only supports UTF-8 and non-shifting single-byte encodings. For all other 356 * encodings expect the counts to be wrong. When the given encoding (or the 357 * `blog_charset` if none is provided) isn’t UTF-8 then the function returns 358 * the byte-count of the provided string. 359 * 360 * @ignore 361 * @since 4.2.0 362 * 363 * @param string $str The string to retrieve the character length from. 364 * @param string|null $encoding Optional. Count characters according to this encoding. 365 * Default is to consult `blog_charset`. 366 * @return int Count of code points if UTF-8, byte length otherwise. 367 */ 368 function _mb_strlen( $str, $encoding = null ) { 369 return _is_utf8_charset( $encoding ?? get_option( 'blog_charset' ) ) 370 ? _wp_utf8_codepoint_count( $str ) 371 : strlen( $str ); 372 } 373 374 if ( ! function_exists( 'utf8_encode' ) ) : 375 if ( extension_loaded( 'mbstring' ) ) : 376 /** 377 * Converts a string from ISO-8859-1 to UTF-8. 378 * 379 * @deprecated Use {@see \mb_convert_encoding()} instead. 380 * 381 * @since 6.9.0 382 * 383 * @param string $iso_8859_1_text Text treated as ISO-8859-1 (latin1) bytes. 384 * @return string Text converted into a UTF-8. 385 */ 386 function utf8_encode( $iso_8859_1_text ): string { 387 _deprecated_function( __FUNCTION__, '6.9.0', 'mb_convert_encoding' ); 388 389 return mb_convert_encoding( $iso_8859_1_text, 'UTF-8', 'ISO-8859-1' ); 390 } 391 392 else : 393 /** 394 * @ignore 395 * @private 396 * 397 * @since 6.9.0 398 */ 399 function utf8_encode( $iso_8859_1_text ): string { 400 _deprecated_function( __FUNCTION__, '6.9.0', 'mb_convert_encoding' ); 401 402 return _wp_utf8_encode_fallback( $iso_8859_1_text ); 403 } 404 405 endif; 406 endif; 407 408 if ( ! function_exists( 'utf8_decode' ) ) : 409 if ( extension_loaded( 'mbstring' ) ) : 410 /** 411 * Converts a string from UTF-8 to ISO-8859-1. 412 * 413 * @deprecated Use {@see \mb_convert_encoding()} instead. 414 * 415 * @since 6.9.0 416 * 417 * @param string $utf8_text Text treated as UTF-8. 418 * @return string Text converted into ISO-8859-1. 419 */ 420 function utf8_decode( $utf8_text ): string { 421 _deprecated_function( __FUNCTION__, '6.9.0', 'mb_convert_encoding' ); 422 423 return mb_convert_encoding( $utf8_text, 'ISO-8859-1', 'UTF-8' ); 424 } 425 426 else : 427 /** 428 * @ignore 429 * @private 430 * 431 * @since 6.9.0 432 */ 433 function utf8_decode( $utf8_text ): string { 434 _deprecated_function( __FUNCTION__, '6.9.0', 'mb_convert_encoding' ); 435 436 return _wp_utf8_decode_fallback( $utf8_text ); 437 } 438 439 endif; 440 endif; 441 442 // sodium_crypto_box() was introduced with Sodium in PHP 7.2, but the extension may not be enabled. 443 if ( ! function_exists( 'sodium_crypto_box' ) ) { 444 require ABSPATH . WPINC . '/sodium_compat/autoload.php'; 445 } 446 447 if ( ! function_exists( 'array_is_list' ) ) { 448 /** 449 * Polyfill for `array_is_list()` function added in PHP 8.1. 450 * 451 * Determines if the given array is a list. 452 * 453 * An array is considered a list if its keys consist of consecutive numbers from 0 to count($array)-1. 454 * 455 * @see https://github.com/symfony/polyfill-php81/tree/main 456 * 457 * @since 6.5.0 458 * 459 * @param array<mixed> $arr The array being evaluated. 460 * @return bool True if array is a list, false otherwise. 461 */ 462 function array_is_list( $arr ) { 463 if ( ( array() === $arr ) || ( array_values( $arr ) === $arr ) ) { 464 return true; 465 } 466 467 $next_key = -1; 468 469 foreach ( $arr as $k => $v ) { 470 if ( ++$next_key !== $k ) { 471 return false; 472 } 473 } 474 475 return true; 476 } 477 } 478 479 if ( ! function_exists( 'str_contains' ) ) { 480 /** 481 * Polyfill for `str_contains()` function added in PHP 8.0. 482 * 483 * Performs a case-sensitive check indicating if needle is 484 * contained in haystack. 485 * 486 * @since 5.9.0 487 * 488 * @param string $haystack The string to search in. 489 * @param string $needle The substring to search for in the `$haystack`. 490 * @return bool True if `$needle` is in `$haystack`, otherwise false. 491 */ 492 function str_contains( $haystack, $needle ) { 493 if ( '' === $needle ) { 494 return true; 495 } 496 497 return false !== strpos( $haystack, $needle ); 498 } 499 } 500 501 if ( ! function_exists( 'str_starts_with' ) ) { 502 /** 503 * Polyfill for `str_starts_with()` function added in PHP 8.0. 504 * 505 * Performs a case-sensitive check indicating if 506 * the haystack begins with needle. 507 * 508 * @since 5.9.0 509 * 510 * @param string $haystack The string to search in. 511 * @param string $needle The substring to search for in the `$haystack`. 512 * @return bool True if `$haystack` starts with `$needle`, otherwise false. 513 */ 514 function str_starts_with( $haystack, $needle ) { 515 if ( '' === $needle ) { 516 return true; 517 } 518 519 return 0 === strpos( $haystack, $needle ); 520 } 521 } 522 523 if ( ! function_exists( 'str_ends_with' ) ) { 524 /** 525 * Polyfill for `str_ends_with()` function added in PHP 8.0. 526 * 527 * Performs a case-sensitive check indicating if 528 * the haystack ends with needle. 529 * 530 * @since 5.9.0 531 * 532 * @param string $haystack The string to search in. 533 * @param string $needle The substring to search for in the `$haystack`. 534 * @return bool True if `$haystack` ends with `$needle`, otherwise false. 535 */ 536 function str_ends_with( $haystack, $needle ) { 537 if ( '' === $haystack ) { 538 return '' === $needle; 539 } 540 541 $len = strlen( $needle ); 542 543 return substr( $haystack, -$len, $len ) === $needle; 544 } 545 } 546 547 if ( ! function_exists( 'array_find' ) ) { 548 /** 549 * Polyfill for `array_find()` function added in PHP 8.4. 550 * 551 * Searches an array for the first element that passes a given callback. 552 * 553 * @since 6.8.0 554 * 555 * @param array $array The array to search. 556 * @param callable $callback The callback to run for each element. 557 * @return mixed|null The first element in the array that passes the `$callback`, otherwise null. 558 */ 559 function array_find( array $array, callable $callback ) { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.arrayFound 560 foreach ( $array as $key => $value ) { 561 if ( $callback( $value, $key ) ) { 562 return $value; 563 } 564 } 565 566 return null; 567 } 568 } 569 570 if ( ! function_exists( 'array_find_key' ) ) { 571 /** 572 * Polyfill for `array_find_key()` function added in PHP 8.4. 573 * 574 * Searches an array for the first key that passes a given callback. 575 * 576 * @since 6.8.0 577 * 578 * @param array $array The array to search. 579 * @param callable $callback The callback to run for each element. 580 * @return int|string|null The first key in the array that passes the `$callback`, otherwise null. 581 */ 582 function array_find_key( array $array, callable $callback ) { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.arrayFound 583 foreach ( $array as $key => $value ) { 584 if ( $callback( $value, $key ) ) { 585 return $key; 586 } 587 } 588 589 return null; 590 } 591 } 592 593 if ( ! function_exists( 'array_any' ) ) { 594 /** 595 * Polyfill for `array_any()` function added in PHP 8.4. 596 * 597 * Checks if any element of an array passes a given callback. 598 * 599 * @since 6.8.0 600 * 601 * @param array $array The array to check. 602 * @param callable $callback The callback to run for each element. 603 * @return bool True if any element in the array passes the `$callback`, otherwise false. 604 */ 605 function array_any( array $array, callable $callback ): bool { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.arrayFound 606 foreach ( $array as $key => $value ) { 607 if ( $callback( $value, $key ) ) { 608 return true; 609 } 610 } 611 612 return false; 613 } 614 } 615 616 if ( ! function_exists( 'array_all' ) ) { 617 /** 618 * Polyfill for `array_all()` function added in PHP 8.4. 619 * 620 * Checks if all elements of an array pass a given callback. 621 * 622 * @since 6.8.0 623 * 624 * @param array $array The array to check. 625 * @param callable $callback The callback to run for each element. 626 * @return bool True if all elements in the array pass the `$callback`, otherwise false. 627 */ 628 function array_all( array $array, callable $callback ): bool { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.arrayFound 629 foreach ( $array as $key => $value ) { 630 if ( ! $callback( $value, $key ) ) { 631 return false; 632 } 633 } 634 635 return true; 636 } 637 } 638 639 if ( ! function_exists( 'array_first' ) ) { 640 /** 641 * Polyfill for `array_first()` function added in PHP 8.5. 642 * 643 * Returns the first element of an array. 644 * 645 * @since 6.9.0 646 * 647 * @param array $array The array to get the first element from. 648 * @return mixed|null The first element of the array, or null if the array is empty. 649 */ 650 function array_first( array $array ) { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.arrayFound 651 if ( empty( $array ) ) { 652 return null; 653 } 654 655 foreach ( $array as $value ) { 656 return $value; 657 } 658 } 659 } 660 661 if ( ! function_exists( 'array_last' ) ) { 662 /** 663 * Polyfill for `array_last()` function added in PHP 8.5. 664 * 665 * Returns the last element of an array. 666 * 667 * @since 6.9.0 668 * 669 * @param array $array The array to get the last element from. 670 * @return mixed|null The last element of the array, or null if the array is empty. 671 */ 672 function array_last( array $array ) { // phpcs:ignore Universal.NamingConventions.NoReservedKeywordParameterNames.arrayFound 673 if ( empty( $array ) ) { 674 return null; 675 } 676 677 return $array[ array_key_last( $array ) ]; 678 } 679 } 680 681 // IMAGETYPE_AVIF constant is only defined in PHP 8.x or later. 682 if ( ! defined( 'IMAGETYPE_AVIF' ) ) { 683 define( 'IMAGETYPE_AVIF', 19 ); 684 } 685 686 // IMG_AVIF constant is only defined in PHP 8.x or later. 687 if ( ! defined( 'IMG_AVIF' ) ) { 688 define( 'IMG_AVIF', IMAGETYPE_AVIF ); 689 } 690 691 // IMAGETYPE_HEIF constant is only defined in PHP 8.5 or later. 692 if ( ! defined( 'IMAGETYPE_HEIF' ) ) { 693 define( 'IMAGETYPE_HEIF', 20 ); 694 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated : Sat Jun 20 08:20:11 2026 | Cross-referenced by PHPXref |