- Added scalar typehinting.

This commit is contained in:
Derick Rethans 2010-05-20 19:18:35 +00:00
parent f291a1253d
commit 1bc9247651
31 changed files with 4015 additions and 2671 deletions

1
NEWS
View File

@ -36,6 +36,7 @@
FR #51815. (Pierrick)
- Added iterator support in MySQLi. mysqli_result implements Traversable.
(Andrey, Johannes)
- Added scalar typehinting. (Ilia, Derick)
- default_charset if not specified is now UTF-8 instead of ISO-8859-1. (Rasmus)

View File

@ -12,4 +12,4 @@ foo(123);
--EXPECTF--
3
Catchable fatal error: Argument 1 passed to foo() must be an array, integer given, called in %sarray_type_hint_001.php on line 7 and defined in %sarray_type_hint_001.php on line 2
Catchable fatal error: Argument 1 passed to foo() must be of the type array, integer given, called in %sarray_type_hint_001.php on line 7 and defined in %sarray_type_hint_001.php on line 2

View File

@ -0,0 +1,38 @@
--TEST--
Parameter type hint - Testing integer hint
--FILE--
<?php
function test_int($x, int $a = 1) {
}
test_int(1);
print "Ok\n";
test_int('1211');
print "Ok\n";
test_int(null);
print "Ok\n";
test_int(1, 1);
print "Ok\n";
test_int(null, '1211');
print "Ok\n";
?>
--EXPECTF--
Ok
Ok
Ok
Ok
Catchable fatal error: Argument 2 passed to test_int() must be of the type integer, string given, called in %s on line %d and defined in %s on line %d
--UEXPECTF--
Ok
Ok
Ok
Ok
Catchable fatal error: Argument 2 passed to test_int() must be of the type integer, Unicode string given, called in %s on line %d and defined in %s on line %d

View File

@ -0,0 +1,97 @@
--TEST--
Parameter type hint - Reflection
--FILE--
<?php
function test(int $a, double $b, string $c, boolean $d = true, resource $e, array $f = array(), object $g) {
}
$func = new ReflectionFunction('test');
Reflection::Export($func);
foreach ($func->getParameters() as $i => $param) {
printf(
"-- Parameter #%d: %s {\n".
" Allows NULL: %s\n".
" Hint Type: %s\n".
" Passed to by reference: %s\n".
" Is optional?: %s\n",
$i,
$param->getName(),
var_export($param->getClass(), 1),
$param->getTypeHint(),
var_export($param->allowsNull(), 1),
var_export($param->isPassedByReference(), 1),
$param->isOptional() ? 'yes' : 'no'
);
printf(" Int: %d | Double: %d | Bool: %d | String: %d | Resource: %d | Array: %d | Object: %d\n",
$param->isInt(), $param->isDouble(), $param->isBool(), $param->isString(),
$param->isResource(), $param->isArray(), $param->isObject());
print "}\n";
}
?>
--EXPECTF--
Function [ <user> function test ] {
@@ %s 3 - 4
- Parameters [7] {
Parameter #0 [ <required> integer $a ]
Parameter #1 [ <required> double $b ]
Parameter #2 [ <required> string $c ]
Parameter #3 [ <required> boolean $d ]
Parameter #4 [ <required> resource $e ]
Parameter #5 [ <required> array $f ]
Parameter #6 [ <required> object $g ]
}
}
-- Parameter #0: a {
Allows NULL: NULL
Hint Type: integer
Passed to by reference: false
Is optional?: false
Int: 1 | Double: 0 | Bool: 0 | String: 0 | Resource: 0 | Array: 0 | Object: 0
}
-- Parameter #1: b {
Allows NULL: NULL
Hint Type: double
Passed to by reference: false
Is optional?: false
Int: 0 | Double: 1 | Bool: 0 | String: 0 | Resource: 0 | Array: 0 | Object: 0
}
-- Parameter #2: c {
Allows NULL: NULL
Hint Type: string
Passed to by reference: false
Is optional?: false
Int: 0 | Double: 0 | Bool: 0 | String: 1 | Resource: 0 | Array: 0 | Object: 0
}
-- Parameter #3: d {
Allows NULL: NULL
Hint Type: boolean
Passed to by reference: false
Is optional?: false
Int: 0 | Double: 0 | Bool: 1 | String: 0 | Resource: 0 | Array: 0 | Object: 0
}
-- Parameter #4: e {
Allows NULL: NULL
Hint Type: resource
Passed to by reference: false
Is optional?: false
Int: 0 | Double: 0 | Bool: 0 | String: 0 | Resource: 1 | Array: 0 | Object: 0
}
-- Parameter #5: f {
Allows NULL: NULL
Hint Type: array
Passed to by reference: false
Is optional?: false
Int: 0 | Double: 0 | Bool: 0 | String: 0 | Resource: 0 | Array: 1 | Object: 0
}
-- Parameter #6: g {
Allows NULL: NULL
Hint Type: object
Passed to by reference: false
Is optional?: false
Int: 0 | Double: 0 | Bool: 0 | String: 0 | Resource: 0 | Array: 0 | Object: 1
}

View File

@ -0,0 +1,16 @@
--TEST--
Parameter type hint - Wrong parameter for integer
--FILE--
<?php
function test_int(int $a) {
echo $a, "\n";
}
test_int('+1');
?>
--EXPECTF--
Catchable fatal error: Argument 1 passed to test_int() must be of the type integer, string given, called in %s on line %d and defined in %s on line %d
--UEXPECTF--
Catchable fatal error: Argument 1 passed to test_int() must be of the type integer, Unicode string given, called in %s on line %d and defined in %s on line %d

View File

@ -0,0 +1,16 @@
--TEST--
Parameter type hint - Wrong parameter for double
--FILE--
<?php
function test_double(real $a) {
echo $a, "\n";
}
test_double('+1.1');
?>
--EXPECTF--
Catchable fatal error: Argument 1 passed to test_double() must be of the type double, string given, called in %s on line %d and defined in %s on line %d
--UEXPECTF--
Catchable fatal error: Argument 1 passed to test_double() must be of the type double, Unicode string given, called in %s on line %d and defined in %s on line %d

View File

@ -0,0 +1,23 @@
--TEST--
Parameter type hint - Wrong parameter for string
--FILE--
<?php
function test_str(string $a) {
echo $a, "\n";
}
test_str('+1.1');
test_str('-.1');
test_str('11213111112321312');
test_str('');
test_str(null);
?>
--EXPECTF--
+1.1
-.1
11213111112321312
Catchable fatal error: Argument 1 passed to test_str() must be of the type string, null given, called in %s on line %d and defined in %s on line %d

View File

@ -0,0 +1,22 @@
--TEST--
Parameter type hint - Testing NULL when allowed
--FILE--
<?php
function test_int(int $a = null) {
}
test_int(null);
function test_double(double $a = null) {
}
test_double(null);
function test_bool(bool $a = null) {
}
test_bool(null);
print "Done";
?>
--EXPECT--
Done

View File

@ -0,0 +1,46 @@
--TEST--
Parameter type hint - Testing parameter with reference
--FILE--
<?php
/* string */
function test_string(string &$a) {
$a .= '!!!';
}
$str = 'foo';
test_string($str);
var_dump($str);
/* integer */
function test_int(int &$b) {
$b += 2;
}
$b = 2;
test_int($b);
var_dump($b);
/* object */
function test_obj(object &$c) {
$c->tested = 1;
}
$c = new stdclass;
test_obj($c);
var_dump($c);
?>
--EXPECT--
string(6) "foo!!!"
int(4)
object(stdClass)#1 (1) {
["tested"]=>
int(1)
}
--UEXPECT--
unicode(6) "foo!!!"
int(4)
object(stdClass)#1 (1) {
[u"tested"]=>
int(1)
}

View File

@ -0,0 +1,20 @@
--TEST--
Parameter type hint - Testing string type hint with reference
--FILE--
<?php
function test(string &$a) {
$a .= '!!!';
}
$x = 'foo';
test($x);
var_dump($x);
?>
--EXPECT--
string(6) "foo!!!"
--UEXPECT--
unicode(6) "foo!!!"

View File

@ -0,0 +1,17 @@
--TEST--
Parameter type hint - Testing default parameter value
--FILE--
<?php
function test(string &$a, integer $x = 1) {
var_dump($x);
}
$y = 'foo';
test($y, 2);
test($y);
?>
--EXPECT--
int(2)
int(1)

View File

@ -0,0 +1,28 @@
--TEST--
Parameter type hint - Testing with heredoc
--FILE--
<?php
function test(string $str) {
}
test(<<<FOO
test!
FOO
);
test(<<<'FOO'
test!
FOO
);
test(<<<"FOO"
test!
FOO
);
print "Ok!";
?>
--EXPECT--
Ok!

View File

@ -0,0 +1,15 @@
--TEST--
Parameter type hint - Testing with undefined variable
--FILE--
<?php
function test(string $a) {
}
test($x);
?>
--EXPECTF--
Notice: Undefined variable: x in %s on line %d
Catchable fatal error: Argument 1 passed to test() must be of the type string, null given, called in %s on line %d and defined in %s on line %d

View File

@ -0,0 +1,18 @@
--TEST--
Parameter type hint - Testing with lambda function
--FILE--
<?php
$test = create_function('integer $i', 'return $i + 1;');
var_dump($test(1));
var_dump($test('foo'));
?>
--EXPECTF--
int(2)
Catchable fatal error: Argument 1 passed to __lambda_func() must be of the type integer, string given, called in %s on line %d and defined in %s(%d) : runtime-created function on line %d
--UEXPECTF--
int(2)
Catchable fatal error: Argument 1 passed to __lambda_func() must be of the type integer, Unicode string given, called in %s on line %d and defined in %s(%d) : runtime-created function on line %d

View File

@ -0,0 +1,16 @@
--TEST--
Parameter type hint - Testing with lambda function using 2 parameters
--FILE--
<?php
$test = create_function('integer $i, string $j', 'return $i + $j;');
var_dump($test(1, 'foo'));
var_dump($test(1, '1'));
var_dump($test(1, NULL));
?>
--EXPECTF--
int(1)
int(2)
Catchable fatal error: Argument 2 passed to __lambda_func() must be of the type string, null given, called in %s on line %d and defined in %s(%d) : runtime-created function on line %d

View File

@ -0,0 +1,16 @@
--TEST--
Parameter type hint - Testing in function inside function
--FILE--
<?php
function a() {
function b(real $c) {
}
return b(1);
}
a();
?>
--EXPECTF--
Catchable fatal error: Argument 1 passed to b() must be of the type double, integer given, called in %s on line %d and defined in %s on line %d

View File

@ -0,0 +1,19 @@
--TEST--
Parameter type hint - Testing with call_user_func()
--FILE--
<?php
function test(bool $b) {
print "ok\n";
}
call_user_func('test', true);
call_user_func('test', false);
call_user_func('test', NULL);
?>
--EXPECTF--
ok
ok
Catchable fatal error: Argument 1 passed to test() must be of the type boolean, null given in %s on line %d

View File

@ -0,0 +1,22 @@
--TEST--
Parameter type hint - Testing default parameter values
--FILE--
<?php
function test(string $a, bool $b = NULL, integer $c, double $d = NULL, $e) {
print "ok\n";
}
test('foo', NULL, 1, NULL, 'bar');
test('foo', true, 0, -1., NULL);
test('true', false, -1, 2.2222, 1.1);
test('1.1', false, -1, 11111111111111111111111111, true);
test('1', false, -1, NULL, new stdClass);
?>
--EXPECT--
ok
ok
ok
ok
ok

View File

@ -0,0 +1,14 @@
--TEST--
Parameter type hint - Testing default parameter values as constants
--FILE--
<?php
function test(int $foo = PHP_INT_MAX) {
print "ok\n";
}
test();
?>
--EXPECT--
ok

View File

@ -18,4 +18,4 @@ new bar(new \stdclass);
--EXPECTF--
NULL
Catchable fatal error: Argument 1 passed to foo\bar::__construct() must be an array, object given, called in %s on line %d and defined in %s on line %d
Catchable fatal error: Argument 1 passed to foo\bar::__construct() must be of the type array, object given, called in %s on line %d and defined in %s on line %d

View File

@ -566,6 +566,8 @@ typedef int (*zend_write_func_t)(const char *str, uint str_length);
#define IS_RESOURCE 7
#define IS_CONSTANT 8
#define IS_CONSTANT_ARRAY 9
/* used for type-hinting only */
#define IS_CLASS 10
/* Ugly hack to support constants as static array indices */
#define IS_CONSTANT_TYPE_MASK 0x00f

View File

@ -206,6 +206,7 @@ ZEND_API char *zend_get_type_by_const(int type) /* {{{ */
case IS_STRING:
return "string";
case IS_OBJECT:
case IS_CLASS:
return "object";
case IS_RESOURCE:
return "resource";

View File

@ -98,8 +98,9 @@ typedef struct _zend_fcall_info_cache {
#define ZEND_ARG_INFO(pass_by_ref, name) { #name, sizeof(#name)-1, NULL, 0, 0, 0, pass_by_ref, 0, 0 },
#define ZEND_ARG_PASS_INFO(pass_by_ref) { NULL, 0, NULL, 0, 0, 0, pass_by_ref, 0, 0 },
#define ZEND_ARG_OBJ_INFO(pass_by_ref, name, classname, allow_null) { #name, sizeof(#name)-1, #classname, sizeof(#classname)-1, 0, allow_null, pass_by_ref, 0, 0 },
#define ZEND_ARG_ARRAY_INFO(pass_by_ref, name, allow_null) { #name, sizeof(#name)-1, NULL, 0, 1, allow_null, pass_by_ref, 0, 0 },
#define ZEND_ARG_OBJ_INFO(pass_by_ref, name, classname, allow_null) { #name, sizeof(#name)-1, #classname, sizeof(#classname)-1, IS_CLASS, allow_null, pass_by_ref, 0, 0 },
#define ZEND_ARG_ARRAY_INFO(pass_by_ref, name, allow_null) { #name, sizeof(#name)-1, NULL, 0, IS_ARRAY, allow_null, pass_by_ref, 0, 0 },
#define ZEND_ARG_TYPE_INFO(pass_by_ref, name, type_hint, allow_null) { #name, sizeof(#name)-1, NULL, 0, type_hint, allow_null, pass_by_ref, 0, 0 },
#define ZEND_BEGIN_ARG_INFO_EX(name, pass_rest_by_reference, return_reference, required_num_args) \
static const zend_arg_info name[] = { \
{ NULL, 0, NULL, 0, 0, 0, pass_rest_by_reference, return_reference, required_num_args },

View File

@ -1807,7 +1807,7 @@ void zend_do_receive_arg(zend_uchar op, znode *varname, const znode *offset, con
cur_arg_info = &CG(active_op_array)->arg_info[CG(active_op_array)->num_args-1];
cur_arg_info->name = CG(new_interned_string)(estrndup(varname->u.constant.value.str.val, varname->u.constant.value.str.len), varname->u.constant.value.str.len + 1, 1 TSRMLS_CC);
cur_arg_info->name_len = varname->u.constant.value.str.len;
cur_arg_info->array_type_hint = 0;
cur_arg_info->type_hint = 0;
cur_arg_info->allow_null = 1;
cur_arg_info->pass_by_reference = pass_by_reference;
cur_arg_info->class_name = NULL;
@ -1815,7 +1815,10 @@ void zend_do_receive_arg(zend_uchar op, znode *varname, const znode *offset, con
if (class_type->op_type != IS_UNUSED) {
cur_arg_info->allow_null = 0;
if (class_type->u.constant.type == IS_STRING) {
cur_arg_info->type_hint = class_type->u.constant.type;
switch (class_type->u.constant.type) {
case IS_CLASS:
if (ZEND_FETCH_CLASS_DEFAULT == zend_get_class_fetch_type(Z_STRVAL(class_type->u.constant), Z_STRLEN(class_type->u.constant))) {
zend_resolve_class_name(class_type, &opline->extended_value, 1 TSRMLS_CC);
}
@ -1829,10 +1832,9 @@ void zend_do_receive_arg(zend_uchar op, znode *varname, const znode *offset, con
zend_error(E_COMPILE_ERROR, "Default value for parameters with a class type hint can only be NULL");
}
}
} else {
cur_arg_info->array_type_hint = 1;
cur_arg_info->class_name = NULL;
cur_arg_info->class_name_len = 0;
break;
case IS_ARRAY:
if (op == ZEND_RECV_INIT) {
if (Z_TYPE(initialization->u.constant) == IS_NULL || (Z_TYPE(initialization->u.constant) == IS_CONSTANT && !strcasecmp(Z_STRVAL(initialization->u.constant), "NULL"))) {
cur_arg_info->allow_null = 1;
@ -1840,6 +1842,26 @@ void zend_do_receive_arg(zend_uchar op, znode *varname, const znode *offset, con
zend_error(E_COMPILE_ERROR, "Default value for parameters with array type hint can only be an array or NULL");
}
}
break;
/* scalar type hinting */
case IS_BOOL:
case IS_STRING:
case IS_LONG:
case IS_DOUBLE:
case IS_RESOURCE:
case IS_OBJECT:
if (op == ZEND_RECV_INIT) {
if (Z_TYPE(initialization->u.constant) != class_type->u.constant.type && Z_TYPE(initialization->u.constant) != IS_NULL && (Z_TYPE(initialization->u.constant) & IS_CONSTANT_TYPE_MASK) != IS_CONSTANT) {
zend_error(E_COMPILE_ERROR, "Default value for parameters with %s type hint can only be %s or NULL", zend_get_type_by_const(class_type->u.constant.type), zend_get_type_by_const(class_type->u.constant.type));
} else if (Z_TYPE(initialization->u.constant) == IS_NULL) {
cur_arg_info->allow_null = 1;
}
}
break;
default:
zend_error(E_COMPILE_ERROR, "Unknown type hint");
}
}
}
@ -2868,8 +2890,8 @@ static zend_bool zend_do_perform_implementation_check(const zend_function *fe, c
return 0;
}
}
if (fe->common.arg_info[i].array_type_hint != proto->common.arg_info[i].array_type_hint) {
/* Only one has an array type hint and the other one doesn't */
if (fe->common.arg_info[i].type_hint != proto->common.arg_info[i].type_hint) {
/* Incompatible type hint */
return 0;
}
if (fe->common.arg_info[i].pass_by_reference != proto->common.arg_info[i].pass_by_reference) {

View File

@ -194,7 +194,7 @@ typedef struct _zend_arg_info {
zend_uint name_len;
const char *class_name;
zend_uint class_name_len;
zend_bool array_type_hint;
zend_uint type_hint;
zend_bool allow_null;
zend_bool pass_by_reference;
zend_bool return_reference;

View File

@ -671,13 +671,21 @@ static inline int zend_verify_arg_type(zend_function *zf, zend_uint arg_num, zva
need_msg = zend_verify_arg_class_kind(cur_arg_info, fetch_type, &class_name, &ce TSRMLS_CC);
return zend_verify_arg_error(zf, arg_num, need_msg, class_name, zend_zval_type_name(arg), "" TSRMLS_CC);
}
} else if (cur_arg_info->array_type_hint) {
} else if (cur_arg_info->type_hint) {
if (!arg) {
return zend_verify_arg_error(zf, arg_num, "be an array", "", "none", "" TSRMLS_CC);
return zend_verify_arg_error(zf, arg_num, "be of the type ", zend_get_type_by_const(cur_arg_info->type_hint), "none", "" TSRMLS_CC);
}
if (Z_TYPE_P(arg) != IS_ARRAY && (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null)) {
return zend_verify_arg_error(zf, arg_num, "be an array", "", zend_zval_type_name(arg), "" TSRMLS_CC);
/* existing type already matches the hint or forced type */
if (Z_TYPE_P(arg) == cur_arg_info->type_hint) {
return 1;
}
/* NULL type given, check if parameter is optional */
if (Z_TYPE_P(arg) == IS_NULL && cur_arg_info->allow_null) {
return 1;
}
return zend_verify_arg_error(zf, arg_num, "be of the type ", zend_get_type_by_const(cur_arg_info->type_hint), "", zend_zval_type_name(arg) TSRMLS_CC);
}
return 1;
}

View File

@ -130,6 +130,12 @@
%token T_DOUBLE_ARROW
%token T_LIST
%token T_ARRAY
%token T_BOOL_HINT
%token T_STRING_HINT
%token T_INT_HINT
%token T_DOUBLE_HINT
%token T_RESOURCE_HINT
%token T_OBJECT_HINT
%token T_CLASS_C
%token T_METHOD_C
%token T_FUNC_C
@ -466,8 +472,14 @@ non_empty_parameter_list:
optional_class_type:
/* empty */ { $$.op_type = IS_UNUSED; }
| fully_qualified_class_name { $$ = $1; }
| T_ARRAY { $$.op_type = IS_CONST; Z_TYPE($$.u.constant)=IS_NULL;}
| T_ARRAY { $$ = $1; $$.op_type = IS_CONST; Z_TYPE($$.u.constant)=IS_ARRAY; }
| T_BOOL_HINT { $$ = $1; $$.op_type = IS_CONST; Z_TYPE($$.u.constant)=IS_BOOL; }
| T_STRING_HINT { $$ = $1; $$.op_type = IS_CONST; Z_TYPE($$.u.constant)=IS_STRING; }
| T_INT_HINT { $$ = $1; $$.op_type = IS_CONST; Z_TYPE($$.u.constant)=IS_LONG; }
| T_DOUBLE_HINT { $$ = $1; $$.op_type = IS_CONST; Z_TYPE($$.u.constant)=IS_DOUBLE; }
| T_RESOURCE_HINT { $$ = $1; $$.op_type = IS_CONST; Z_TYPE($$.u.constant)=IS_RESOURCE; }
| T_OBJECT_HINT { $$ = $1; $$.op_type = IS_CONST; Z_TYPE($$.u.constant)=IS_OBJECT; }
| fully_qualified_class_name { $$ = $1; $$.op_type = IS_CONST; Z_TYPE($$.u.constant)=IS_CLASS; }
;

File diff suppressed because it is too large Load Diff

View File

@ -1172,6 +1172,52 @@ NEWLINE ("\r"|"\n"|"\r\n")
return T_ARRAY;
}
<ST_IN_SCRIPTING>("bool"|"boolean"){TABS_AND_SPACES}[ \t&]+"$" {
if (yytext[4] == 'e') {
yyless((sizeof("boolean") - 1));
} else {
yyless((sizeof("bool") - 1));
}
return T_BOOL_HINT;
}
<ST_IN_SCRIPTING>("string"|"binary"){TABS_AND_SPACES}[ \t&]+"$" {
yyless(6);
return T_STRING_HINT;
}
<ST_IN_SCRIPTING>("int"|"integer"|"long"){TABS_AND_SPACES}[ \t&]+"$" {
if (yytext[3] == 'e') {
yyless((sizeof("integer") - 1));
} else if (yytext[3] == 'g') {
yyless((sizeof("long") - 1));
} else {
yyless(3);
}
return T_INT_HINT;
}
<ST_IN_SCRIPTING>("real"|"double"|"float"){TABS_AND_SPACES}[ \t&]+"$" {
if (yytext[4] == 'l') {
yyless((sizeof("double") - 1));
} else if (yytext[4] == 't') {
yyless((sizeof("float") - 1));
} else {
yyless(4);
}
return T_DOUBLE_HINT;
}
<ST_IN_SCRIPTING>"resource"{TABS_AND_SPACES}[ \t&]+"$" {
yyless((sizeof("resource") - 1));
return T_RESOURCE_HINT;
}
<ST_IN_SCRIPTING>"object"{TABS_AND_SPACES}[ \t&]+"$" {
yyless((sizeof("object") - 1));
return T_OBJECT_HINT;
}
<ST_IN_SCRIPTING>"++" {
return T_INC;
}

View File

@ -1,4 +1,4 @@
/* Generated by re2c 0.13.5 on Thu Apr 22 23:49:41 2010 */
/* Generated by re2c 0.13.5 on Thu May 20 09:19:36 2010 */
#line 3 "Zend/zend_language_scanner_defs.h"
enum YYCONDTYPE {

View File

@ -674,8 +674,8 @@ static void _parameter_string(string *str, zend_function *fptr, struct _zend_arg
if (arg_info->allow_null) {
string_printf(str, "or NULL ");
}
} else if (arg_info->array_type_hint) {
string_printf(str, "array ");
} else if (arg_info->type_hint) {
string_printf(str, "%s ", zend_get_type_by_const(arg_info->type_hint));
if (arg_info->allow_null) {
string_printf(str, "or NULL ");
}
@ -2338,7 +2338,102 @@ ZEND_METHOD(reflection_parameter, isArray)
}
GET_REFLECTION_OBJECT_PTR(param);
RETVAL_BOOL(param->arg_info->array_type_hint);
RETVAL_BOOL(param->arg_info->type_hint == IS_ARRAY);
}
/* }}} */
/* {{{ proto public bool ReflectionParameter::isInt()
Returns whether parameter MUST be a long */
ZEND_METHOD(reflection_parameter, isInt)
{
reflection_object *intern;
parameter_reference *param;
GET_REFLECTION_OBJECT_PTR(param);
RETVAL_BOOL(param->arg_info->type_hint == IS_LONG);
}
/* }}} */
/* {{{ proto public bool ReflectionParameter::isDouble()
Returns whether parameter MUST be a double */
ZEND_METHOD(reflection_parameter, isDouble)
{
reflection_object *intern;
parameter_reference *param;
GET_REFLECTION_OBJECT_PTR(param);
RETVAL_BOOL(param->arg_info->type_hint == IS_DOUBLE);
}
/* }}} */
/* {{{ proto public bool ReflectionParameter::isBool()
Returns whether parameter MUST be a boolean */
ZEND_METHOD(reflection_parameter, isBool)
{
reflection_object *intern;
parameter_reference *param;
GET_REFLECTION_OBJECT_PTR(param);
RETVAL_BOOL(param->arg_info->type_hint == IS_BOOL);
}
/* }}} */
/* {{{ proto public bool ReflectionParameter::isObject()
Returns whether parameter MUST be a boolean */
ZEND_METHOD(reflection_parameter, isObject)
{
reflection_object *intern;
parameter_reference *param;
GET_REFLECTION_OBJECT_PTR(param);
RETVAL_BOOL(param->arg_info->type_hint == IS_OBJECT);
}
/* }}} */
/* {{{ proto public bool ReflectionParameter::isString()
Returns whether parameter MUST be a string */
ZEND_METHOD(reflection_parameter, isString)
{
reflection_object *intern;
parameter_reference *param;
GET_REFLECTION_OBJECT_PTR(param);
RETVAL_BOOL(param->arg_info->type_hint == IS_STRING);
}
/* }}} */
/* {{{ proto public bool ReflectionParameter::isResource()
Returns whether parameter MUST be a resource */
ZEND_METHOD(reflection_parameter, isResource)
{
reflection_object *intern;
parameter_reference *param;
GET_REFLECTION_OBJECT_PTR(param);
RETVAL_BOOL(param->arg_info->type_hint == IS_RESOURCE);
}
/* }}} */
/* {{{ proto public string ReflectionParameter::getTypeHint()
Returns what type hint is defined for this parameter */
ZEND_METHOD(reflection_parameter, getTypeHint)
{
reflection_object *intern;
parameter_reference *param;
GET_REFLECTION_OBJECT_PTR(param);
if (!param->arg_info->type_hint) {
RETURN_FALSE;
}
RETURN_STRING(zend_get_type_by_const(param->arg_info->type_hint), 1);
}
/* }}} */
@ -5089,7 +5184,7 @@ ZEND_METHOD(reflection_extension, getDependencies)
}
/* }}} */
/* {{{ proto public void ReflectionExtension::info() U
/* {{{ proto public void ReflectionExtension::info()
Prints phpinfo block for the extension */
ZEND_METHOD(reflection_extension, info)
{
@ -5617,6 +5712,13 @@ static const zend_function_entry reflection_parameter_functions[] = {
ZEND_ME(reflection_parameter, getDeclaringClass, arginfo_reflection__void, 0)
ZEND_ME(reflection_parameter, getClass, arginfo_reflection__void, 0)
ZEND_ME(reflection_parameter, isArray, arginfo_reflection__void, 0)
ZEND_ME(reflection_parameter, isInt, arginfo_reflection__void, 0)
ZEND_ME(reflection_parameter, isDouble, arginfo_reflection__void, 0)
ZEND_ME(reflection_parameter, isBool, arginfo_reflection__void, 0)
ZEND_ME(reflection_parameter, getTypeHint, arginfo_reflection__void, 0)
ZEND_ME(reflection_parameter, isString, arginfo_reflection__void, 0)
ZEND_ME(reflection_parameter, isObject, arginfo_reflection__void, 0)
ZEND_ME(reflection_parameter, isResource, arginfo_reflection__void, 0)
ZEND_ME(reflection_parameter, allowsNull, arginfo_reflection__void, 0)
ZEND_ME(reflection_parameter, getPosition, arginfo_reflection__void, 0)
ZEND_ME(reflection_parameter, isOptional, arginfo_reflection__void, 0)