php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Return to Bug #53399
Patch strict-required-opt2.patch revision 2010-11-25 01:27 UTC by jbafford at zort dot net
Patch strict-required-opt.patch revision 2010-11-24 15:27 UTC by jbafford at zort dot net

Patch strict-required-opt2.patch for Scripting Engine problem Bug #53399

Patch version 2010-11-25 01:27 UTC

Return to Bug #53399 | Download this patch
This patch renders other patches obsolete

Obsolete patches:

Patch Revisions:

Developer: jbafford@zort.net

Index: Zend/zend_compile.c
===================================================================
--- Zend/zend_compile.c	(revision 305734)
+++ Zend/zend_compile.c	(working copy)
@@ -1439,6 +1439,8 @@
 {
 	char lcname[16];
 	int name_len;
+	int num_args, x, has_optional;
+	zend_arg_info *arg_info;
 
 	zend_do_extended_info(TSRMLS_C);
 	zend_do_return(NULL, 0 TSRMLS_CC);
@@ -1459,6 +1461,26 @@
 		}		
 	}
 
+	num_args = CG(active_op_array)->num_args;
+	has_optional = 0;
+	for (x = 0; x < num_args; x++) {
+		arg_info = &CG(active_op_array)->arg_info[x];
+		
+		//This argument is considered required if it is !optional, OR there is a classname AND it is !allow_null
+		//We throw the warning if: a previous argument is optional and the current one isn't
+		int is_optional = (arg_info->optional && (arg_info->class_name && arg_info->allow_null));
+		if (!is_optional) {
+			if (has_optional) {
+				zend_error(E_STRICT, "Declaration of required function parameter '%s' after optional parameter in %s", arg_info->name, CG(active_op_array)->function_name);
+				break;
+			}
+			else {
+				int is_required = (!arg_info->optional || (arg_info->class_name && arg_info->allow_null));
+				has_optional = !is_required;
+			}
+		}
+	}
+
 	CG(active_op_array)->line_end = zend_get_compiled_lineno(TSRMLS_C);
 	CG(active_op_array) = function_token->u.op_array;
 
@@ -1516,6 +1538,7 @@
 	cur_arg_info->pass_by_reference = pass_by_reference;
 	cur_arg_info->class_name = NULL;
 	cur_arg_info->class_name_len = 0;
+	cur_arg_info->optional = (op == ZEND_RECV_INIT);
 
 	if (class_type->op_type != IS_UNUSED) {
 		cur_arg_info->allow_null = 0;
Index: Zend/zend_compile.h
===================================================================
--- Zend/zend_compile.h	(revision 305734)
+++ Zend/zend_compile.h	(working copy)
@@ -179,6 +179,7 @@
 	zend_bool allow_null;
 	zend_bool pass_by_reference;
 	zend_bool return_reference;
+	zend_bool optional;
 	int required_num_args;
 } zend_arg_info;
 
Index: Zend/tests/func_optarg_strict.phpt
===================================================================
--- Zend/tests/func_optarg_strict.phpt	(revision 0)
+++ Zend/tests/func_optarg_strict.phpt	(revision 0)
@@ -0,0 +1,26 @@
+--TEST--
+Declaration of required function parameter after optional parameter E_STRICT warning
+--CREDITS--
+John Bafford
+http://bafford.com
+--INI--
+error_reporting=E_STRICT
+--FILE--
+<?php
+//These should have no warnings
+function ClassNull(StdClass $a = null, StdClass $b, $c) {}
+function FinalOptionalClass($a, StdClass $b = null) {}
+function AllOptional($a = 0, StdClass $b = null) {}
+function AllRequired($a, $b, $c) {}
+function AllRequiredClass($a, StdClass $b, $c) {}
+
+//These should generate a warning
+function FirstOptional($a = null, $b, $c) {}
+function FirstOptional2($a = null, StdClass $b, $c) {}
+function FirstOptional3($a = null, StdClass $b = null, $c) {}
+--EXPECTF--
+Strict Standards: Declaration of required function parameter 'b' after optional parameter in FirstOptional in %s on line %d
+
+Strict Standards: Declaration of required function parameter 'b' after optional parameter in FirstOptional2 in %s on line %d
+
+Strict Standards: Declaration of required function parameter 'c' after optional parameter in FirstOptional3 in %s on line %d
Index: Zend/tests/call_user_func_005.phpt
===================================================================
--- Zend/tests/call_user_func_005.phpt	(revision 305734)
+++ Zend/tests/call_user_func_005.phpt	(working copy)
@@ -10,7 +10,7 @@
 	}
 	
 	public function teste() {
-		return foo::x(function &($a=1,$b) { });
+		return foo::x(function &($a,$b) { });
 	}
 }
 
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Nov 22 03:01:27 2024 UTC