xref: /PHP-5.5/ext/standard/type.c (revision 73c1be26)
1 /*
2    +----------------------------------------------------------------------+
3    | PHP Version 5                                                        |
4    +----------------------------------------------------------------------+
5    | Copyright (c) 1997-2015 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 bool boolval(mixed var)
180    Get the boolean value of a variable */
PHP_FUNCTION(boolval)181 PHP_FUNCTION(boolval)
182 {
183 	zval **val;
184 
185 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &val) == FAILURE) {
186 		return;
187 	}
188 
189 	RETURN_BOOL(zend_is_true(*val));
190 }
191 /* }}} */
192 
193 /* {{{ proto string strval(mixed var)
194    Get the string value of a variable */
PHP_FUNCTION(strval)195 PHP_FUNCTION(strval)
196 {
197 	zval **num, *tmp;
198 	zval expr_copy;
199 	int use_copy;
200 
201 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &num) == FAILURE) {
202 		return;
203 	}
204 
205 	zend_make_printable_zval(*num, &expr_copy, &use_copy);
206 	if (use_copy) {
207 		tmp = &expr_copy;
208 		RETVAL_ZVAL(tmp, 0, 0);
209 	} else {
210 		RETVAL_ZVAL(*num, 1, 0);
211 	}
212 }
213 /* }}} */
214 
php_is_type(INTERNAL_FUNCTION_PARAMETERS,int type)215 static void php_is_type(INTERNAL_FUNCTION_PARAMETERS, int type)
216 {
217 	zval **arg;
218 
219 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &arg) == FAILURE) {
220 		RETURN_FALSE;
221 	}
222 
223 	if (Z_TYPE_PP(arg) == type) {
224 		if (type == IS_OBJECT) {
225 			zend_class_entry *ce;
226 			if(Z_OBJ_HT_PP(arg)->get_class_entry == NULL) {
227 			/* if there's no get_class_entry it's not a PHP object, so it can't be INCOMPLETE_CLASS */
228 				RETURN_TRUE;
229 			}
230 			ce = Z_OBJCE_PP(arg);
231 			if (!strcmp(ce->name, INCOMPLETE_CLASS)) {
232 				RETURN_FALSE;
233 			}
234 		}
235 		if (type == IS_RESOURCE) {
236 			const char *type_name = zend_rsrc_list_get_rsrc_type(Z_LVAL_PP(arg) TSRMLS_CC);
237 			if (!type_name) {
238 				RETURN_FALSE;
239 			}
240 		}
241 		RETURN_TRUE;
242 	} else {
243 		RETURN_FALSE;
244 	}
245 }
246 
247 
248 /* {{{ proto bool is_null(mixed var)
249    Returns true if variable is null */
PHP_FUNCTION(is_null)250 PHP_FUNCTION(is_null)
251 {
252 	php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_NULL);
253 }
254 /* }}} */
255 
256 /* {{{ proto bool is_resource(mixed var)
257    Returns true if variable is a resource */
PHP_FUNCTION(is_resource)258 PHP_FUNCTION(is_resource)
259 {
260 	php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_RESOURCE);
261 }
262 /* }}} */
263 
264 /* {{{ proto bool is_bool(mixed var)
265    Returns true if variable is a boolean */
PHP_FUNCTION(is_bool)266 PHP_FUNCTION(is_bool)
267 {
268 	php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_BOOL);
269 }
270 /* }}} */
271 
272 /* {{{ proto bool is_long(mixed var)
273    Returns true if variable is a long (integer) */
PHP_FUNCTION(is_long)274 PHP_FUNCTION(is_long)
275 {
276 	php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_LONG);
277 }
278 /* }}} */
279 
280 /* {{{ proto bool is_float(mixed var)
281    Returns true if variable is float point*/
PHP_FUNCTION(is_float)282 PHP_FUNCTION(is_float)
283 {
284 	php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_DOUBLE);
285 }
286 /* }}} */
287 
288 /* {{{ proto bool is_string(mixed var)
289    Returns true if variable is a string */
PHP_FUNCTION(is_string)290 PHP_FUNCTION(is_string)
291 {
292 	php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_STRING);
293 }
294 /* }}} */
295 
296 /* {{{ proto bool is_array(mixed var)
297    Returns true if variable is an array */
PHP_FUNCTION(is_array)298 PHP_FUNCTION(is_array)
299 {
300 	php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_ARRAY);
301 }
302 /* }}} */
303 
304 /* {{{ proto bool is_object(mixed var)
305    Returns true if variable is an object */
PHP_FUNCTION(is_object)306 PHP_FUNCTION(is_object)
307 {
308 	php_is_type(INTERNAL_FUNCTION_PARAM_PASSTHRU, IS_OBJECT);
309 }
310 /* }}} */
311 
312 /* {{{ proto bool is_numeric(mixed value)
313    Returns true if value is a number or a numeric string */
PHP_FUNCTION(is_numeric)314 PHP_FUNCTION(is_numeric)
315 {
316 	zval **arg;
317 
318 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &arg) == FAILURE) {
319 		return;
320 	}
321 
322 	switch (Z_TYPE_PP(arg)) {
323 		case IS_LONG:
324 		case IS_DOUBLE:
325 			RETURN_TRUE;
326 			break;
327 
328 		case IS_STRING:
329 			if (is_numeric_string(Z_STRVAL_PP(arg), Z_STRLEN_PP(arg), NULL, NULL, 0)) {
330 				RETURN_TRUE;
331 			} else {
332 				RETURN_FALSE;
333 			}
334 			break;
335 
336 		default:
337 			RETURN_FALSE;
338 			break;
339 	}
340 }
341 /* }}} */
342 
343 /* {{{ proto bool is_scalar(mixed value)
344    Returns true if value is a scalar */
PHP_FUNCTION(is_scalar)345 PHP_FUNCTION(is_scalar)
346 {
347 	zval **arg;
348 
349 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &arg) == FAILURE) {
350 		return;
351 	}
352 
353 	switch (Z_TYPE_PP(arg)) {
354 		case IS_BOOL:
355 		case IS_DOUBLE:
356 		case IS_LONG:
357 		case IS_STRING:
358 			RETURN_TRUE;
359 			break;
360 
361 		default:
362 			RETURN_FALSE;
363 			break;
364 	}
365 }
366 /* }}} */
367 
368 /* {{{ proto bool is_callable(mixed var [, bool syntax_only [, string callable_name]])
369    Returns true if var is callable. */
PHP_FUNCTION(is_callable)370 PHP_FUNCTION(is_callable)
371 {
372 	zval *var, **callable_name = NULL;
373 	char *name;
374 	char *error;
375 	zend_bool retval;
376 	zend_bool syntax_only = 0;
377 	int check_flags = 0;
378 
379 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|bZ", &var,
380 							  &syntax_only, &callable_name) == FAILURE) {
381 		return;
382 	}
383 
384 	if (syntax_only) {
385 		check_flags |= IS_CALLABLE_CHECK_SYNTAX_ONLY;
386 	}
387 	if (ZEND_NUM_ARGS() > 2) {
388 		retval = zend_is_callable_ex(var, NULL, check_flags, &name, NULL, NULL, &error TSRMLS_CC);
389 		zval_dtor(*callable_name);
390 		ZVAL_STRING(*callable_name, name, 0);
391 	} else {
392 		retval = zend_is_callable_ex(var, NULL, check_flags, NULL, NULL, NULL, &error TSRMLS_CC);
393 	}
394 	if (error) {
395 		/* ignore errors */
396 		efree(error);
397 	}
398 
399 	RETURN_BOOL(retval);
400 }
401 /* }}} */
402 
403 /*
404  * Local variables:
405  * tab-width: 4
406  * c-basic-offset: 4
407  * End:
408  * vim600: sw=4 ts=4 fdm=marker
409  * vim<600: sw=4 ts=4
410  */
411