blob: ba75a2c95fc4c05575dca9a716ef0d8360c6693d [file] [log] [blame]
Matthias Andreas Benkard12a57352021-12-28 18:02:04 +01001<?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 *
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +010028 * @param mixed $text
Matthias Andreas Benkard12a57352021-12-28 18:02:04 +010029 *
30 * @return bool
31 */
32 public static function ctype_alnum($text)
33 {
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +010034 $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);
Matthias Andreas Benkard12a57352021-12-28 18:02:04 +010035
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 *
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +010044 * @param mixed $text
Matthias Andreas Benkard12a57352021-12-28 18:02:04 +010045 *
46 * @return bool
47 */
48 public static function ctype_alpha($text)
49 {
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +010050 $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);
Matthias Andreas Benkard12a57352021-12-28 18:02:04 +010051
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 *
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +010060 * @param mixed $text
Matthias Andreas Benkard12a57352021-12-28 18:02:04 +010061 *
62 * @return bool
63 */
64 public static function ctype_cntrl($text)
65 {
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +010066 $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);
Matthias Andreas Benkard12a57352021-12-28 18:02:04 +010067
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 *
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +010076 * @param mixed $text
Matthias Andreas Benkard12a57352021-12-28 18:02:04 +010077 *
78 * @return bool
79 */
80 public static function ctype_digit($text)
81 {
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +010082 $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);
Matthias Andreas Benkard12a57352021-12-28 18:02:04 +010083
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 *
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +010092 * @param mixed $text
Matthias Andreas Benkard12a57352021-12-28 18:02:04 +010093 *
94 * @return bool
95 */
96 public static function ctype_graph($text)
97 {
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +010098 $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);
Matthias Andreas Benkard12a57352021-12-28 18:02:04 +010099
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 *
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +0100108 * @param mixed $text
Matthias Andreas Benkard12a57352021-12-28 18:02:04 +0100109 *
110 * @return bool
111 */
112 public static function ctype_lower($text)
113 {
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +0100114 $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);
Matthias Andreas Benkard12a57352021-12-28 18:02:04 +0100115
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 *
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +0100124 * @param mixed $text
Matthias Andreas Benkard12a57352021-12-28 18:02:04 +0100125 *
126 * @return bool
127 */
128 public static function ctype_print($text)
129 {
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +0100130 $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);
Matthias Andreas Benkard12a57352021-12-28 18:02:04 +0100131
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 *
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +0100140 * @param mixed $text
Matthias Andreas Benkard12a57352021-12-28 18:02:04 +0100141 *
142 * @return bool
143 */
144 public static function ctype_punct($text)
145 {
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +0100146 $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);
Matthias Andreas Benkard12a57352021-12-28 18:02:04 +0100147
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 *
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +0100156 * @param mixed $text
Matthias Andreas Benkard12a57352021-12-28 18:02:04 +0100157 *
158 * @return bool
159 */
160 public static function ctype_space($text)
161 {
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +0100162 $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);
Matthias Andreas Benkard12a57352021-12-28 18:02:04 +0100163
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 *
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +0100172 * @param mixed $text
Matthias Andreas Benkard12a57352021-12-28 18:02:04 +0100173 *
174 * @return bool
175 */
176 public static function ctype_upper($text)
177 {
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +0100178 $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);
Matthias Andreas Benkard12a57352021-12-28 18:02:04 +0100179
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 *
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +0100188 * @param mixed $text
Matthias Andreas Benkard12a57352021-12-28 18:02:04 +0100189 *
190 * @return bool
191 */
192 public static function ctype_xdigit($text)
193 {
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +0100194 $text = self::convert_int_to_char_for_ctype($text, __FUNCTION__);
Matthias Andreas Benkard12a57352021-12-28 18:02:04 +0100195
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 *
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +0100207 * @param mixed $int
208 * @param string $function
Matthias Andreas Benkard12a57352021-12-28 18:02:04 +0100209 *
210 * @return mixed
211 */
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +0100212 private static function convert_int_to_char_for_ctype($int, $function)
Matthias Andreas Benkard12a57352021-12-28 18:02:04 +0100213 {
214 if (!\is_int($int)) {
215 return $int;
216 }
217
218 if ($int < -128 || $int > 255) {
219 return (string) $int;
220 }
221
Matthias Andreas Benkard1ba53812022-12-27 17:32:58 +0100222 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
Matthias Andreas Benkard12a57352021-12-28 18:02:04 +0100226 if ($int < 0) {
227 $int += 256;
228 }
229
230 return \chr($int);
231 }
232}