PHP namespace ::Foo::test ?????

2015-01-15 16:15:40 +08:00
 lvfujun
<?php
namespace Foobar;

class Foo {
static public function test($name) {
print '[['. $name .']]';
}
}

spl_autoload_register(__NAMESPACE__ .'::Foo::test'); // As of PHP 5.3.0

new InexistentClass;
?>

请问一下大家spl_autoload_register(__NAMESPACE__ .'::Foo::test'); // As of PHP 5.3.0
里面的::Foo::test是什么写法? ::Foo代表的什么?调用类为什么要加"::"呢?调用方法test为什么不用加()呢?
3281 次点击
所在节点    PHP
27 条回复
tuuuz
2015-01-15 16:35:00 +08:00
不知道
wesley
2015-01-15 16:38:35 +08:00
我怎么感觉这个写法不太对,不应该是像下面这样码?
Foobar\Foo::test
cevincheung
2015-01-15 16:40:38 +08:00
第1个我也不知道怎么回答,我一直是Foobar\Foo::test
::Foo 调用namespace Foobar下的Foo类
因为这个类是个静态类所以 ::Foo,调用静态方法 Class::method()
不加()是因为spl_autoload_register是注册一个autoload回调。要求回调函数只有一个参数。所以不用加(),系统调用会知道那是个函数而且会带参数。

像js
function abc() {}
setTimeout(abc,100)
一样的
feiyuanqiu
2015-01-15 16:44:13 +08:00
:: 在php里表示调用静态方法、变量、类常量等,如:

static $test;
const TEST_CONST = 1;
static function testFunc() {}

self::$test = '2'; // 调用静态类变量
if (self::TEST_CONST == $test) {} // 调用类常量
self::testFunc();



PHP里把一个函数作为参数是这样的:
1、call_user_func('test'); // 如果是函数,直接传函数名
2-0、array_map(array(__CLASS__, 'test'), $array); // 静态方法传类名及方法名
2-1、array_map(__CLASS__ . '::test', $array); // 或者只传一个字符串
3、array_filter($array, array($this, 'test')); // 非静态方法需要传一个类实例及方法名
4、register_shutdown_function(function () { echo 'no!'; }); // PHP 5.3.0开始支持匿名函数

这就是为什么 test 不加 () 的原因。
imn1
2015-01-15 16:46:29 +08:00
:: 是静态类
这个只是注册,不是调用或实例化,不需要括号
feiyuanqiu
2015-01-15 16:49:46 +08:00
然后对于这一句:
spl_autoload_register(__NAMESPACE__ .'::Foo::test'); // As of PHP 5.3.0

请看手册下面的运行结果:

以上例程的输出类似于:

[[Foobar::InexistentClass]]
Fatal error: Class 'Foobar::InexistentClass' not found in ...
lvfujun
2015-01-15 16:56:04 +08:00
@cevincheung Thanks
lvfujun
2015-01-15 17:00:00 +08:00
@imn1
@feiyuanqiu
Thanks!
lvfujun
2015-01-15 17:00:17 +08:00
@wesley
@tuuuz
好吧、、
lvfujun
2015-01-15 17:00:36 +08:00
感谢大家我已经明白了.
Sunyanzi
2015-01-15 17:23:42 +08:00
我整个人都惊呆了 ... 楼上的诸位居然能说得风生水起 ... 而且楼主居然还明白了 ...

首先我必须要说 ... 楼主你哪里看到的这个例子 ... 赶紧把那本书扔了 ... 再不扔耽误事 ...

在 php 5.3 的初期 ... php 6 在蠢蠢欲动的时候 ... php 的 namespace 标记是 :: ...

几个测试版之后 ... php 官方的人才意识到 ... 卧槽 ... 如果用 :: 岂不是分不清命名空间和类了 ...

于是忙不迭的发了个投票问到底 namespace 标记用什么比较好 ... 最后决定了 \ ...

楼主你顶楼的那个代码 ... 就是在 namespace 的雏形期写的 ... 很明显现在已经是废代码了 ...

现在的版本应该写做 spl_autoload_register(__NAMESPACE__ .'\\Foo::test'); // As of PHP 5.3.0 ...

至于 spl_autoload_register 我不想多说 ... 手册里说的很详细 ...

这个函数的第一个参数是一个 callable ... 它只是定义了函数的名字 ... 而不是在这里就调用函数 ...
haiyang416
2015-01-15 17:32:00 +08:00
哈哈哈,这代码根本就是错的好吗
lvfujun
2015-01-15 18:25:56 +08:00
@Sunyanzi 感谢大牛教诲.
lvfujun
2015-01-15 18:26:10 +08:00
@haiyang416 php官方的例子
lvfujun
2015-01-15 18:26:47 +08:00
@Sunyanzi php官方的例子
lvfujun
2015-01-15 18:26:59 +08:00
@haiyang416 应该是没错的.
shiny
2015-01-15 18:32:45 +08:00
@lvfujun 因为你看的是中文版的 spl_autoload_register,如果是英文版,已经换成
spl_autoload_register(__NAMESPACE__ .'\Foo::test');

如果有人对翻译 PHP 中文手册有兴趣,但是不知道怎么贡献的,欢迎联系我~
haiyang416
2015-01-15 18:34:23 +08:00
@lvfujun http://php.net/manual/pl/function.spl-autoload-register.php
我建议你以后不要看中文版的手册,满地坑。以前也提交过好多文档翻译,中文版惨不忍睹。
Sunyanzi
2015-01-15 18:38:14 +08:00
@lvfujun 给跪 ... 不要看官方的中文手册是常识啊 ...
haiyang416
2015-01-15 18:42:27 +08:00
回头想了一下,觉得一味的不推荐中文文档做法欠妥,还是辩证的看吧,有错误的地方应该去提交修订。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/162432

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX