On Wed, 11 Aug 2010, Derick Rethans wrote:

> On Wed, 11 Aug 2010, Stas Malyshev wrote:
> 
> > So I'd propose doing the following:
> > 
> > 1. Moving parameter typing to a feature branch (by branching current trunk 
> > and
> > then rolling back the typing part in the trunk).
> > 2. Starting 5.4 alpha process after that basing on trunk.
> > 
> > Any objections to this?
> 
> A little bit; yes. There is indeed 0 consensus for having the strict 
> typehints. However, instead of removing it altogether, and instead 
> answering every mail in this thread :P, I wrote/am writing a patch that 
> removes the hard type checks. It however keeps the parsed structures and 
> reflection API for it. In this sense, they're actually real hints. The 
> patch also adds a mechanism similariy to the zend_error_cb mechanism so 
> that extensions could override the argument type checking. As my use 
> case for strict checking is development I'd be happy to just move the 
> hard checks into an extension. I could even offer a soft check. It also 
> allows some type inference which might be useful for webservice 
> introspecition generation. I am sure SOAP might have some benefit of 
> this, and I know that at least pecl/dbus does. The patch is attached, 
> but not ready (I haven't remove the hard checks yet because things got 
> busy at work).

I've spend some more time on this, and have attached a new patch that:

- Removes the strict type verification, changing it back into typehints 
  only.
- Keeps the current syntax so that typehints create structures in the 
  function entries.
- Keeps the reflection API for the syntax, so that you can query the 
  typehints.
- Changed the API so that the verification function can also modify the 
  variables.

I've also written a proof of concept extension at 
svn://svn.xdebug.org/svn/php/typed and 
http://svn.xdebug.org/cgi-bin/viewvc.cgi/typed/?root=php that implements 
both the current strict-type verification, and a form of the "option 1" 
from 
http://wiki.php.net/rfc/typecheckingstrictandweak#option_1_current_type_juggeling_rules_with_e_strict_on_data_loss
 
(I've not done the E_STRICT warnings for all, as the RFC didn't specifiy 
when data loss was considered to occur).

Here follows an example script:

        <?php
        function errorHandler( $errno, $string )
        {
                global $ok;
                $ok = $errno;
                return true;
        }

        set_error_handler( 'errorHandler' );

        $twelve = 12;
        settype( $twelve, 'float' );

        $values = array(
                true, false,
                0, 1, 12, $twelve, 12.23,
                'true', 'false',
                '0', '1', '12', '12abc', '12.0', '12.34', 'foo',
                array(1,2,3), array('345' => 12),
                NULL, ''
        );
        $funcs = array(
                'testString', 'testFloat', 'testInt', 'testNumeric', 
'testScalar', 'testBool', 'testArray',
        );

        function testString( string $a ) { }
        function testFloat( float $a ) { }
        function testInt( int $a ) { }
        function testBool( boolean $a ) { }
        function testArray( array $a ) { }
        function testNumeric( numeric $a ) { }
        function testScalar( scalar $a ) { }

        echo "string  float   int     numeric scalar  bool    array\n";
        foreach( $values as $value )
        {
                foreach( $funcs as $func )
                {
                        $ok = true;
                        $func($value);
                        echo $ok === true ? "pass    " : ( $ok === 0x1000 ? 
"fail    " : "warn    " );
                }
                echo ' ', str_replace( "\n", '', var_export( $value, true ) );
                echo "\n";
        }
        ?>

And the output (with the three different validation/verification methods:

No validation/verification:

        der...@kossu:/home/httpd/html/test/verify-arg$ php -dextension=typed.so 
-dtyped.mode=0 option2.php 
        string  float   int     numeric scalar  bool    array
        pass    pass    pass    pass    pass    pass    fail     true
        pass    pass    pass    pass    pass    pass    fail     false
        pass    pass    pass    pass    pass    pass    fail     0
        pass    pass    pass    pass    pass    pass    fail     1
        pass    pass    pass    pass    pass    pass    fail     12
        pass    pass    pass    pass    pass    pass    fail     12
        pass    pass    pass    pass    pass    pass    fail     12.23
        pass    pass    pass    pass    pass    pass    fail     'true'
        pass    pass    pass    pass    pass    pass    fail     'false'
        pass    pass    pass    pass    pass    pass    fail     '0'
        pass    pass    pass    pass    pass    pass    fail     '1'
        pass    pass    pass    pass    pass    pass    fail     '12'
        pass    pass    pass    pass    pass    pass    fail     '12abc'
        pass    pass    pass    pass    pass    pass    fail     '12.0'
        pass    pass    pass    pass    pass    pass    fail     '12.34'
        pass    pass    pass    pass    pass    pass    fail     'foo'
        pass    pass    pass    pass    pass    pass    pass     array (  0 => 
1,  1 => 2,  2 => 3,)
        pass    pass    pass    pass    pass    pass    pass     array (  345 
=> 12,)
        pass    pass    pass    pass    pass    pass    fail     NULL
        pass    pass    pass    pass    pass    pass    fail     ''

Script type-checks:

        der...@kossu:/home/httpd/html/test/verify-arg$ php -dextension=typed.so 
-dtyped.mode=1 option2.php 
        string  float   int     numeric scalar  bool    array
        fail    fail    fail    fail    pass    pass    fail     true
        fail    fail    fail    fail    pass    pass    fail     false
        fail    fail    pass    pass    pass    fail    fail     0
        fail    fail    pass    pass    pass    fail    fail     1
        fail    fail    pass    pass    pass    fail    fail     12
        fail    pass    fail    pass    pass    fail    fail     12
        fail    pass    fail    pass    pass    fail    fail     12.23
        pass    fail    fail    fail    pass    fail    fail     'true'
        pass    fail    fail    fail    pass    fail    fail     'false'
        pass    fail    fail    pass    pass    fail    fail     '0'
        pass    fail    fail    pass    pass    fail    fail     '1'
        pass    fail    fail    pass    pass    fail    fail     '12'
        pass    fail    fail    fail    pass    fail    fail     '12abc'
        pass    fail    fail    pass    pass    fail    fail     '12.0'
        pass    fail    fail    pass    pass    fail    fail     '12.34'
        pass    fail    fail    fail    pass    fail    fail     'foo'
        fail    fail    fail    fail    fail    fail    pass     array (  0 => 
1,  1 => 2,  2 => 3,)
        fail    fail    fail    fail    fail    fail    pass     array (  345 
=> 12,)
        fail    fail    fail    fail    fail    fail    fail     NULL
        pass    fail    fail    fail    pass    fail    fail     ''

"Option 1" type-casting:

        der...@kossu:/home/httpd/html/test/verify-arg$ php -dextension=typed.so 
-dtyped.mode=2 option2.php 
        string  float   int     numeric scalar  bool    array
        pass    pass    pass    fail    pass    pass    fail     true
        pass    pass    pass    fail    pass    pass    fail     false
        pass    pass    pass    pass    pass    pass    fail     0
        pass    pass    pass    pass    pass    pass    fail     1
        pass    pass    pass    pass    pass    pass    fail     12
        pass    pass    warn    pass    pass    pass    fail     12
        pass    pass    warn    pass    pass    pass    fail     12.23
        pass    fail    warn    fail    pass    pass    fail     'true'
        pass    fail    warn    fail    pass    pass    fail     'false'
        pass    pass    pass    pass    pass    pass    fail     '0'
        pass    pass    pass    pass    pass    pass    fail     '1'
        pass    pass    pass    pass    pass    pass    fail     '12'
        pass    fail    warn    fail    pass    pass    fail     '12abc'
        pass    pass    pass    pass    pass    pass    fail     '12.0'
        pass    pass    pass    pass    pass    pass    fail     '12.34'
        pass    fail    warn    fail    pass    pass    fail     'foo'
        fail    fail    fail    fail    fail    fail    pass     array (  0 => 
1,  1 => 2,  2 => 3,)
        fail    fail    fail    fail    fail    fail    pass     array (  345 
=> 12,)
        pass    pass    pass    fail    fail    pass    fail     NULL
        pass    fail    warn    fail    pass    pass    fail     ''

I'd hope to commit this patch in the next week or so, so that we can get
started with 5.4.

regards,
Derick

-- 
http://derickrethans.nl | http://xdebug.org
Like Xdebug? Consider a donation: http://xdebug.org/donate.php
twitter: @derickr and @xdebug
Index: Zend/zend.c
===================================================================
--- Zend/zend.c (revision 302885)
+++ Zend/zend.c (working copy)
@@ -60,6 +60,7 @@
 int (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, va_list 
ap);
 ZEND_API char *(*zend_getenv)(char *name, size_t name_len TSRMLS_DC);
 ZEND_API char *(*zend_resolve_path)(const char *filename, int filename_len 
TSRMLS_DC);
+ZEND_API int (*zend_verify_arg_type)(union _zend_function *zf, zend_uint 
arg_num, zval **arg, ulong fetch_type TSRMLS_DC);
 
 void (*zend_on_timeout)(int seconds TSRMLS_DC);
 
@@ -648,6 +649,7 @@
        zend_vspprintf = utility_functions->vspprintf_function;
        zend_getenv = utility_functions->getenv_function;
        zend_resolve_path = utility_functions->resolve_path_function;
+       zend_verify_arg_type = utility_functions->verify_arg_type_function;
 
 #if HAVE_DTRACE
 /* build with dtrace support */
Index: Zend/zend.h
===================================================================
--- Zend/zend.h (revision 302885)
+++ Zend/zend.h (working copy)
@@ -536,6 +536,7 @@
        int (*vspprintf_function)(char **pbuf, size_t max_len, const char 
*format, va_list ap);
        char *(*getenv_function)(char *name, size_t name_len TSRMLS_DC);
        char *(*resolve_path_function)(const char *filename, int filename_len 
TSRMLS_DC);
+       int (*verify_arg_type_function)(union _zend_function *zf, zend_uint 
arg_num, zval **arg, ulong fetch_type TSRMLS_DC);
 } zend_utility_functions;
 
 typedef struct _zend_utility_values {
@@ -683,6 +684,7 @@
 extern int (*zend_vspprintf)(char **pbuf, size_t max_len, const char *format, 
va_list ap);
 extern ZEND_API char *(*zend_getenv)(char *name, size_t name_len TSRMLS_DC);
 extern ZEND_API char *(*zend_resolve_path)(const char *filename, int 
filename_len TSRMLS_DC);
+extern ZEND_API int (*zend_verify_arg_type)(union _zend_function *zf, 
zend_uint arg_num, zval **arg, ulong fetch_type TSRMLS_DC);
 
 ZEND_API void zend_error(int type, const char *format, ...) 
ZEND_ATTRIBUTE_FORMAT(printf, 2, 3);
 
Index: Zend/zend_execute.c
===================================================================
--- Zend/zend_execute.c (revision 302885)
+++ Zend/zend_execute.c (working copy)
@@ -577,7 +577,7 @@
        }
 }
 
-static inline char * zend_verify_arg_class_kind(const zend_arg_info 
*cur_arg_info, ulong fetch_type, const char **class_name, zend_class_entry 
**pce TSRMLS_DC)
+ZEND_API char * zend_verify_arg_class_kind(const zend_arg_info *cur_arg_info, 
ulong fetch_type, const char **class_name, zend_class_entry **pce TSRMLS_DC)
 {
        *pce = zend_fetch_class(cur_arg_info->class_name, 
cur_arg_info->class_name_len, (fetch_type | ZEND_FETCH_CLASS_AUTO | 
ZEND_FETCH_CLASS_NO_AUTOLOAD) TSRMLS_CC);
 
@@ -589,7 +589,7 @@
        }
 }
 
-static inline int zend_verify_arg_error(const zend_function *zf, zend_uint 
arg_num, const char *need_msg, const char *need_kind, const char *given_msg, 
char *given_kind TSRMLS_DC)
+ZEND_API int zend_verify_arg_error(int error_type, const zend_function *zf, 
zend_uint arg_num, const char *need_msg, const char *need_kind, const char 
*given_msg, char *given_kind TSRMLS_DC)
 {
        zend_execute_data *ptr = EG(current_execute_data)->prev_execute_data;
        char *fname = zf->common.function_name;
@@ -605,14 +605,14 @@
        }
 
        if (ptr && ptr->op_array) {
-               zend_error(E_RECOVERABLE_ERROR, "Argument %d passed to %s%s%s() 
must %s%s, %s%s given, called in %s on line %d and defined", arg_num, fclass, 
fsep, fname, need_msg, need_kind, given_msg, given_kind, 
ptr->op_array->filename, ptr->opline->lineno);
+               zend_error(error_type, "Argument %d passed to %s%s%s() must 
%s%s, %s%s given, called in %s on line %d and defined", arg_num, fclass, fsep, 
fname, need_msg, need_kind, given_msg, given_kind, ptr->op_array->filename, 
ptr->opline->lineno);
        } else {
-               zend_error(E_RECOVERABLE_ERROR, "Argument %d passed to %s%s%s() 
must %s%s, %s%s given", arg_num, fclass, fsep, fname, need_msg, need_kind, 
given_msg, given_kind);
+               zend_error(error_type, "Argument %d passed to %s%s%s() must 
%s%s, %s%s given", arg_num, fclass, fsep, fname, need_msg, need_kind, 
given_msg, given_kind);
        }
        return 0;
 }
 
-static inline int zend_verify_arg_type(zend_function *zf, zend_uint arg_num, 
zval *arg, ulong fetch_type TSRMLS_DC)
+ZEND_API int zend_original_verify_arg_type(zend_function *zf, zend_uint 
arg_num, zval **arg, ulong fetch_type TSRMLS_DC)
 {
        zend_arg_info *cur_arg_info;
        char *need_msg;
@@ -628,46 +628,27 @@
        if (cur_arg_info->class_name) {
                const char *class_name;
 
-               if (!arg) {
+               if (!arg || !*arg) {
                        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, "none", "" TSRMLS_CC);
+                       return zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, 
arg_num, need_msg, class_name, "none", "" TSRMLS_CC);
                }
-               if (Z_TYPE_P(arg) == IS_OBJECT) {
+               if (Z_TYPE_PP(arg) == IS_OBJECT) {
                        need_msg = zend_verify_arg_class_kind(cur_arg_info, 
fetch_type, &class_name, &ce TSRMLS_CC);
-                       if (!ce || !instanceof_function(Z_OBJCE_P(arg), ce 
TSRMLS_CC)) {
-                               return zend_verify_arg_error(zf, arg_num, 
need_msg, class_name, "instance of ", Z_OBJCE_P(arg)->name TSRMLS_CC);
+                       if (!ce || !instanceof_function(Z_OBJCE_PP(arg), ce 
TSRMLS_CC)) {
+                               return 
zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, need_msg, class_name, 
"instance of ", Z_OBJCE_PP(arg)->name TSRMLS_CC);
                        }
-               } else if (Z_TYPE_P(arg) != IS_NULL || 
!cur_arg_info->allow_null) {
+               } else if (Z_TYPE_PP(arg) != IS_NULL || 
!cur_arg_info->allow_null) {
                        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);
+                       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) {
-               if (!arg) {
-                       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);
+       } else if (cur_arg_info->type_hint && cur_arg_info->type_hint == 
IS_ARRAY) {
+               if (!arg || !*arg) {
+                       return zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, 
arg_num, "be of the type array", "", "none", "" TSRMLS_CC);
                }
 
-               /* existing type already matches the hint or forced type */
-               if (Z_TYPE_P(arg) == cur_arg_info->type_hint) {
-                       return 1;
+               if (Z_TYPE_PP(arg) != IS_ARRAY && (Z_TYPE_PP(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);
                }
-
-               /* NULL type given, check if parameter is optional */
-               if (Z_TYPE_P(arg) == IS_NULL && cur_arg_info->allow_null) {
-                       return 1;
-               }
-
-               if (cur_arg_info->type_hint == IS_SCALAR && Z_TYPE_P(arg) != 
IS_NULL && Z_TYPE_P(arg) != IS_ARRAY && Z_TYPE_P(arg) != IS_OBJECT && 
Z_TYPE_P(arg) != IS_RESOURCE) {
-                       return 1;
-               }
-
-               if (cur_arg_info->type_hint == IS_NUMERIC && (
-                               (Z_TYPE_P(arg) == IS_LONG || Z_TYPE_P(arg) == 
IS_DOUBLE)
-                               || (Z_TYPE_P(arg) == IS_STRING && 
is_numeric_string(Z_STRVAL_P(arg), Z_STRLEN_P(arg), NULL, NULL, 0))
-               )) {
-                       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;
 }
Index: Zend/zend_execute.h
===================================================================
--- Zend/zend_execute.h (revision 302885)
+++ Zend/zend_execute.h (working copy)
@@ -389,7 +389,11 @@
 ZEND_API zend_class_entry *zend_fetch_class(const char *class_name, uint 
class_name_len, int fetch_type TSRMLS_DC);
 ZEND_API zend_class_entry *zend_fetch_class_by_name(const char *class_name, 
uint class_name_len, const zend_literal *key, int fetch_type TSRMLS_DC);
 void zend_verify_abstract_class(zend_class_entry *ce TSRMLS_DC);
+ZEND_API int zend_verify_arg_error(int error_type, const zend_function *zf, 
zend_uint arg_num, const char *need_msg, const char *need_kind, const char 
*given_msg, char *given_kind TSRMLS_DC);
+ZEND_API int zend_original_verify_arg_type(zend_function *zf, zend_uint 
arg_num, zval **arg, ulong fetch_type TSRMLS_DC);
+ZEND_API char *zend_verify_arg_class_kind(const zend_arg_info *cur_arg_info, 
ulong fetch_type, const char **class_name, zend_class_entry **pce TSRMLS_DC);
 
+
 #ifdef ZEND_WIN32
 void zend_init_timeout_thread(void);
 void zend_shutdown_timeout_thread(void);
Index: Zend/tests/hint/param_type_hint_021.phpt
===================================================================
--- Zend/tests/hint/param_type_hint_021.phpt    (revision 302885)
+++ Zend/tests/hint/param_type_hint_021.phpt    (working copy)
@@ -1,46 +0,0 @@
---TEST--
-Parameter type hint - numeric type hints
---FILE--
-<?php
-
-function x($error, $msg) { var_dump($msg); }
-set_error_handler('x', E_RECOVERABLE_ERROR);
-
-function foo(numeric $param) { var_dump($param); }
-
-foo(1);
-foo(true);
-foo(NULL);
-foo(array(1));
-foo("foo");
-foo("123.33");
-foo("123");
-foo("");
-foo(111.222);
-foo(new Stdclass);
-foo(tmpfile());
-
-?>
---EXPECTF--
-int(1)
-string(%d) "Argument 1 passed to foo() must be of the type numeric, boolean 
given, called in %s on line %d and defined"
-bool(true)
-string(%d) "Argument 1 passed to foo() must be of the type numeric, null 
given, called in %s on line %d and defined"
-NULL
-string(%d) "Argument 1 passed to foo() must be of the type numeric, array 
given, called in %s on line %d and defined"
-array(1) {
-  [0]=>
-  int(1)
-}
-string(%d) "Argument 1 passed to foo() must be of the type numeric, string 
given, called in %s on line %d and defined"
-string(3) "foo"
-string(6) "123.33"
-string(3) "123"
-string(%d) "Argument 1 passed to foo() must be of the type numeric, string 
given, called in %s on line %d and defined"
-string(0) ""
-float(111.222)
-string(%d) "Argument 1 passed to foo() must be of the type numeric, object 
given, called in %s on line %d and defined"
-object(stdClass)#1 (0) {
-}
-string(%d) "Argument 1 passed to foo() must be of the type numeric, resource 
given, called in %s on line %d and defined"
-resource(4) of type (stream)
Index: Zend/tests/hint/param_type_hint_003.phpt
===================================================================
--- Zend/tests/hint/param_type_hint_003.phpt    (revision 302885)
+++ Zend/tests/hint/param_type_hint_003.phpt    (working copy)
@@ -1,16 +0,0 @@
---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
Index: Zend/tests/hint/param_type_hint_012.phpt
===================================================================
--- Zend/tests/hint/param_type_hint_012.phpt    (revision 302885)
+++ Zend/tests/hint/param_type_hint_012.phpt    (working copy)
@@ -1,18 +0,0 @@
---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
Index: Zend/tests/hint/param_type_hint_004.phpt
===================================================================
--- Zend/tests/hint/param_type_hint_004.phpt    (revision 302885)
+++ Zend/tests/hint/param_type_hint_004.phpt    (working copy)
@@ -1,16 +0,0 @@
---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
Index: Zend/tests/hint/param_type_hint_013.phpt
===================================================================
--- Zend/tests/hint/param_type_hint_013.phpt    (revision 302885)
+++ Zend/tests/hint/param_type_hint_013.phpt    (working copy)
@@ -1,16 +0,0 @@
---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
Index: Zend/tests/hint/param_type_hint_005.phpt
===================================================================
--- Zend/tests/hint/param_type_hint_005.phpt    (revision 302885)
+++ Zend/tests/hint/param_type_hint_005.phpt    (working copy)
@@ -1,23 +0,0 @@
---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
Index: Zend/tests/hint/param_type_hint_014.phpt
===================================================================
--- Zend/tests/hint/param_type_hint_014.phpt    (revision 302885)
+++ Zend/tests/hint/param_type_hint_014.phpt    (working copy)
@@ -1,16 +0,0 @@
---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
Index: Zend/tests/hint/param_type_hint_015.phpt
===================================================================
--- Zend/tests/hint/param_type_hint_015.phpt    (revision 302885)
+++ Zend/tests/hint/param_type_hint_015.phpt    (working copy)
@@ -1,19 +0,0 @@
---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
Index: Zend/tests/hint/param_type_hint_019.phpt
===================================================================
--- Zend/tests/hint/param_type_hint_019.phpt    (revision 302885)
+++ Zend/tests/hint/param_type_hint_019.phpt    (working copy)
@@ -1,37 +0,0 @@
---TEST--
-Parameter type hint - scalar type hints
---FILE--
-<?php
-
-function x($error, $msg) { var_dump($msg); }
-set_error_handler('x', E_RECOVERABLE_ERROR);
-
-function foo(scalar $param) { var_dump($param); }
-
-foo(1);
-foo(true);
-foo(NULL);
-foo(array(1));
-foo("foo");
-foo(111.222);
-foo(new Stdclass);
-foo(tmpfile());
-
-?>
---EXPECTF--
-int(1)
-bool(true)
-string(%d) "Argument 1 passed to foo() must be of the type scalar, null given, 
called in %s on line %d and defined"
-NULL
-string(%d) "Argument 1 passed to foo() must be of the type scalar, array 
given, called in %s on line %d and defined"
-array(1) {
-  [0]=>
-  int(1)
-}
-string(3) "foo"
-float(111.222)
-string(%d) "Argument 1 passed to foo() must be of the type scalar, object 
given, called in %s on line %d and defined"
-object(stdClass)#1 (0) {
-}
-string(%d) "Argument 1 passed to foo() must be of the type scalar, resource 
given, called in %s on line %d and defined"
-resource(4) of type (stream)
Index: Zend/tests/hint/param_type_hint_001.phpt
===================================================================
--- Zend/tests/hint/param_type_hint_001.phpt    (revision 302885)
+++ Zend/tests/hint/param_type_hint_001.phpt    (working copy)
@@ -1,38 +0,0 @@
---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
Index: Zend/tests/hint/param_type_hint_011.phpt
===================================================================
--- Zend/tests/hint/param_type_hint_011.phpt    (revision 302885)
+++ Zend/tests/hint/param_type_hint_011.phpt    (working copy)
@@ -1,15 +0,0 @@
---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
Index: Zend/zend_vm_def.h
===================================================================
--- Zend/zend_vm_def.h  (revision 302885)
+++ Zend/zend_vm_def.h  (working copy)
@@ -2586,7 +2586,7 @@
                        ulong arg_count = opline->extended_value;
 
                        while (arg_count>0) {
-                               zend_verify_arg_type(fbc, ++i, *(p-arg_count), 
0 TSRMLS_CC);
+                               zend_verify_arg_type(fbc, ++i, p-arg_count, 0 
TSRMLS_CC);
                                arg_count--;
                        }
                }
@@ -3111,7 +3111,7 @@
        } else {
                zval **var_ptr;
 
-               zend_verify_arg_type((zend_function *) EG(active_op_array), 
arg_num, *param, opline->extended_value TSRMLS_CC);
+               zend_verify_arg_type((zend_function *) EG(active_op_array), 
arg_num, param, opline->extended_value TSRMLS_CC);
                var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), 
opline->result.var TSRMLS_CC);
                Z_DELREF_PP(var_ptr);
                *var_ptr = *param;
@@ -3147,7 +3147,7 @@
                Z_ADDREF_P(assignment_value);
        }
 
-       zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, 
assignment_value, opline->extended_value TSRMLS_CC);
+       zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, 
&assignment_value, opline->extended_value TSRMLS_CC);
        var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->result.var 
TSRMLS_CC);
        Z_DELREF_PP(var_ptr);
        *var_ptr = assignment_value;
Index: Zend/zend_vm_execute.h
===================================================================
--- Zend/zend_vm_execute.h      (revision 302885)
+++ Zend/zend_vm_execute.h      (working copy)
@@ -628,7 +628,7 @@
                        ulong arg_count = opline->extended_value;
 
                        while (arg_count>0) {
-                               zend_verify_arg_type(fbc, ++i, *(p-arg_count), 
0 TSRMLS_CC);
+                               zend_verify_arg_type(fbc, ++i, p-arg_count, 0 
TSRMLS_CC);
                                arg_count--;
                        }
                }
@@ -778,7 +778,7 @@
        } else {
                zval **var_ptr;
 
-               zend_verify_arg_type((zend_function *) EG(active_op_array), 
arg_num, *param, opline->extended_value TSRMLS_CC);
+               zend_verify_arg_type((zend_function *) EG(active_op_array), 
arg_num, param, opline->extended_value TSRMLS_CC);
                var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), 
opline->result.var TSRMLS_CC);
                Z_DELREF_PP(var_ptr);
                *var_ptr = *param;
@@ -1294,7 +1294,7 @@
                Z_ADDREF_P(assignment_value);
        }
 
-       zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, 
assignment_value, opline->extended_value TSRMLS_CC);
+       zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, 
&assignment_value, opline->extended_value TSRMLS_CC);
        var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(EX_CVs(), opline->result.var 
TSRMLS_CC);
        Z_DELREF_PP(var_ptr);
        *var_ptr = assignment_value;
Index: main/main.c
===================================================================
--- main/main.c (revision 302885)
+++ main/main.c (working copy)
@@ -1885,6 +1885,7 @@
        zuf.vspprintf_function = vspprintf;
        zuf.getenv_function = sapi_getenv;
        zuf.resolve_path_function = php_resolve_path_for_zend;
+       zuf.verify_arg_type_function = zend_original_verify_arg_type;
        zend_startup(&zuf, NULL TSRMLS_CC);
 
 #ifdef ZTS
-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to