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