1 /*
2 +----------------------------------------------------------------------+
3 | PHP Version 7 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) The PHP Group |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
15 | Author: Rasmus Lerdorf <rasmus@php.net> |
16 +----------------------------------------------------------------------+
17 */
18
19 #include "php.h"
20 #include "php_incomplete_class.h"
21
22 /* {{{ proto string gettype(mixed var)
23 Returns the type of the variable */
PHP_FUNCTION(gettype)24 PHP_FUNCTION(gettype)
25 {
26 zval *arg;
27 zend_string *type;
28
29 ZEND_PARSE_PARAMETERS_START(1, 1)
30 Z_PARAM_ZVAL(arg)
31 ZEND_PARSE_PARAMETERS_END();
32
33 type = zend_zval_get_type(arg);
34 if (EXPECTED(type)) {
35 RETURN_INTERNED_STR(type);
36 } else {
37 RETURN_STRING("unknown type");
38 }
39 }
40 /* }}} */
41
42 /* {{{ proto bool settype(mixed &var, string type)
43 Set the type of the variable */
PHP_FUNCTION(settype)44 PHP_FUNCTION(settype)
45 {
46 zval *var;
47 zend_string *type;
48 zval tmp, *ptr;
49
50 ZEND_PARSE_PARAMETERS_START(2, 2)
51 Z_PARAM_ZVAL(var)
52 Z_PARAM_STR(type)
53 ZEND_PARSE_PARAMETERS_END();
54
55 ZEND_ASSERT(Z_ISREF_P(var));
56 if (UNEXPECTED(ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(var)))) {
57 ZVAL_COPY(&tmp, Z_REFVAL_P(var));
58 ptr = &tmp;
59 } else {
60 ptr = Z_REFVAL_P(var);
61 }
62 if (zend_string_equals_literal_ci(type, "integer")) {
63 convert_to_long(ptr);
64 } else if (zend_string_equals_literal_ci(type, "int")) {
65 convert_to_long(ptr);
66 } else if (zend_string_equals_literal_ci(type, "float")) {
67 convert_to_double(ptr);
68 } else if (zend_string_equals_literal_ci(type, "double")) { /* deprecated */
69 convert_to_double(ptr);
70 } else if (zend_string_equals_literal_ci(type, "string")) {
71 convert_to_string(ptr);
72 } else if (zend_string_equals_literal_ci(type, "array")) {
73 convert_to_array(ptr);
74 } else if (zend_string_equals_literal_ci(type, "object")) {
75 convert_to_object(ptr);
76 } else if (zend_string_equals_literal_ci(type, "bool")) {
77 convert_to_boolean(ptr);
78 } else if (zend_string_equals_literal_ci(type, "boolean")) {
79 convert_to_boolean(ptr);
80 } else if (zend_string_equals_literal_ci(type, "null")) {
81 convert_to_null(ptr);
82 } else {
83 if (ptr == &tmp) {
84 zval_ptr_dtor(&tmp);
85 }
86 if (zend_string_equals_literal_ci(type, "resource")) {
87 php_error_docref(NULL, E_WARNING, "Cannot convert to resource type");
88 } else {
89 php_error_docref(NULL, E_WARNING, "Invalid type");
90 }
91 RETURN_FALSE;
92 }
93
94 if (ptr == &tmp) {
95 zend_try_assign_typed_ref(Z_REF_P(var), &tmp);
96 }
97 RETVAL_TRUE;
98 }
99 /* }}} */
100
101 /* {{{ proto int intval(mixed var [, int base])
102 Get the integer value of a variable using the optional base for the conversion */
PHP_FUNCTION(intval)103 PHP_FUNCTION(intval)
104 {
105 zval *num;
106 zend_long base = 10;
107
108 ZEND_PARSE_PARAMETERS_START(1, 2)
109 Z_PARAM_ZVAL(num)
110 Z_PARAM_OPTIONAL
111 Z_PARAM_LONG(base)
112 ZEND_PARSE_PARAMETERS_END();
113
114 if (Z_TYPE_P(num) != IS_STRING || base == 10) {
115 RETVAL_LONG(zval_get_long(num));
116 return;
117 }
118
119
120 if (base == 0 || base == 2) {
121 char *strval = Z_STRVAL_P(num);
122 size_t strlen = Z_STRLEN_P(num);
123
124 while (isspace(*strval) && strlen) {
125 strval++;
126 strlen--;
127 }
128
129 /* Length of 3+ covers "0b#" and "-0b" (which results in 0) */
130 if (strlen > 2) {
131 int offset = 0;
132 if (strval[0] == '-' || strval[0] == '+') {
133 offset = 1;
134 }
135
136 if (strval[offset] == '0' && (strval[offset + 1] == 'b' || strval[offset + 1] == 'B')) {
137 char *tmpval;
138 strlen -= 2; /* Removing "0b" */
139 tmpval = emalloc(strlen + 1);
140
141 /* Place the unary symbol at pos 0 if there was one */
142 if (offset) {
143 tmpval[0] = strval[0];
144 }
145
146 /* Copy the data from after "0b" to the end of the buffer */
147 memcpy(tmpval + offset, strval + offset + 2, strlen - offset);
148 tmpval[strlen] = 0;
149
150 RETVAL_LONG(ZEND_STRTOL(tmpval, NULL, 2));
151 efree(tmpval);
152 return;
153 }
154 }
155 }
156
157 RETVAL_LONG(ZEND_STRTOL(Z_STRVAL_P(num), NULL, base));
158 }
159 /* }}} */
160
161 /* {{{ proto float floatval(mixed var)
162 Get the float value of a variable */
PHP_FUNCTION(floatval)163 PHP_FUNCTION(floatval)
164 {
165 zval *num;
166
167 ZEND_PARSE_PARAMETERS_START(1, 1)
168 Z_PARAM_ZVAL(num)
169 ZEND_PARSE_PARAMETERS_END();
170
171 RETURN_DOUBLE(zval_get_double(num));
172 }
173 /* }}} */
174
175 /* {{{ proto bool boolval(mixed var)
176 Get the boolean value of a variable */
PHP_FUNCTION(boolval)177 PHP_FUNCTION(boolval)
178 {
179 zval *val;
180
181 ZEND_PARSE_PARAMETERS_START(1, 1)
182 Z_PARAM_ZVAL(val)
183 ZEND_PARSE_PARAMETERS_END();
184
185 RETURN_BOOL(zend_is_true(val));
186 }
187 /* }}} */
188
189 /* {{{ proto string strval(mixed var)
190 Get the string value of a variable */
PHP_FUNCTION(strval)191 PHP_FUNCTION(strval)
192 {
193 zval *num;
194
195 ZEND_PARSE_PARAMETERS_START(1, 1)
196 Z_PARAM_ZVAL(num)
197 ZEND_PARSE_PARAMETERS_END();
198
199 RETVAL_STR(zval_get_string(num));
200 }
201 /* }}} */
202
php_is_type(INTERNAL_FUNCTION_PARAMETERS,int type)203 static inline void php_is_type(INTERNAL_FUNCTION_PARAMETERS, int type)
204 {
205 zval *arg;
206
207 ZEND_PARSE_PARAMETERS_START(1, 1)
208 Z_PARAM_ZVAL(arg)
209 ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE);
210
211 if (Z_TYPE_P(arg) == type) {
212 if (type == IS_RESOURCE) {
213 const char *type_name = zend_rsrc_list_get_rsrc_type(Z_RES_P(arg));
214 if (!type_name) {
215 RETURN_FALSE;
216 }
217 }
218 RETURN_TRUE;
219 } else {
220 RETURN_FALSE;
221 }
222 }
223
224
225 /* {{{ proto bool is_null(mixed var)
226 Returns true if variable is null
227 Warning: This function is special-cased by zend_compile.c and so is usually bypassed */
PHP_FUNCTION(is_null)228 PHP_FUNCTION(is_null)
229 {
230 php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_NULL);
231 }
232 /* }}} */
233
234 /* {{{ proto bool is_resource(mixed var)
235 Returns true if variable is a resource
236 Warning: This function is special-cased by zend_compile.c and so is usually bypassed */
PHP_FUNCTION(is_resource)237 PHP_FUNCTION(is_resource)
238 {
239 php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_RESOURCE);
240 }
241 /* }}} */
242
243 /* {{{ proto bool is_bool(mixed var)
244 Returns true if variable is a boolean
245 Warning: This function is special-cased by zend_compile.c and so is usually bypassed */
PHP_FUNCTION(is_bool)246 PHP_FUNCTION(is_bool)
247 {
248 zval *arg;
249
250 ZEND_PARSE_PARAMETERS_START(1, 1)
251 Z_PARAM_ZVAL(arg)
252 ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE);
253
254 RETURN_BOOL(Z_TYPE_P(arg) == IS_FALSE || Z_TYPE_P(arg) == IS_TRUE);
255 }
256 /* }}} */
257
258 /* {{{ proto bool is_int(mixed var)
259 Returns true if variable is an integer
260 Warning: This function is special-cased by zend_compile.c and so is usually bypassed */
PHP_FUNCTION(is_int)261 PHP_FUNCTION(is_int)
262 {
263 php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_LONG);
264 }
265 /* }}} */
266
267 /* {{{ proto bool is_float(mixed var)
268 Returns true if variable is float point
269 Warning: This function is special-cased by zend_compile.c and so is usually bypassed */
PHP_FUNCTION(is_float)270 PHP_FUNCTION(is_float)
271 {
272 php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_DOUBLE);
273 }
274 /* }}} */
275
276 /* {{{ proto bool is_string(mixed var)
277 Returns true if variable is a string
278 Warning: This function is special-cased by zend_compile.c and so is usually bypassed */
PHP_FUNCTION(is_string)279 PHP_FUNCTION(is_string)
280 {
281 php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_STRING);
282 }
283 /* }}} */
284
285 /* {{{ proto bool is_array(mixed var)
286 Returns true if variable is an array
287 Warning: This function is special-cased by zend_compile.c and so is usually bypassed */
PHP_FUNCTION(is_array)288 PHP_FUNCTION(is_array)
289 {
290 php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_ARRAY);
291 }
292 /* }}} */
293
294 /* {{{ proto bool is_object(mixed var)
295 Returns true if variable is an object
296 Warning: This function is special-cased by zend_compile.c and so is usually bypassed */
PHP_FUNCTION(is_object)297 PHP_FUNCTION(is_object)
298 {
299 php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_OBJECT);
300 }
301 /* }}} */
302
303 /* {{{ proto bool is_numeric(mixed value)
304 Returns true if value is a number or a numeric string */
PHP_FUNCTION(is_numeric)305 PHP_FUNCTION(is_numeric)
306 {
307 zval *arg;
308
309 ZEND_PARSE_PARAMETERS_START(1, 1)
310 Z_PARAM_ZVAL(arg)
311 ZEND_PARSE_PARAMETERS_END();
312
313 switch (Z_TYPE_P(arg)) {
314 case IS_LONG:
315 case IS_DOUBLE:
316 RETURN_TRUE;
317 break;
318
319 case IS_STRING:
320 if (is_numeric_string(Z_STRVAL_P(arg), Z_STRLEN_P(arg), NULL, NULL, 0)) {
321 RETURN_TRUE;
322 } else {
323 RETURN_FALSE;
324 }
325 break;
326
327 default:
328 RETURN_FALSE;
329 break;
330 }
331 }
332 /* }}} */
333
334 /* {{{ proto bool is_scalar(mixed value)
335 Returns true if value is a scalar */
PHP_FUNCTION(is_scalar)336 PHP_FUNCTION(is_scalar)
337 {
338 zval *arg;
339
340 ZEND_PARSE_PARAMETERS_START(1, 1)
341 Z_PARAM_ZVAL(arg)
342 ZEND_PARSE_PARAMETERS_END();
343
344 switch (Z_TYPE_P(arg)) {
345 case IS_FALSE:
346 case IS_TRUE:
347 case IS_DOUBLE:
348 case IS_LONG:
349 case IS_STRING:
350 RETURN_TRUE;
351 break;
352
353 default:
354 RETURN_FALSE;
355 break;
356 }
357 }
358 /* }}} */
359
360 /* {{{ proto bool is_callable(mixed var [, bool syntax_only [, string &callable_name]])
361 Returns true if var is callable. */
PHP_FUNCTION(is_callable)362 PHP_FUNCTION(is_callable)
363 {
364 zval *var, *callable_name = NULL;
365 zend_string *name;
366 char *error;
367 zend_bool retval;
368 zend_bool syntax_only = 0;
369 int check_flags = 0;
370
371 ZEND_PARSE_PARAMETERS_START(1, 3)
372 Z_PARAM_ZVAL(var)
373 Z_PARAM_OPTIONAL
374 Z_PARAM_BOOL(syntax_only)
375 Z_PARAM_ZVAL(callable_name)
376 ZEND_PARSE_PARAMETERS_END();
377
378 if (syntax_only) {
379 check_flags |= IS_CALLABLE_CHECK_SYNTAX_ONLY;
380 }
381 if (ZEND_NUM_ARGS() > 2) {
382 retval = zend_is_callable_ex(var, NULL, check_flags, &name, NULL, &error);
383 ZEND_TRY_ASSIGN_REF_STR(callable_name, name);
384 } else {
385 retval = zend_is_callable_ex(var, NULL, check_flags, NULL, NULL, &error);
386 }
387 if (error) {
388 /* ignore errors */
389 efree(error);
390 }
391
392 RETURN_BOOL(retval);
393 }
394 /* }}} */
395
396 /* {{{ proto bool is_iterable(mixed var)
397 Returns true if var is iterable (array or instance of Traversable). */
PHP_FUNCTION(is_iterable)398 PHP_FUNCTION(is_iterable)
399 {
400 zval *var;
401
402 ZEND_PARSE_PARAMETERS_START(1, 1)
403 Z_PARAM_ZVAL(var)
404 ZEND_PARSE_PARAMETERS_END();
405
406 RETURN_BOOL(zend_is_iterable(var));
407 }
408 /* }}} */
409
410 /* {{{ proto bool is_countable(mixed var)
411 Returns true if var is countable (array or instance of Countable). */
PHP_FUNCTION(is_countable)412 PHP_FUNCTION(is_countable)
413 {
414 zval *var;
415
416 ZEND_PARSE_PARAMETERS_START(1, 1)
417 Z_PARAM_ZVAL(var)
418 ZEND_PARSE_PARAMETERS_END();
419
420 RETURN_BOOL(zend_is_countable(var));
421 }
422 /* }}} */
423