xref: /PHP-5.4/ext/standard/type.c (revision c0d060f5)
1 /*
2    +----------------------------------------------------------------------+
3    | PHP Version 5                                                        |
4    +----------------------------------------------------------------------+
5    | Copyright (c) 1997-2014 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() TSRMLS_CC, "Z", &arg) == FAILURE) {
31 		return;
32 	}
33 
34 	switch (Z_TYPE_PP(arg)) {
35 		case IS_NULL:
36 			RETVAL_STRING("NULL", 1);
37 			break;
38 
39 		case IS_BOOL:
40 			RETVAL_STRING("boolean", 1);
41 			break;
42 
43 		case IS_LONG:
44 			RETVAL_STRING("integer", 1);
45 			break;
46 
47 		case IS_DOUBLE:
48 			RETVAL_STRING("double", 1);
49 			break;
50 
51 		case IS_STRING:
52 			RETVAL_STRING("string", 1);
53 			break;
54 
55 		case IS_ARRAY:
56 			RETVAL_STRING("array", 1);
57 			break;
58 
59 		case IS_OBJECT:
60 			RETVAL_STRING("object", 1);
61 		/*
62 		   {
63 		   char *result;
64 		   int res_len;
65 
66 		   res_len = sizeof("object of type ")-1 + Z_OBJCE_P(arg)->name_length;
67 		   spprintf(&result, 0, "object of type %s", Z_OBJCE_P(arg)->name);
68 		   RETVAL_STRINGL(result, res_len, 0);
69 		   }
70 		 */
71 			break;
72 
73 		case IS_RESOURCE:
74 			{
75 				const char *type_name = zend_rsrc_list_get_rsrc_type(Z_LVAL_PP(arg) TSRMLS_CC);
76 
77 				if (type_name) {
78 					RETVAL_STRING("resource", 1);
79 					break;
80 				}
81 			}
82 
83 		default:
84 			RETVAL_STRING("unknown type", 1);
85 	}
86 }
87 /* }}} */
88 
89 /* {{{ proto bool settype(mixed var, string type)
90    Set the type of the variable */
PHP_FUNCTION(settype)91 PHP_FUNCTION(settype)
92 {
93 	zval **var;
94 	char *type;
95 	int type_len = 0;
96 
97 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Zs", &var, &type, &type_len) == FAILURE) {
98 		return;
99 	}
100 
101 	if (!strcasecmp(type, "integer")) {
102 		convert_to_long(*var);
103 	} else if (!strcasecmp(type, "int")) {
104 		convert_to_long(*var);
105 	} else if (!strcasecmp(type, "float")) {
106 		convert_to_double(*var);
107 	} else if (!strcasecmp(type, "double")) { /* deprecated */
108 		convert_to_double(*var);
109 	} else if (!strcasecmp(type, "string")) {
110 		convert_to_string(*var);
111 	} else if (!strcasecmp(type, "array")) {
112 		convert_to_array(*var);
113 	} else if (!strcasecmp(type, "object")) {
114 		convert_to_object(*var);
115 	} else if (!strcasecmp(type, "bool")) {
116 		convert_to_boolean(*var);
117 	} else if (!strcasecmp(type, "boolean")) {
118 		convert_to_boolean(*var);
119 	} else if (!strcasecmp(type, "null")) {
120 		convert_to_null(*var);
121 	} else if (!strcasecmp(type, "resource")) {
122 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot convert to resource type");
123 		RETURN_FALSE;
124 	} else {
125 		php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid type");
126 		RETURN_FALSE;
127 	}
128 	RETVAL_TRUE;
129 }
130 /* }}} */
131 
132 /* {{{ proto int intval(mixed var [, int base])
133    Get the integer value of a variable using the optional base for the conversion */
PHP_FUNCTION(intval)134 PHP_FUNCTION(intval)
135 {
136 	zval **num;
137 	long arg_base;
138 	int base;
139 
140 	switch (ZEND_NUM_ARGS()) {
141 		case 1:
142 			if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &num) == FAILURE) {
143 				return;
144 			}
145 			base = 10;
146 			break;
147 
148 		case 2:
149 			if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Zl", &num, &arg_base) == FAILURE) {
150 				return;
151 			}
152 			base = arg_base;
153 			break;
154 
155 		default:
156 			WRONG_PARAM_COUNT;
157 	}
158 
159 	RETVAL_ZVAL(*num, 1, 0);
160 	convert_to_long_base(return_value, base);
161 }
162 /* }}} */
163 
164 /* {{{ proto float floatval(mixed var)
165    Get the float value of a variable */
PHP_FUNCTION(floatval)166 PHP_FUNCTION(floatval)
167 {
168 	zval **num;
169 
170 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &num) == FAILURE) {
171 		return;
172 	}
173 
174 	RETVAL_ZVAL(*num, 1, 0);
175 	convert_to_double(return_value);
176 }
177 /* }}} */
178 
179 /* {{{ proto string strval(mixed var)
180    Get the string value of a variable */
PHP_FUNCTION(strval)181 PHP_FUNCTION(strval)
182 {
183 	zval **num, *tmp;
184 	zval expr_copy;
185 	int use_copy;
186 
187 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &num) == FAILURE) {
188 		return;
189 	}
190 
191 	zend_make_printable_zval(*num, &expr_copy, &use_copy);
192 	if (use_copy) {
193 		tmp = &expr_copy;
194 		RETVAL_ZVAL(tmp, 0, 0);
195 	} else {
196 		RETVAL_ZVAL(*num, 1, 0);
197 	}
198 }
199 /* }}} */
200 
php_is_type(INTERNAL_FUNCTION_PARAMETERS,int type)201 static void php_is_type(INTERNAL_FUNCTION_PARAMETERS, int type)
202 {
203 	zval **arg;
204 
205 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &arg) == FAILURE) {
206 		RETURN_FALSE;
207 	}
208 
209 	if (Z_TYPE_PP(arg) == type) {
210 		if (type == IS_OBJECT) {
211 			zend_class_entry *ce;
212 			if(Z_OBJ_HT_PP(arg)->get_class_entry == NULL) {
213 			/* if there's no get_class_entry it's not a PHP object, so it can't be INCOMPLETE_CLASS */
214 				RETURN_TRUE;
215 			}
216 			ce = Z_OBJCE_PP(arg);
217 			if (!strcmp(ce->name, INCOMPLETE_CLASS)) {
218 				RETURN_FALSE;
219 			}
220 		}
221 		if (type == IS_RESOURCE) {
222 			const char *type_name = zend_rsrc_list_get_rsrc_type(Z_LVAL_PP(arg) TSRMLS_CC);
223 			if (!type_name) {
224 				RETURN_FALSE;
225 			}
226 		}
227 		RETURN_TRUE;
228 	} else {
229 		RETURN_FALSE;
230 	}
231 }
232 
233 
234 /* {{{ proto bool is_null(mixed var)
235    Returns true if variable is null */
PHP_FUNCTION(is_null)236 PHP_FUNCTION(is_null)
237 {
238 	php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_NULL);
239 }
240 /* }}} */
241 
242 /* {{{ proto bool is_resource(mixed var)
243    Returns true if variable is a resource */
PHP_FUNCTION(is_resource)244 PHP_FUNCTION(is_resource)
245 {
246 	php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_RESOURCE);
247 }
248 /* }}} */
249 
250 /* {{{ proto bool is_bool(mixed var)
251    Returns true if variable is a boolean */
PHP_FUNCTION(is_bool)252 PHP_FUNCTION(is_bool)
253 {
254 	php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_BOOL);
255 }
256 /* }}} */
257 
258 /* {{{ proto bool is_long(mixed var)
259    Returns true if variable is a long (integer) */
PHP_FUNCTION(is_long)260 PHP_FUNCTION(is_long)
261 {
262 	php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_LONG);
263 }
264 /* }}} */
265 
266 /* {{{ proto bool is_float(mixed var)
267    Returns true if variable is float point*/
PHP_FUNCTION(is_float)268 PHP_FUNCTION(is_float)
269 {
270 	php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_DOUBLE);
271 }
272 /* }}} */
273 
274 /* {{{ proto bool is_string(mixed var)
275    Returns true if variable is a string */
PHP_FUNCTION(is_string)276 PHP_FUNCTION(is_string)
277 {
278 	php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_STRING);
279 }
280 /* }}} */
281 
282 /* {{{ proto bool is_array(mixed var)
283    Returns true if variable is an array */
PHP_FUNCTION(is_array)284 PHP_FUNCTION(is_array)
285 {
286 	php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_ARRAY);
287 }
288 /* }}} */
289 
290 /* {{{ proto bool is_object(mixed var)
291    Returns true if variable is an object */
PHP_FUNCTION(is_object)292 PHP_FUNCTION(is_object)
293 {
294 	php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_OBJECT);
295 }
296 /* }}} */
297 
298 /* {{{ proto bool is_numeric(mixed value)
299    Returns true if value is a number or a numeric string */
PHP_FUNCTION(is_numeric)300 PHP_FUNCTION(is_numeric)
301 {
302 	zval **arg;
303 
304 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &arg) == FAILURE) {
305 		return;
306 	}
307 
308 	switch (Z_TYPE_PP(arg)) {
309 		case IS_LONG:
310 		case IS_DOUBLE:
311 			RETURN_TRUE;
312 			break;
313 
314 		case IS_STRING:
315 			if (is_numeric_string(Z_STRVAL_PP(arg), Z_STRLEN_PP(arg), NULL, NULL, 0)) {
316 				RETURN_TRUE;
317 			} else {
318 				RETURN_FALSE;
319 			}
320 			break;
321 
322 		default:
323 			RETURN_FALSE;
324 			break;
325 	}
326 }
327 /* }}} */
328 
329 /* {{{ proto bool is_scalar(mixed value)
330    Returns true if value is a scalar */
PHP_FUNCTION(is_scalar)331 PHP_FUNCTION(is_scalar)
332 {
333 	zval **arg;
334 
335 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &arg) == FAILURE) {
336 		return;
337 	}
338 
339 	switch (Z_TYPE_PP(arg)) {
340 		case IS_BOOL:
341 		case IS_DOUBLE:
342 		case IS_LONG:
343 		case IS_STRING:
344 			RETURN_TRUE;
345 			break;
346 
347 		default:
348 			RETURN_FALSE;
349 			break;
350 	}
351 }
352 /* }}} */
353 
354 /* {{{ proto bool is_callable(mixed var [, bool syntax_only [, string callable_name]])
355    Returns true if var is callable. */
PHP_FUNCTION(is_callable)356 PHP_FUNCTION(is_callable)
357 {
358 	zval *var, **callable_name = NULL;
359 	char *name;
360 	char *error;
361 	zend_bool retval;
362 	zend_bool syntax_only = 0;
363 	int check_flags = 0;
364 
365 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|bZ", &var,
366 							  &syntax_only, &callable_name) == FAILURE) {
367 		return;
368 	}
369 
370 	if (syntax_only) {
371 		check_flags |= IS_CALLABLE_CHECK_SYNTAX_ONLY;
372 	}
373 	if (ZEND_NUM_ARGS() > 2) {
374 		retval = zend_is_callable_ex(var, NULL, check_flags, &name, NULL, NULL, &error TSRMLS_CC);
375 		zval_dtor(*callable_name);
376 		ZVAL_STRING(*callable_name, name, 0);
377 	} else {
378 		retval = zend_is_callable_ex(var, NULL, check_flags, NULL, NULL, NULL, &error TSRMLS_CC);
379 	}
380 	if (error) {
381 		/* ignore errors */
382 		efree(error);
383 	}
384 
385 	RETURN_BOOL(retval);
386 }
387 /* }}} */
388 
389 /*
390  * Local variables:
391  * tab-width: 4
392  * c-basic-offset: 4
393  * End:
394  * vim600: sw=4 ts=4 fdm=marker
395  * vim<600: sw=4 ts=4
396  */
397