1 /*
2 +----------------------------------------------------------------------+
3 | PHP Version 7 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1997-2018 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 /* $Id$ */
20
21 #include "php.h"
22 #include "php_incomplete_class.h"
23
24 /* {{{ proto string gettype(mixed var)
25 Returns the type of the variable */
PHP_FUNCTION(gettype)26 PHP_FUNCTION(gettype)
27 {
28 zval *arg;
29
30 if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &arg) == FAILURE) {
31 return;
32 }
33
34 switch (Z_TYPE_P(arg)) {
35 case IS_NULL:
36 RETVAL_STRING("NULL");
37 break;
38
39 case IS_FALSE:
40 case IS_TRUE:
41 RETVAL_STRING("boolean");
42 break;
43
44 case IS_LONG:
45 RETVAL_STRING("integer");
46 break;
47
48 case IS_DOUBLE:
49 RETVAL_STRING("double");
50 break;
51
52 case IS_STRING:
53 RETVAL_STRING("string");
54 break;
55
56 case IS_ARRAY:
57 RETVAL_STRING("array");
58 break;
59
60 case IS_OBJECT:
61 RETVAL_STRING("object");
62 /*
63 {
64 char *result;
65 int res_len;
66
67 res_len = sizeof("object of type ")-1 + Z_OBJCE_P(arg)->name_length;
68 spprintf(&result, 0, "object of type %s", Z_OBJCE_P(arg)->name);
69 RETVAL_STRINGL(result, res_len);
70 efree(result);
71 }
72 */
73 break;
74
75 case IS_RESOURCE:
76 {
77 const char *type_name = zend_rsrc_list_get_rsrc_type(Z_RES_P(arg));
78
79 if (type_name) {
80 RETVAL_STRING("resource");
81 break;
82 }
83 }
84
85 default:
86 RETVAL_STRING("unknown type");
87 }
88 }
89 /* }}} */
90
91 /* {{{ proto bool settype(mixed var, string type)
92 Set the type of the variable */
PHP_FUNCTION(settype)93 PHP_FUNCTION(settype)
94 {
95 zval *var;
96 char *type;
97 size_t type_len = 0;
98
99 if (zend_parse_parameters(ZEND_NUM_ARGS(), "zs", &var, &type, &type_len) == FAILURE) {
100 return;
101 }
102
103 ZVAL_DEREF(var);
104 if (!strcasecmp(type, "integer")) {
105 convert_to_long(var);
106 } else if (!strcasecmp(type, "int")) {
107 convert_to_long(var);
108 } else if (!strcasecmp(type, "float")) {
109 convert_to_double(var);
110 } else if (!strcasecmp(type, "double")) { /* deprecated */
111 convert_to_double(var);
112 } else if (!strcasecmp(type, "string")) {
113 convert_to_string(var);
114 } else if (!strcasecmp(type, "array")) {
115 convert_to_array(var);
116 } else if (!strcasecmp(type, "object")) {
117 convert_to_object(var);
118 } else if (!strcasecmp(type, "bool")) {
119 convert_to_boolean(var);
120 } else if (!strcasecmp(type, "boolean")) {
121 convert_to_boolean(var);
122 } else if (!strcasecmp(type, "null")) {
123 convert_to_null(var);
124 } else if (!strcasecmp(type, "resource")) {
125 php_error_docref(NULL, E_WARNING, "Cannot convert to resource type");
126 RETURN_FALSE;
127 } else {
128 php_error_docref(NULL, E_WARNING, "Invalid type");
129 RETURN_FALSE;
130 }
131 RETVAL_TRUE;
132 }
133 /* }}} */
134
135 /* {{{ proto int intval(mixed var [, int base])
136 Get the integer value of a variable using the optional base for the conversion */
PHP_FUNCTION(intval)137 PHP_FUNCTION(intval)
138 {
139 zval *num;
140 zend_long base = 10;
141
142 if (ZEND_NUM_ARGS() != 1 && ZEND_NUM_ARGS() != 2) {
143 WRONG_PARAM_COUNT;
144 }
145 ZEND_PARSE_PARAMETERS_START(1, 2)
146 Z_PARAM_ZVAL(num)
147 Z_PARAM_OPTIONAL
148 Z_PARAM_LONG(base)
149 ZEND_PARSE_PARAMETERS_END();
150
151 if (Z_TYPE_P(num) != IS_STRING || base == 10) {
152 RETVAL_LONG(zval_get_long(num));
153 return;
154 }
155
156
157 if (base == 0 || base == 2) {
158 char *strval = Z_STRVAL_P(num);
159 size_t strlen = Z_STRLEN_P(num);
160
161 while (isspace(*strval) && strlen) {
162 strval++;
163 strlen--;
164 }
165
166 /* Length of 3+ covers "0b#" and "-0b" (which results in 0) */
167 if (strlen > 2) {
168 int offset = 0;
169 if (strval[0] == '-' || strval[0] == '+') {
170 offset = 1;
171 }
172
173 if (strval[offset] == '0' && (strval[offset + 1] == 'b' || strval[offset + 1] == 'B')) {
174 char *tmpval;
175 strlen -= 2; /* Removing "0b" */
176 tmpval = emalloc(strlen + 1);
177
178 /* Place the unary symbol at pos 0 if there was one */
179 if (offset) {
180 tmpval[0] = strval[0];
181 }
182
183 /* Copy the data from after "0b" to the end of the buffer */
184 memcpy(tmpval + offset, strval + offset + 2, strlen - offset);
185 tmpval[strlen] = 0;
186
187 RETVAL_LONG(ZEND_STRTOL(tmpval, NULL, 2));
188 efree(tmpval);
189 return;
190 }
191 }
192 }
193
194 RETVAL_LONG(ZEND_STRTOL(Z_STRVAL_P(num), NULL, base));
195 }
196 /* }}} */
197
198 /* {{{ proto float floatval(mixed var)
199 Get the float value of a variable */
PHP_FUNCTION(floatval)200 PHP_FUNCTION(floatval)
201 {
202 zval *num;
203
204 if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &num) == FAILURE) {
205 return;
206 }
207
208 RETURN_DOUBLE(zval_get_double(num));
209 }
210 /* }}} */
211
212 /* {{{ proto bool boolval(mixed var)
213 Get the boolean value of a variable */
PHP_FUNCTION(boolval)214 PHP_FUNCTION(boolval)
215 {
216 zval *val;
217
218 if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) {
219 return;
220 }
221
222 RETURN_BOOL(zend_is_true(val));
223 }
224 /* }}} */
225
226 /* {{{ proto string strval(mixed var)
227 Get the string value of a variable */
PHP_FUNCTION(strval)228 PHP_FUNCTION(strval)
229 {
230 zval *num;
231
232 ZEND_PARSE_PARAMETERS_START(1, 1)
233 Z_PARAM_ZVAL(num)
234 ZEND_PARSE_PARAMETERS_END();
235
236 RETVAL_STR(zval_get_string(num));
237 }
238 /* }}} */
239
php_is_type(INTERNAL_FUNCTION_PARAMETERS,int type)240 static inline void php_is_type(INTERNAL_FUNCTION_PARAMETERS, int type)
241 {
242 zval *arg;
243
244 ZEND_PARSE_PARAMETERS_START(1, 1)
245 Z_PARAM_ZVAL_DEREF(arg)
246 ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE);
247
248 if (Z_TYPE_P(arg) == type) {
249 if (type == IS_OBJECT) {
250 zend_class_entry *ce = Z_OBJCE_P(arg);
251 if (ZSTR_LEN(ce->name) == sizeof(INCOMPLETE_CLASS) - 1
252 && !memcmp(ZSTR_VAL(ce->name), INCOMPLETE_CLASS, sizeof(INCOMPLETE_CLASS) - 1)) {
253 RETURN_FALSE;
254 }
255 } else if (type == IS_RESOURCE) {
256 const char *type_name = zend_rsrc_list_get_rsrc_type(Z_RES_P(arg));
257 if (!type_name) {
258 RETURN_FALSE;
259 }
260 }
261 RETURN_TRUE;
262 } else {
263 RETURN_FALSE;
264 }
265 }
266
267
268 /* {{{ proto bool is_null(mixed var)
269 Returns true if variable is null
270 Warning: This function is special-cased by zend_compile.c and so is usually bypassed */
PHP_FUNCTION(is_null)271 PHP_FUNCTION(is_null)
272 {
273 php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_NULL);
274 }
275 /* }}} */
276
277 /* {{{ proto bool is_resource(mixed var)
278 Returns true if variable is a resource
279 Warning: This function is special-cased by zend_compile.c and so is usually bypassed */
PHP_FUNCTION(is_resource)280 PHP_FUNCTION(is_resource)
281 {
282 php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_RESOURCE);
283 }
284 /* }}} */
285
286 /* {{{ proto bool is_bool(mixed var)
287 Returns true if variable is a boolean
288 Warning: This function is special-cased by zend_compile.c and so is usually bypassed */
PHP_FUNCTION(is_bool)289 PHP_FUNCTION(is_bool)
290 {
291 zval *arg;
292
293 if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &arg) == FAILURE) {
294 RETURN_FALSE;
295 }
296
297 ZVAL_DEREF(arg);
298 RETURN_BOOL(Z_TYPE_P(arg) == IS_FALSE || Z_TYPE_P(arg) == IS_TRUE);
299 }
300 /* }}} */
301
302 /* {{{ proto bool is_int(mixed var)
303 Returns true if variable is an integer
304 Warning: This function is special-cased by zend_compile.c and so is usually bypassed */
PHP_FUNCTION(is_int)305 PHP_FUNCTION(is_int)
306 {
307 php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_LONG);
308 }
309 /* }}} */
310
311 /* {{{ proto bool is_float(mixed var)
312 Returns true if variable is float point
313 Warning: This function is special-cased by zend_compile.c and so is usually bypassed */
PHP_FUNCTION(is_float)314 PHP_FUNCTION(is_float)
315 {
316 php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_DOUBLE);
317 }
318 /* }}} */
319
320 /* {{{ proto bool is_string(mixed var)
321 Returns true if variable is a string
322 Warning: This function is special-cased by zend_compile.c and so is usually bypassed */
PHP_FUNCTION(is_string)323 PHP_FUNCTION(is_string)
324 {
325 php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_STRING);
326 }
327 /* }}} */
328
329 /* {{{ proto bool is_array(mixed var)
330 Returns true if variable is an array
331 Warning: This function is special-cased by zend_compile.c and so is usually bypassed */
PHP_FUNCTION(is_array)332 PHP_FUNCTION(is_array)
333 {
334 php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_ARRAY);
335 }
336 /* }}} */
337
338 /* {{{ proto bool is_object(mixed var)
339 Returns true if variable is an object
340 Warning: This function is special-cased by zend_compile.c and so is usually bypassed */
PHP_FUNCTION(is_object)341 PHP_FUNCTION(is_object)
342 {
343 php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_OBJECT);
344 }
345 /* }}} */
346
347 /* {{{ proto bool is_numeric(mixed value)
348 Returns true if value is a number or a numeric string */
PHP_FUNCTION(is_numeric)349 PHP_FUNCTION(is_numeric)
350 {
351 zval *arg;
352
353 ZEND_PARSE_PARAMETERS_START(1, 1)
354 Z_PARAM_ZVAL(arg)
355 ZEND_PARSE_PARAMETERS_END();
356
357 switch (Z_TYPE_P(arg)) {
358 case IS_LONG:
359 case IS_DOUBLE:
360 RETURN_TRUE;
361 break;
362
363 case IS_STRING:
364 if (is_numeric_string(Z_STRVAL_P(arg), Z_STRLEN_P(arg), NULL, NULL, 0)) {
365 RETURN_TRUE;
366 } else {
367 RETURN_FALSE;
368 }
369 break;
370
371 default:
372 RETURN_FALSE;
373 break;
374 }
375 }
376 /* }}} */
377
378 /* {{{ proto bool is_scalar(mixed value)
379 Returns true if value is a scalar */
PHP_FUNCTION(is_scalar)380 PHP_FUNCTION(is_scalar)
381 {
382 zval *arg;
383
384 ZEND_PARSE_PARAMETERS_START(1, 1)
385 Z_PARAM_ZVAL(arg)
386 ZEND_PARSE_PARAMETERS_END();
387
388 switch (Z_TYPE_P(arg)) {
389 case IS_FALSE:
390 case IS_TRUE:
391 case IS_DOUBLE:
392 case IS_LONG:
393 case IS_STRING:
394 RETURN_TRUE;
395 break;
396
397 default:
398 RETURN_FALSE;
399 break;
400 }
401 }
402 /* }}} */
403
404 /* {{{ proto bool is_callable(mixed var [, bool syntax_only [, string callable_name]])
405 Returns true if var is callable. */
PHP_FUNCTION(is_callable)406 PHP_FUNCTION(is_callable)
407 {
408 zval *var, *callable_name = NULL;
409 zend_string *name;
410 char *error;
411 zend_bool retval;
412 zend_bool syntax_only = 0;
413 int check_flags = 0;
414
415 if (zend_parse_parameters(ZEND_NUM_ARGS(), "z|bz/", &var,
416 &syntax_only, &callable_name) == FAILURE) {
417 return;
418 }
419
420 if (syntax_only) {
421 check_flags |= IS_CALLABLE_CHECK_SYNTAX_ONLY;
422 }
423 if (ZEND_NUM_ARGS() > 2) {
424 retval = zend_is_callable_ex(var, NULL, check_flags, &name, NULL, &error);
425 zval_dtor(callable_name);
426 ZVAL_STR(callable_name, name);
427 } else {
428 retval = zend_is_callable_ex(var, NULL, check_flags, NULL, NULL, &error);
429 }
430 if (error) {
431 /* ignore errors */
432 efree(error);
433 }
434
435 RETURN_BOOL(retval);
436 }
437 /* }}} */
438
439 /* {{{ proto bool is_iterable(mixed var)
440 Returns true if var is iterable (array or instance of Traversable). */
PHP_FUNCTION(is_iterable)441 PHP_FUNCTION(is_iterable)
442 {
443 zval *var;
444
445 if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &var) == FAILURE) {
446 return;
447 }
448
449 RETURN_BOOL(zend_is_iterable(var));
450 }
451 /* }}} */
452
453 /*
454 * Local variables:
455 * tab-width: 4
456 * c-basic-offset: 4
457 * End:
458 * vim600: sw=4 ts=4 fdm=marker
459 * vim<600: sw=4 ts=4
460 */
461