xref: /PHP-5.3/ext/standard/type.c (revision a2045ff3)
1 /*
2    +----------------------------------------------------------------------+
3    | PHP Version 5                                                        |
4    +----------------------------------------------------------------------+
5    | Copyright (c) 1997-2013 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 				char *type_name;
76 				type_name = zend_rsrc_list_get_rsrc_type(Z_LVAL_PP(arg) TSRMLS_CC);
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 			char *type_name;
223 			type_name = zend_rsrc_list_get_rsrc_type(Z_LVAL_PP(arg) TSRMLS_CC);
224 			if (!type_name) {
225 				RETURN_FALSE;
226 			}
227 		}
228 		RETURN_TRUE;
229 	} else {
230 		RETURN_FALSE;
231 	}
232 }
233 
234 
235 /* {{{ proto bool is_null(mixed var)
236    Returns true if variable is null */
PHP_FUNCTION(is_null)237 PHP_FUNCTION(is_null)
238 {
239 	php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_NULL);
240 }
241 /* }}} */
242 
243 /* {{{ proto bool is_resource(mixed var)
244    Returns true if variable is a resource */
PHP_FUNCTION(is_resource)245 PHP_FUNCTION(is_resource)
246 {
247 	php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_RESOURCE);
248 }
249 /* }}} */
250 
251 /* {{{ proto bool is_bool(mixed var)
252    Returns true if variable is a boolean */
PHP_FUNCTION(is_bool)253 PHP_FUNCTION(is_bool)
254 {
255 	php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_BOOL);
256 }
257 /* }}} */
258 
259 /* {{{ proto bool is_long(mixed var)
260    Returns true if variable is a long (integer) */
PHP_FUNCTION(is_long)261 PHP_FUNCTION(is_long)
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*/
PHP_FUNCTION(is_float)269 PHP_FUNCTION(is_float)
270 {
271 	php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_DOUBLE);
272 }
273 /* }}} */
274 
275 /* {{{ proto bool is_string(mixed var)
276    Returns true if variable is a string */
PHP_FUNCTION(is_string)277 PHP_FUNCTION(is_string)
278 {
279 	php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_STRING);
280 }
281 /* }}} */
282 
283 /* {{{ proto bool is_array(mixed var)
284    Returns true if variable is an array */
PHP_FUNCTION(is_array)285 PHP_FUNCTION(is_array)
286 {
287 	php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_ARRAY);
288 }
289 /* }}} */
290 
291 /* {{{ proto bool is_object(mixed var)
292    Returns true if variable is an object */
PHP_FUNCTION(is_object)293 PHP_FUNCTION(is_object)
294 {
295 	php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_OBJECT);
296 }
297 /* }}} */
298 
299 /* {{{ proto bool is_numeric(mixed value)
300    Returns true if value is a number or a numeric string */
PHP_FUNCTION(is_numeric)301 PHP_FUNCTION(is_numeric)
302 {
303 	zval **arg;
304 
305 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &arg) == FAILURE) {
306 		return;
307 	}
308 
309 	switch (Z_TYPE_PP(arg)) {
310 		case IS_LONG:
311 		case IS_DOUBLE:
312 			RETURN_TRUE;
313 			break;
314 
315 		case IS_STRING:
316 			if (is_numeric_string(Z_STRVAL_PP(arg), Z_STRLEN_PP(arg), NULL, NULL, 0)) {
317 				RETURN_TRUE;
318 			} else {
319 				RETURN_FALSE;
320 			}
321 			break;
322 
323 		default:
324 			RETURN_FALSE;
325 			break;
326 	}
327 }
328 /* }}} */
329 
330 /* {{{ proto bool is_scalar(mixed value)
331    Returns true if value is a scalar */
PHP_FUNCTION(is_scalar)332 PHP_FUNCTION(is_scalar)
333 {
334 	zval **arg;
335 
336 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &arg) == FAILURE) {
337 		return;
338 	}
339 
340 	switch (Z_TYPE_PP(arg)) {
341 		case IS_BOOL:
342 		case IS_DOUBLE:
343 		case IS_LONG:
344 		case IS_STRING:
345 			RETURN_TRUE;
346 			break;
347 
348 		default:
349 			RETURN_FALSE;
350 			break;
351 	}
352 }
353 /* }}} */
354 
355 /* {{{ proto bool is_callable(mixed var [, bool syntax_only [, string callable_name]])
356    Returns true if var is callable. */
PHP_FUNCTION(is_callable)357 PHP_FUNCTION(is_callable)
358 {
359 	zval *var, **callable_name = NULL;
360 	char *name;
361 	char *error;
362 	zend_bool retval;
363 	zend_bool syntax_only = 0;
364 	int check_flags = 0;
365 
366 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|bZ", &var,
367 							  &syntax_only, &callable_name) == FAILURE) {
368 		return;
369 	}
370 
371 	if (syntax_only) {
372 		check_flags |= IS_CALLABLE_CHECK_SYNTAX_ONLY;
373 	}
374 	if (ZEND_NUM_ARGS() > 2) {
375 		retval = zend_is_callable_ex(var, NULL, check_flags, &name, NULL, NULL, &error TSRMLS_CC);
376 		zval_dtor(*callable_name);
377 		ZVAL_STRING(*callable_name, name, 0);
378 	} else {
379 		retval = zend_is_callable_ex(var, NULL, check_flags, NULL, NULL, NULL, &error TSRMLS_CC);
380 	}
381 	if (error) {
382 		/* ignore errors */
383 		efree(error);
384 	}
385 
386 	RETURN_BOOL(retval);
387 }
388 /* }}} */
389 
390 /*
391  * Local variables:
392  * tab-width: 4
393  * c-basic-offset: 4
394  * End:
395  * vim600: sw=4 ts=4 fdm=marker
396  * vim<600: sw=4 ts=4
397  */
398