xref: /PHP-7.0/ext/standard/type.c (revision 7e5cf2aa)
1 /*
2    +----------------------------------------------------------------------+
3    | PHP Version 7                                                        |
4    +----------------------------------------------------------------------+
5    | Copyright (c) 1997-2017 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) {
152 		RETVAL_LONG(zval_get_long(num));
153 	} else {
154 		RETVAL_LONG(ZEND_STRTOL(Z_STRVAL_P(num), NULL, base));
155 	}
156 }
157 /* }}} */
158 
159 /* {{{ proto float floatval(mixed var)
160    Get the float value of a variable */
PHP_FUNCTION(floatval)161 PHP_FUNCTION(floatval)
162 {
163 	zval *num;
164 
165 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &num) == FAILURE) {
166 		return;
167 	}
168 
169 	RETURN_DOUBLE(zval_get_double(num));
170 }
171 /* }}} */
172 
173 /* {{{ proto bool boolval(mixed var)
174    Get the boolean value of a variable */
PHP_FUNCTION(boolval)175 PHP_FUNCTION(boolval)
176 {
177 	zval *val;
178 
179 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &val) == FAILURE) {
180 		return;
181 	}
182 
183 	RETURN_BOOL(zend_is_true(val));
184 }
185 /* }}} */
186 
187 /* {{{ proto string strval(mixed var)
188    Get the string value of a variable */
PHP_FUNCTION(strval)189 PHP_FUNCTION(strval)
190 {
191 	zval *num;
192 
193 	ZEND_PARSE_PARAMETERS_START(1, 1)
194 		Z_PARAM_ZVAL(num)
195 	ZEND_PARSE_PARAMETERS_END();
196 
197 	RETVAL_STR(zval_get_string(num));
198 }
199 /* }}} */
200 
php_is_type(INTERNAL_FUNCTION_PARAMETERS,int type)201 static inline void php_is_type(INTERNAL_FUNCTION_PARAMETERS, int type)
202 {
203 	zval *arg;
204 
205 	ZEND_PARSE_PARAMETERS_START(1, 1)
206 		Z_PARAM_ZVAL_DEREF(arg)
207 	ZEND_PARSE_PARAMETERS_END_EX(RETURN_FALSE);
208 
209 	if (Z_TYPE_P(arg) == type) {
210 		if (type == IS_OBJECT) {
211 			zend_class_entry *ce = Z_OBJCE_P(arg);
212 			if (ZSTR_LEN(ce->name) == sizeof(INCOMPLETE_CLASS) - 1
213 					&& !memcmp(ZSTR_VAL(ce->name), INCOMPLETE_CLASS, sizeof(INCOMPLETE_CLASS) - 1)) {
214 				RETURN_FALSE;
215 			}
216 		} else if (type == IS_RESOURCE) {
217 			const char *type_name = zend_rsrc_list_get_rsrc_type(Z_RES_P(arg));
218 			if (!type_name) {
219 				RETURN_FALSE;
220 			}
221 		}
222 		RETURN_TRUE;
223 	} else {
224 		RETURN_FALSE;
225 	}
226 }
227 
228 
229 /* {{{ proto bool is_null(mixed var)
230    Returns true if variable is null
231    Warning: This function is special-cased by zend_compile.c and so is usually bypassed */
PHP_FUNCTION(is_null)232 PHP_FUNCTION(is_null)
233 {
234 	php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_NULL);
235 }
236 /* }}} */
237 
238 /* {{{ proto bool is_resource(mixed var)
239    Returns true if variable is a resource
240    Warning: This function is special-cased by zend_compile.c and so is usually bypassed */
PHP_FUNCTION(is_resource)241 PHP_FUNCTION(is_resource)
242 {
243 	php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_RESOURCE);
244 }
245 /* }}} */
246 
247 /* {{{ proto bool is_bool(mixed var)
248    Returns true if variable is a boolean
249    Warning: This function is special-cased by zend_compile.c and so is usually bypassed */
PHP_FUNCTION(is_bool)250 PHP_FUNCTION(is_bool)
251 {
252 	zval *arg;
253 
254 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &arg) == FAILURE) {
255 		RETURN_FALSE;
256 	}
257 
258 	ZVAL_DEREF(arg);
259 	RETURN_BOOL(Z_TYPE_P(arg) == IS_FALSE || Z_TYPE_P(arg) == IS_TRUE);
260 }
261 /* }}} */
262 
263 /* {{{ proto bool is_int(mixed var)
264    Returns true if variable is an integer
265    Warning: This function is special-cased by zend_compile.c and so is usually bypassed */
PHP_FUNCTION(is_int)266 PHP_FUNCTION(is_int)
267 {
268 	php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_LONG);
269 }
270 /* }}} */
271 
272 /* {{{ proto bool is_float(mixed var)
273    Returns true if variable is float point
274    Warning: This function is special-cased by zend_compile.c and so is usually bypassed */
PHP_FUNCTION(is_float)275 PHP_FUNCTION(is_float)
276 {
277 	php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_DOUBLE);
278 }
279 /* }}} */
280 
281 /* {{{ proto bool is_string(mixed var)
282    Returns true if variable is a string
283    Warning: This function is special-cased by zend_compile.c and so is usually bypassed */
PHP_FUNCTION(is_string)284 PHP_FUNCTION(is_string)
285 {
286 	php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_STRING);
287 }
288 /* }}} */
289 
290 /* {{{ proto bool is_array(mixed var)
291    Returns true if variable is an array
292    Warning: This function is special-cased by zend_compile.c and so is usually bypassed */
PHP_FUNCTION(is_array)293 PHP_FUNCTION(is_array)
294 {
295 	php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_ARRAY);
296 }
297 /* }}} */
298 
299 /* {{{ proto bool is_object(mixed var)
300    Returns true if variable is an object
301    Warning: This function is special-cased by zend_compile.c and so is usually bypassed */
PHP_FUNCTION(is_object)302 PHP_FUNCTION(is_object)
303 {
304 	php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_OBJECT);
305 }
306 /* }}} */
307 
308 /* {{{ proto bool is_numeric(mixed value)
309    Returns true if value is a number or a numeric string */
PHP_FUNCTION(is_numeric)310 PHP_FUNCTION(is_numeric)
311 {
312 	zval *arg;
313 
314 	ZEND_PARSE_PARAMETERS_START(1, 1)
315 		Z_PARAM_ZVAL(arg)
316 	ZEND_PARSE_PARAMETERS_END();
317 
318 	switch (Z_TYPE_P(arg)) {
319 		case IS_LONG:
320 		case IS_DOUBLE:
321 			RETURN_TRUE;
322 			break;
323 
324 		case IS_STRING:
325 			if (is_numeric_string(Z_STRVAL_P(arg), Z_STRLEN_P(arg), NULL, NULL, 0)) {
326 				RETURN_TRUE;
327 			} else {
328 				RETURN_FALSE;
329 			}
330 			break;
331 
332 		default:
333 			RETURN_FALSE;
334 			break;
335 	}
336 }
337 /* }}} */
338 
339 /* {{{ proto bool is_scalar(mixed value)
340    Returns true if value is a scalar */
PHP_FUNCTION(is_scalar)341 PHP_FUNCTION(is_scalar)
342 {
343 	zval *arg;
344 
345 	ZEND_PARSE_PARAMETERS_START(1, 1)
346 		Z_PARAM_ZVAL(arg)
347 	ZEND_PARSE_PARAMETERS_END();
348 
349 	switch (Z_TYPE_P(arg)) {
350 		case IS_FALSE:
351 		case IS_TRUE:
352 		case IS_DOUBLE:
353 		case IS_LONG:
354 		case IS_STRING:
355 			RETURN_TRUE;
356 			break;
357 
358 		default:
359 			RETURN_FALSE;
360 			break;
361 	}
362 }
363 /* }}} */
364 
365 /* {{{ proto bool is_callable(mixed var [, bool syntax_only [, string callable_name]])
366    Returns true if var is callable. */
PHP_FUNCTION(is_callable)367 PHP_FUNCTION(is_callable)
368 {
369 	zval *var, *callable_name = NULL;
370 	zend_string *name;
371 	char *error;
372 	zend_bool retval;
373 	zend_bool syntax_only = 0;
374 	int check_flags = 0;
375 
376 	if (zend_parse_parameters(ZEND_NUM_ARGS(), "z|bz/", &var,
377 							  &syntax_only, &callable_name) == FAILURE) {
378 		return;
379 	}
380 
381 	if (syntax_only) {
382 		check_flags |= IS_CALLABLE_CHECK_SYNTAX_ONLY;
383 	}
384 	if (ZEND_NUM_ARGS() > 2) {
385 		retval = zend_is_callable_ex(var, NULL, check_flags, &name, NULL, &error);
386 		zval_dtor(callable_name);
387 		ZVAL_STR(callable_name, name);
388 	} else {
389 		retval = zend_is_callable_ex(var, NULL, check_flags, NULL, NULL, &error);
390 	}
391 	if (error) {
392 		/* ignore errors */
393 		efree(error);
394 	}
395 
396 	RETURN_BOOL(retval);
397 }
398 /* }}} */
399 
400 /*
401  * Local variables:
402  * tab-width: 4
403  * c-basic-offset: 4
404  * End:
405  * vim600: sw=4 ts=4 fdm=marker
406  * vim<600: sw=4 ts=4
407  */
408