| From | Sent On | Attachments |
|---|---|---|
| Hannes Magnusson | Jun 6, 2011 12:41 pm | .txt |
| Stas Malyshev | Jun 6, 2011 1:35 pm | |
| Hannes Magnusson | Jun 6, 2011 1:48 pm | |
| Christopher Jones | Jun 6, 2011 1:49 pm | |
| Stas Malyshev | Jun 6, 2011 2:16 pm | |
| Matthew Weier O'Phinney | Jun 6, 2011 3:15 pm | |
| Pierre Joye | Jun 6, 2011 3:26 pm | |
| Matthew Weier O'Phinney | Jun 6, 2011 3:32 pm | |
| Etienne Kneuss | Jun 6, 2011 3:41 pm | |
| Chris Stockton | Jun 6, 2011 3:51 pm | |
| Chris Stockton | Jun 6, 2011 3:52 pm | |
| Ferenc Kovacs | Jun 6, 2011 4:01 pm | |
| Stas Malyshev | Jun 6, 2011 4:01 pm | |
| Chris Stockton | Jun 6, 2011 4:20 pm | |
| Derick Rethans | Jun 6, 2011 4:30 pm | |
| Martin Scotta | Jun 6, 2011 7:50 pm | |
| Jordi Boggiano | Jun 7, 2011 3:08 am | |
| Hannes Magnusson | Jun 7, 2011 6:59 am | |
| Richard Quadling | Jun 7, 2011 7:03 am | |
| Hannes Magnusson | Jun 7, 2011 7:21 am | |
| Jaroslav Hanslik | Jun 7, 2011 8:22 am | |
| Matthew Weier O'Phinney | Jun 7, 2011 9:10 am | |
| Stas Malyshev | Jun 7, 2011 11:50 am | |
| David Zülke | Jun 7, 2011 12:03 pm | |
| Stas Malyshev | Jun 7, 2011 12:12 pm | |
| David Zülke | Jun 7, 2011 12:28 pm | |
| Anthony Ferrara | Jun 7, 2011 12:37 pm | |
| Martin Scotta | Jun 7, 2011 1:28 pm | |
| Stas Malyshev | Jun 7, 2011 1:31 pm | |
| David Zülke | Jun 7, 2011 1:32 pm | |
| Pierre Joye | Jun 7, 2011 1:36 pm | |
| Mike van Riel | Jun 7, 2011 1:43 pm | |
| Matthew Weier O'Phinney | Jun 7, 2011 1:44 pm | |
| dukeofgaming | Jun 7, 2011 2:15 pm | |
| Matthew Weier O'Phinney | Jun 7, 2011 2:41 pm | |
| dukeofgaming | Jun 7, 2011 3:38 pm | |
| Johannes Schlüter | Jun 7, 2011 4:39 pm | |
| David Zülke | Jun 7, 2011 5:04 pm | |
| Alexey Shein | Jun 7, 2011 10:24 pm | |
| Hannes Magnusson | Jun 8, 2011 1:31 am | |
| Hannes Magnusson | Jun 8, 2011 1:38 am | |
| Alexey Shein | Jun 8, 2011 1:47 am | |
| Johannes Schlüter | Jun 8, 2011 3:04 am | |
| Hannes Magnusson | Jun 8, 2011 3:17 am | |
| Richard Quadling | Jun 8, 2011 3:27 am | |
| Johannes Schlüter | Jun 8, 2011 3:28 am | |
| Hannes Magnusson | Jun 8, 2011 3:30 am | |
| Johannes Schlüter | Jun 8, 2011 3:31 am | |
| Richard Quadling | Jun 8, 2011 3:31 am | |
| Anthony Ferrara | Jun 8, 2011 6:31 am | |
| Martin Scotta | Jun 8, 2011 7:42 am | |
| Martin Scotta | Jun 8, 2011 7:48 am | |
| David Zülke | Jun 8, 2011 8:53 am | |
| Johannes Schlüter | Jul 10, 2011 12:02 pm | |
| Stas Malyshev | Jul 10, 2011 12:57 pm | |
| Hannes Magnusson | Jul 11, 2011 1:21 am | |
| Stas Malyshev | Jul 11, 2011 1:27 am | |
| Peter Cowburn | Jul 11, 2011 1:37 am | |
| Hannes Magnusson | Jul 11, 2011 1:38 am | |
| Stas Malyshev | Jul 11, 2011 1:43 am |
| Subject: | [PHP-DEV] Callable typehint | |
|---|---|---|
| From: | Hannes Magnusson (hann...@gmail.com) | |
| Date: | Jun 6, 2011 12:41:00 pm | |
| List: | net.php.lists.internals | |
| Attachments: | ||
Hi
As quickly mentioned in the '$arr = array('Hello', 'world'); $arr();' thread[1], we are hitting the need for a callable typehint.
See attached patch+phpt; Any objections to include it in 5.4?
-Hannes
[1] http://php.markmail.org/message/gdas65h3im52sleg
Index: Zend/zend.h =================================================================== --- Zend/zend.h (revision 311867) +++ Zend/zend.h (working copy) @@ -573,6 +573,7 @@ #define IS_RESOURCE 7 #define IS_CONSTANT 8 #define IS_CONSTANT_ARRAY 9 +#define IS_CALLABLE 10
/* Ugly hack to support constants as static array indices */
#define IS_CONSTANT_TYPE_MASK 0x00f
Index: Zend/zend_execute.c
===================================================================
--- Zend/zend_execute.c (revision 311867)
+++ Zend/zend_execute.c (working copy)
@@ -626,13 +626,24 @@
need_msg = zend_verify_arg_class_kind(cur_arg_info, fetch_type, &class_name,
&ce TSRMLS_CC);
return zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, need_msg,
class_name, zend_zval_type_name(arg), "" TSRMLS_CC);
}
- } else if (cur_arg_info->type_hint && cur_arg_info->type_hint == IS_ARRAY) {
- if (!arg) {
- return zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, "be of the
type array", "", "none", "" TSRMLS_CC);
- }
+ } else if (cur_arg_info->type_hint) {
+ switch(cur_arg_info->type_hint) {
+ case IS_ARRAY:
+ if (!arg) {
+ return zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, "be of the
type array", "", "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(E_RECOVERABLE_ERROR, zf, arg_num, "be of the
type array", "", zend_zval_type_name(arg), "" 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(E_RECOVERABLE_ERROR, zf, arg_num, "be of the
type array", "", zend_zval_type_name(arg), "" TSRMLS_CC);
+ }
+ break;
+ case IS_CALLABLE:
+ if (!zend_is_callable(arg, IS_CALLABLE_CHECK_SILENT, NULL) && (Z_TYPE_P(arg)
!= IS_NULL || !cur_arg_info->allow_null)) {
+ return zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, "be
callable", "", zend_zval_type_name(arg), "" TSRMLS_CC);
+ }
+ break;
+ default:
+ zend_error(E_ERROR, "Unknown typehint");
}
}
return 1;
Index: Zend/zend_language_scanner.l
===================================================================
--- Zend/zend_language_scanner.l (revision 311867)
+++ Zend/zend_language_scanner.l (working copy)
@@ -1310,6 +1310,10 @@
return T_ARRAY;
}
+<ST_IN_SCRIPTING>"callable" { + return T_CALLABLE; +} + <ST_IN_SCRIPTING>"++" { return T_INC; } Index: Zend/zend_compile.c =================================================================== --- Zend/zend_compile.c (revision 311867) +++ Zend/zend_compile.c (working copy) @@ -1849,28 +1849,40 @@ cur_arg_info->allow_null = 0;
if (class_type->u.constant.type != IS_NULL) {
- cur_arg_info->type_hint = IS_OBJECT;
- 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);
- }
- class_type->u.constant.value.str.val =
zend_new_interned_string(class_type->u.constant.value.str.val,
class_type->u.constant.value.str.len + 1, 1 TSRMLS_CC);
- cur_arg_info->class_name = class_type->u.constant.value.str.val;
- cur_arg_info->class_name_len = class_type->u.constant.value.str.len;
- 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;
- } else {
- zend_error(E_COMPILE_ERROR, "Default value for parameters with a class
type hint can only be NULL");
+ if (class_type->u.constant.type == IS_ARRAY) {
+ cur_arg_info->type_hint = 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;
+ } else if (Z_TYPE(initialization->u.constant) != IS_ARRAY &&
Z_TYPE(initialization->u.constant) != IS_CONSTANT_ARRAY) {
+ zend_error(E_COMPILE_ERROR, "Default value for parameters with array type
hint can only be an array or NULL");
+ }
}
- }
- } else {
- cur_arg_info->type_hint = 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;
- } else if (Z_TYPE(initialization->u.constant) != IS_ARRAY &&
Z_TYPE(initialization->u.constant) != IS_CONSTANT_ARRAY) {
- zend_error(E_COMPILE_ERROR, "Default value for parameters with array type
hint can only be an array or NULL");
+ } else if (class_type->u.constant.type == IS_CALLABLE) {
+ char *callable_name;
+ cur_arg_info->type_hint = IS_CALLABLE;
+ 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;
+ } else {
+ zend_error(E_COMPILE_ERROR, "Default value for parameters with callable
type hint can only be NULL");
+ }
}
+ } else {
+ cur_arg_info->type_hint = IS_OBJECT;
+ 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);
+ }
+ class_type->u.constant.value.str.val =
zend_new_interned_string(class_type->u.constant.value.str.val,
class_type->u.constant.value.str.len + 1, 1 TSRMLS_CC);
+ cur_arg_info->class_name = class_type->u.constant.value.str.val;
+ cur_arg_info->class_name_len = class_type->u.constant.value.str.len;
+ 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;
+ } else {
+ zend_error(E_COMPILE_ERROR, "Default value for parameters with a class
type hint can only be NULL");
+ }
+ }
}
}
}
Index: Zend/zend_language_parser.y
===================================================================
--- Zend/zend_language_parser.y (revision 311867)
+++ Zend/zend_language_parser.y (working copy)
@@ -130,6 +130,7 @@
%token T_DOUBLE_ARROW
%token T_LIST
%token T_ARRAY
+%token T_CALLABLE
%token T_CLASS_C
%token T_METHOD_C
%token T_FUNC_C
@@ -466,7 +467,8 @@
optional_class_type: /* empty */ { $$.op_type = IS_UNUSED; } - | T_ARRAY { $$.op_type = IS_CONST; Z_TYPE($$.u.constant)=IS_NULL; } + | T_ARRAY { $$.op_type = IS_CONST; Z_TYPE($$.u.constant)=IS_ARRAY; } + | T_CALLABLE { $$.op_type = IS_CONST; Z_TYPE($$.u.constant)=IS_CALLABLE; } | fully_qualified_class_name { $$ = $1; } ;
Index: Zend/tests/callable_type_hint_001.phpt
===================================================================
--- Zend/tests/callable_type_hint_001.phpt (revision 0)
+++ Zend/tests/callable_type_hint_001.phpt (revision 0)
@@ -0,0 +1,40 @@
+--TEST--
+callable type hint#001
+--FILE--
+<?php
+
+class bar {
+ function baz() {}
+ static function foo() {}
+}
+function foo(callable $bar) {
+ var_dump($bar);
+}
+$closure = function () {};
+
+foo("strpos");
+foo("foo");
+foo(array("bar", "baz"));
+foo(array("bar", "foo"));
+foo($closure);
+--EXPECTF--
+string(6) "strpos"
+string(3) "foo"
+
+Strict Standards: Non-static method bar::baz() should not be called statically
in %scallable_type_hint_001.php on line %d
+array(2) {
+ [0]=>
+ string(3) "bar"
+ [1]=>
+ string(3) "baz"
+}
+array(2) {
+ [0]=>
+ string(3) "bar"
+ [1]=>
+ string(3) "foo"
+}
+object(Closure)#%d (0) {
+}
+
+
-- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php






.txt