Hi,
I've decided to play a little with namespaces as some of you asked for feedback on this list or on your blogs. I'm just an userland developer and have no clue about PHP internals so forgive me if I say something stupid in this regard.
Here's what I found on some simple test. It may be the intended behaviour but confused me so I decided to ask on this list for clarifications.
I have two files:
- include.php
<?php
namespace Test;
class Bar
{
public static function baz()
{
return 'namespaced static method';
}
}
function foo() {
return 'namespaced function';
}
- index.php
<?php
require_once 'include.php';
use Test::Bar;
class Test
{
public static function foo()
{
return 'static method';
}
}
echo Test::foo(); // outputs namespace function
echo '<br>';
echo ::Test::foo(); // outputs namespace function
echo '<br>';
echo call_user_func(array('Test', 'foo')); // outputs static method
echo '<br>';
echo Bar::baz(); // outputs namespaced static method
echo '<br>';
echo call_user_func(array('Bar', 'baz')); // gives warning
I have executed them on a very recent snapshot of 5.3.0alpha3-dev on a Windows XP. The result is put on comments by the appropriate lines.
My questions are:
- How should I call the static method foo in the global class Test (except for call_user_func)
- How should I call the static method baz of class Bar in namespace Test with call_user_func
- Is there no possibility to change your minds and replace the double colon with something else, likes a simple colon? I find it very confusing to figure out what is what and the way I should call it.
Thank you in advance,
I. Stan
Hi!
- include.php <?php
namespace Test;
class Bar { public static function baz() { return 'namespaced static
method'; } }function foo() { return 'namespaced function'; }
- index.php <?php
require_once 'include.php'; use Test::Bar;
class Test { public static function foo() { return 'static method'; }
}
I would advise you to avoid calling your classes and namespaces by the
same name, for the sake of clarity - especially if you are going to have
identically named static functions in both. You can always have My::Test
instead, etc.
- How should I call the static method
baz of class Bar in namespace Test with call_user_func
call_user_func(array('Test::Bar', 'baz')). Remember, the true name is
always the full name.
- Is there no possibility to change your minds and replace the double colon with
something else, likes a simple colon?
With simple colon - not likely.
I find it very confusing to
figure out what is what and the way I should call it.
You should always use full name with call_*, reflection, variable class
names and other runtime constructs. You can use shortcuts with static
constructs - where you specify the class name explicitly.
Stanislav Malyshev, Zend Software Architect
stas@zend.com http://www.zend.com/
(408)253-8829 MSN: stas@zend.com
Stanislav Malyshev schreef:
Hi!
- include.php <?php
namespace Test;
class Bar { public static function baz() { return 'namespaced static
method'; } }function foo() { return 'namespaced function'; }
- index.php <?php
require_once 'include.php'; use Test::Bar;
class Test { public static function foo() { return 'static method'; }
}I would advise you to avoid calling your classes and namespaces by the
same name, for the sake of clarity - especially if you are going to have
identically named static functions in both. You can always have My::Test
instead, etc.
essentially good advice, but completely dismissive of the underlying issue.
- How should I call the static method
baz of class Bar in namespace Test with call_user_funccall_user_func(array('Test::Bar', 'baz')). Remember, the true name is
always the full name.
- Is there no possibility to change your minds and replace the double
colon with
something else, likes a simple colon?With simple colon - not likely.
what about a simple new concept then?
I find it very confusing to
figure out what is what and the way I should call it.You should always use full name with call_*, reflection, variable class
names and other runtime constructs. You can use shortcuts with static
constructs - where you specify the class name explicitly.
now that last point is darn good raw material for an upcoming namespaces
guideline, don't mind if I pinch it do you?
Ionut Gabriel Stan wrote:
<snip><snip>echo Test::foo(); // outputs namespace function
echo '<br>';
echo ::Test::foo(); // outputs namespace function
My questions are:
- How should I call the static method foo in the global class Test (except for call_user_func)
- How should I call the static method baz of class Bar in namespace Test with call_user_func
- Is there no possibility to change your minds and replace the double colon with something else, likes a simple colon? I find it very confusing to figure out what is what and the way I should call it.
Hi Ionut,
Stas did a good job of answering how to call the static method using
call_user_func. The answer to #1 under the current implementation is
"you can't" which is why I posted a patch to allow differentiating
between the two earlier this week.
However, I have since discovered a much better solution, and have a
working patch, but am checking details offlist before I propose it, as
it involves a slight but important change to namespace syntax. Stay
tuned for further details. As for your 3rd question, I guarantee this
will not happen, as it is technically impossible to do. For instance:
switch ($something) {
case oops:
is:this:part:of:oops();
break;
}
The above code could resolve to either "case oops:" followed by
"is:this:part:of:oops()" or as "case oops:is:this:part:of:oops()" and
there is no way for a computer to tell the difference without
introducing required whitespace. Since PHP != Python, that won't happen :).
Greg