1<?php 2 3/* 4 * This file is part of the Symfony package. 5 * 6 * (c) Fabien Potencier <fabien@symfony.com> 7 * 8 * For the full copyright and license information, please view the LICENSE 9 * file that was distributed with this source code. 10 */ 11 12namespace Symfony\Polyfill\Ctype; 13 14/** 15 * Ctype implementation through regex. 16 * 17 * @internal 18 * 19 * @author Gert de Pagter <BackEndTea@gmail.com> 20 */ 21final class Ctype 22{ 23 /** 24 * Returns TRUE if every character in text is either a letter or a digit, FALSE otherwise. 25 * 26 * @see https://php.net/ctype-alnum 27 * 28 * @param mixed $text 29 * 30 * @return bool 31 */ 32 public static function ctype_alnum($text) 33 { 34 $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); 35 36 return \is_string($text) && '' !== $text && !preg_match('/[^A-Za-z0-9]/', $text); 37 } 38 39 /** 40 * Returns TRUE if every character in text is a letter, FALSE otherwise. 41 * 42 * @see https://php.net/ctype-alpha 43 * 44 * @param mixed $text 45 * 46 * @return bool 47 */ 48 public static function ctype_alpha($text) 49 { 50 $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); 51 52 return \is_string($text) && '' !== $text && !preg_match('/[^A-Za-z]/', $text); 53 } 54 55 /** 56 * Returns TRUE if every character in text is a control character from the current locale, FALSE otherwise. 57 * 58 * @see https://php.net/ctype-cntrl 59 * 60 * @param mixed $text 61 * 62 * @return bool 63 */ 64 public static function ctype_cntrl($text) 65 { 66 $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); 67 68 return \is_string($text) && '' !== $text && !preg_match('/[^\x00-\x1f\x7f]/', $text); 69 } 70 71 /** 72 * Returns TRUE if every character in the string text is a decimal digit, FALSE otherwise. 73 * 74 * @see https://php.net/ctype-digit 75 * 76 * @param mixed $text 77 * 78 * @return bool 79 */ 80 public static function ctype_digit($text) 81 { 82 $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); 83 84 return \is_string($text) && '' !== $text && !preg_match('/[^0-9]/', $text); 85 } 86 87 /** 88 * Returns TRUE if every character in text is printable and actually creates visible output (no white space), FALSE otherwise. 89 * 90 * @see https://php.net/ctype-graph 91 * 92 * @param mixed $text 93 * 94 * @return bool 95 */ 96 public static function ctype_graph($text) 97 { 98 $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); 99 100 return \is_string($text) && '' !== $text && !preg_match('/[^!-~]/', $text); 101 } 102 103 /** 104 * Returns TRUE if every character in text is a lowercase letter. 105 * 106 * @see https://php.net/ctype-lower 107 * 108 * @param mixed $text 109 * 110 * @return bool 111 */ 112 public static function ctype_lower($text) 113 { 114 $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); 115 116 return \is_string($text) && '' !== $text && !preg_match('/[^a-z]/', $text); 117 } 118 119 /** 120 * Returns TRUE if every character in text will actually create output (including blanks). Returns FALSE if text contains control characters or characters that do not have any output or control function at all. 121 * 122 * @see https://php.net/ctype-print 123 * 124 * @param mixed $text 125 * 126 * @return bool 127 */ 128 public static function ctype_print($text) 129 { 130 $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); 131 132 return \is_string($text) && '' !== $text && !preg_match('/[^ -~]/', $text); 133 } 134 135 /** 136 * Returns TRUE if every character in text is printable, but neither letter, digit or blank, FALSE otherwise. 137 * 138 * @see https://php.net/ctype-punct 139 * 140 * @param mixed $text 141 * 142 * @return bool 143 */ 144 public static function ctype_punct($text) 145 { 146 $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); 147 148 return \is_string($text) && '' !== $text && !preg_match('/[^!-\/\:-@\[-`\{-~]/', $text); 149 } 150 151 /** 152 * Returns TRUE if every character in text creates some sort of white space, FALSE otherwise. Besides the blank character this also includes tab, vertical tab, line feed, carriage return and form feed characters. 153 * 154 * @see https://php.net/ctype-space 155 * 156 * @param mixed $text 157 * 158 * @return bool 159 */ 160 public static function ctype_space($text) 161 { 162 $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); 163 164 return \is_string($text) && '' !== $text && !preg_match('/[^\s]/', $text); 165 } 166 167 /** 168 * Returns TRUE if every character in text is an uppercase letter. 169 * 170 * @see https://php.net/ctype-upper 171 * 172 * @param mixed $text 173 * 174 * @return bool 175 */ 176 public static function ctype_upper($text) 177 { 178 $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); 179 180 return \is_string($text) && '' !== $text && !preg_match('/[^A-Z]/', $text); 181 } 182 183 /** 184 * Returns TRUE if every character in text is a hexadecimal 'digit', that is a decimal digit or a character from [A-Fa-f] , FALSE otherwise. 185 * 186 * @see https://php.net/ctype-xdigit 187 * 188 * @param mixed $text 189 * 190 * @return bool 191 */ 192 public static function ctype_xdigit($text) 193 { 194 $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__); 195 196 return \is_string($text) && '' !== $text && !preg_match('/[^A-Fa-f0-9]/', $text); 197 } 198 199 /** 200 * Converts integers to their char versions according to normal ctype behaviour, if needed. 201 * 202 * If an integer between -128 and 255 inclusive is provided, 203 * it is interpreted as the ASCII value of a single character 204 * (negative values have 256 added in order to allow characters in the Extended ASCII range). 205 * Any other integer is interpreted as a string containing the decimal digits of the integer. 206 * 207 * @param mixed $int 208 * @param string $function 209 * 210 * @return mixed 211 */ 212 private static function convert_int_to_char_for_ctype($int, $function) 213 { 214 if (!\is_int($int)) { 215 return $int; 216 } 217 218 if ($int < -128 || $int > 255) { 219 return (string) $int; 220 } 221 222 if (\PHP_VERSION_ID >= 80100) { 223 @trigger_error($function.'(): Argument of type int will be interpreted as string in the future', \E_USER_DEPRECATED); 224 } 225 226 if ($int < 0) { 227 $int += 256; 228 } 229 230 return \chr($int); 231 } 232} 233