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