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 */ |
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 */ |
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 */ |
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 */ |
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 */ |
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 */ |
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 | |
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 */ |
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 */ |
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 */ |
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) */ |
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*/ |
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 */ |
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 */ |
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 */ |
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 */ |
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 */ |
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. */ |
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 | |