Hi all, This patch is also available at http://pear.php.net/~greg/namespace.patch.txt
The patch adds the syntax "namespace { *stuff }" and allows multiple namespaces per file with no performance penalty or added complexity as only 4 lines of code need to be changed, and 9 lines of code added to implement this support! Basically, there is one use case of multiple namespaces per file that the patch is designed to support, which is the ability to cram many files into a single file. I have done this for purposes of distributing things (prior to phar), it is used by some with phing tasks for performance reasons, and can have other uses as well. The patch provides the ability to do this, for example: <?php namespace One { require_once 'blah.php'; class MyClass extends blah { function test() { echo "OK\n"; } } function test() { echo "OK\n"; } } namespace Two { class MyClass { function test() { echo "OK\n"; } } function test() { echo "OK\n"; } } ?> Note that the old format "namespace OneRingToRuleThemAll;" is still fully supported, and should be the recommended format, as build tools can easily take an entire file, change namespace .*; into namespace .*{ and append <?php } ?> to the end of the file. The attached patch is against php6, but as you can see, a blind monkey could port it to PHP_5_3 when the time comes. All of the introduced changes are now tested, including the error message for nested namespace declarations, and the error message for multiple namespace declarations with ; (which was previously untested by .phpt tests) Thanks, Greg
? halt_compiler_php6.patch.txt ? namespace.patch.txt Index: Zend/zend_compile.c =================================================================== RCS file: /repository/ZendEngine2/zend_compile.c,v retrieving revision 1.762 diff -u -r1.762 zend_compile.c --- Zend/zend_compile.c 20 Aug 2007 09:48:41 -0000 1.762 +++ Zend/zend_compile.c 20 Aug 2007 19:46:52 -0000 @@ -4966,16 +4966,16 @@ } /* }}} */ -void zend_do_namespace(znode *name TSRMLS_DC) /* {{{ */ +void zend_do_namespace(znode *name, int brackets TSRMLS_DC) /* {{{ */ { unsigned int lcname_len; zstr lcname; - if (CG(active_op_array)->last > 0) { + if (!brackets && CG(active_op_array)->last > 0) { zend_error(E_COMPILE_ERROR, "Namespace declaration statement has to be the very first statement in the script"); } if (CG(current_namespace)) { - zend_error(E_COMPILE_ERROR, "Namespace cannot be declared twice"); + zend_error(E_COMPILE_ERROR, "Namespace cannot be declared twice (without brackets) or nested within brackets"); } lcname = zend_u_str_case_fold(Z_TYPE(name->u.constant), Z_UNIVAL(name->u.constant), Z_UNILEN(name->u.constant), 0, &lcname_len); if (((lcname_len == sizeof("self")-1) && @@ -4991,6 +4991,16 @@ } /* }}} */ +void zend_do_end_namespace(TSRMLS_D) /* {{{ */ +{ + if (CG(current_namespace)) { + zval_dtor(CG(current_namespace)); + efree(CG(current_namespace)); + CG(current_namespace) = NULL; + } +} +/* }}} */ + void zend_do_import(znode *ns_name, znode *new_name TSRMLS_DC) /* {{{ */ { unsigned int lcname_len; Index: Zend/zend_compile.h =================================================================== RCS file: /repository/ZendEngine2/zend_compile.h,v retrieving revision 1.363 diff -u -r1.363 zend_compile.h --- Zend/zend_compile.h 20 Aug 2007 09:48:41 -0000 1.363 +++ Zend/zend_compile.h 20 Aug 2007 19:46:53 -0000 @@ -520,7 +520,8 @@ void zend_do_abstract_method(znode *function_name, znode *modifiers, znode *body TSRMLS_DC); void zend_do_build_namespace_name(znode *result, znode *prefix, znode *name TSRMLS_DC); -void zend_do_namespace(znode *name TSRMLS_DC); +void zend_do_namespace(znode *name, int brackets TSRMLS_DC); +void zend_do_end_namespace(TSRMLS_D); void zend_do_import(znode *name, znode *new_name TSRMLS_DC); void zend_do_end_compilation(TSRMLS_D); Index: Zend/zend_language_parser.y =================================================================== RCS file: /repository/ZendEngine2/zend_language_parser.y,v retrieving revision 1.188 diff -u -r1.188 zend_language_parser.y --- Zend/zend_language_parser.y 20 Aug 2007 09:48:41 -0000 1.188 +++ Zend/zend_language_parser.y 20 Aug 2007 19:46:54 -0000 @@ -171,12 +171,12 @@ | function_declaration_statement { zend_do_early_binding(TSRMLS_C); } | class_declaration_statement { zend_do_early_binding(TSRMLS_C); } | T_HALT_COMPILER '(' ')' ';' { zend_do_halt_compiler_register(TSRMLS_C); YYACCEPT; } - | T_NAMESPACE namespace_name ';' { zend_do_namespace(&$2 TSRMLS_CC); } + | T_NAMESPACE namespace_name ';' { zend_do_namespace(&$2, 0 TSRMLS_CC); } + | T_NAMESPACE namespace_name '{' { zend_do_namespace(&$2, 1 TSRMLS_CC); } top_statement_list '}' { zend_do_end_namespace(TSRMLS_C); } | T_IMPORT namespace_name ';' { zend_do_import(&$2, NULL TSRMLS_CC); } | T_IMPORT namespace_name T_AS T_STRING ';' { zend_do_import(&$2, &$4 TSRMLS_CC); } ; - inner_statement_list: inner_statement_list { zend_do_extended_info(TSRMLS_C); } inner_statement { HANDLE_INTERACTIVE(); } | /* empty */ Index: Zend/tests/ns_039.phpt =================================================================== RCS file: Zend/tests/ns_039.phpt diff -N Zend/tests/ns_039.phpt --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ Zend/tests/ns_039.phpt 20 Aug 2007 19:46:54 -0000 @@ -0,0 +1,14 @@ +--TEST-- +039: double namespace declaration +--FILE-- +<?php +namespace Exception; +namespace Oops; +function foo() { + echo "ok\n"; +} +Exception::foo(); +Exception::bar(); +--EXPECTF-- +Fatal error: Namespace cannot be declared twice (without brackets) or nested within brackets in %sns_039.php on line 3 + Index: Zend/tests/ns_040.phpt =================================================================== RCS file: Zend/tests/ns_040.phpt diff -N Zend/tests/ns_040.phpt --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ Zend/tests/ns_040.phpt 20 Aug 2007 19:46:54 -0000 @@ -0,0 +1,14 @@ +--TEST-- +040: namespace not first declaration +--FILE-- +<?php +$a = oops; +namespace Exception; +function foo() { + echo "ok\n"; +} +Exception::foo(); +Exception::bar(); +--EXPECTF-- +Fatal error: Namespace declaration statement has to be the very first statement in the script in %sns_040.php on line 3 + Index: Zend/tests/ns_041.phpt =================================================================== RCS file: Zend/tests/ns_041.phpt diff -N Zend/tests/ns_041.phpt --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ Zend/tests/ns_041.phpt 20 Aug 2007 19:46:54 -0000 @@ -0,0 +1,13 @@ +--TEST-- +041: namespace with brackets, function declaration +--FILE-- +<?php +namespace Exception { +function foo() { + echo "ok\n"; +} +} +Exception::foo(); +--EXPECTF-- +ok + Index: Zend/tests/ns_042.phpt =================================================================== RCS file: Zend/tests/ns_042.phpt diff -N Zend/tests/ns_042.phpt --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ Zend/tests/ns_042.phpt 20 Aug 2007 19:46:54 -0000 @@ -0,0 +1,15 @@ +--TEST-- +042: namespace with brackets, class declaration +--FILE-- +<?php +namespace Exception { +class test { +static function foo() { + echo "ok\n"; +} +} +} +Exception::test::foo(); +--EXPECTF-- +ok + Index: Zend/tests/ns_043.phpt =================================================================== RCS file: Zend/tests/ns_043.phpt diff -N Zend/tests/ns_043.phpt --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ Zend/tests/ns_043.phpt 20 Aug 2007 19:46:54 -0000 @@ -0,0 +1,20 @@ +--TEST-- +043: namespace with brackets, class declaration + function declaration +--FILE-- +<?php +namespace Exception { +class test { +static function foo() { + echo "ok\n"; +} +} +function foo() { + echo "ok\n"; +} +} +Exception::test::foo(); +Exception::foo(); +--EXPECTF-- +ok +ok + Index: Zend/tests/ns_044.phpt =================================================================== RCS file: Zend/tests/ns_044.phpt diff -N Zend/tests/ns_044.phpt --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ Zend/tests/ns_044.phpt 20 Aug 2007 19:46:54 -0000 @@ -0,0 +1,34 @@ +--TEST-- +044: namespace with brackets, two namespace declarations +--FILE-- +<?php +namespace Exception { +class test { +static function foo() { + echo "ok\n"; +} +} +function foo() { + echo "ok\n"; +} +} +Exception::test::foo(); +Exception::foo(); +namespace Second { +class test { +static function foo() { + echo "ok\n"; +} +} +function foo() { + echo "ok\n"; +} +} +Second::test::foo(); +Second::foo(); +--EXPECTF-- +ok +ok +ok +ok + Index: Zend/tests/ns_045.phpt =================================================================== RCS file: Zend/tests/ns_045.phpt diff -N Zend/tests/ns_045.phpt --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ Zend/tests/ns_045.phpt 20 Aug 2007 19:46:54 -0000 @@ -0,0 +1,31 @@ +--TEST-- +045: illegal nested namespace with brackets +--FILE-- +<?php +namespace Exception { +class test { +static function foo() { + echo "ok\n"; +} +} +function foo() { + echo "ok\n"; +} +test::foo(); +foo(); +namespace Second { +class test { +static function foo() { + echo "ok\n"; +} +} +function foo() { + echo "ok\n"; +} +} +} +Second::test::foo(); +Second::foo(); +--EXPECTF-- +Fatal error: Namespace cannot be declared twice (without brackets) or nested within brackets in %sns_045.php on line 13 +
-- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php