V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
lvfujun
V2EX  ›  PHP

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

  •  
  •   lvfujun · 2015-01-15 16:15:40 +08:00 · 3261 次点击
    这是一个创建于 3603 天前的主题,其中的信息可能已经有所发展或是发生改变。
    <?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为什么不用加()呢?
    27 条回复    2015-01-16 10:01:57 +08:00
    tuuuz
        1
    tuuuz  
       2015-01-15 16:35:00 +08:00
    不知道
    wesley
        2
    wesley  
       2015-01-15 16:38:35 +08:00
    我怎么感觉这个写法不太对,不应该是像下面这样码?
    Foobar\Foo::test
    cevincheung
        3
    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
        4
    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
        5
    imn1  
       2015-01-15 16:46:29 +08:00
    :: 是静态类
    这个只是注册,不是调用或实例化,不需要括号
    feiyuanqiu
        6
    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
        7
    lvfujun  
    OP
       2015-01-15 16:56:04 +08:00
    @cevincheung Thanks
    lvfujun
        8
    lvfujun  
    OP
       2015-01-15 17:00:00 +08:00
    @imn1
    @feiyuanqiu
    Thanks!
    lvfujun
        9
    lvfujun  
    OP
       2015-01-15 17:00:17 +08:00
    @wesley
    @tuuuz
    好吧、、
    lvfujun
        10
    lvfujun  
    OP
       2015-01-15 17:00:36 +08:00
    感谢大家我已经明白了.
    Sunyanzi
        11
    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
        12
    haiyang416  
       2015-01-15 17:32:00 +08:00
    哈哈哈,这代码根本就是错的好吗
    lvfujun
        13
    lvfujun  
    OP
       2015-01-15 18:25:56 +08:00
    @Sunyanzi 感谢大牛教诲.
    lvfujun
        14
    lvfujun  
    OP
       2015-01-15 18:26:10 +08:00
    @haiyang416 php官方的例子
    lvfujun
        15
    lvfujun  
    OP
       2015-01-15 18:26:47 +08:00
    @Sunyanzi php官方的例子
    lvfujun
        16
    lvfujun  
    OP
       2015-01-15 18:26:59 +08:00
    @haiyang416 应该是没错的.
    shiny
        17
    shiny  
       2015-01-15 18:32:45 +08:00
    @lvfujun 因为你看的是中文版的 spl_autoload_register,如果是英文版,已经换成
    spl_autoload_register(__NAMESPACE__ .'\Foo::test');

    如果有人对翻译 PHP 中文手册有兴趣,但是不知道怎么贡献的,欢迎联系我~
    haiyang416
        18
    haiyang416  
       2015-01-15 18:34:23 +08:00
    @lvfujun http://php.net/manual/pl/function.spl-autoload-register.php
    我建议你以后不要看中文版的手册,满地坑。以前也提交过好多文档翻译,中文版惨不忍睹。
    Sunyanzi
        19
    Sunyanzi  
       2015-01-15 18:38:14 +08:00
    @lvfujun 给跪 ... 不要看官方的中文手册是常识啊 ...
    haiyang416
        20
    haiyang416  
       2015-01-15 18:42:27 +08:00
    回头想了一下,觉得一味的不推荐中文文档做法欠妥,还是辩证的看吧,有错误的地方应该去提交修订。
    shiny
        21
    shiny  
       2015-01-15 18:45:13 +08:00
    @haiyang416 因为文件 outdate 了,需要整个文件更新下,单独改这里也不合适。
    haiyang416
        22
    haiyang416  
       2015-01-15 18:51:52 +08:00
    @shiny 很多地方脱节很严重,我之前提交翻译的时候头都大了。因为不只是错误,各种中英文重复,各种代码示例块重复。最关键的问题还是你说的 outdate。
    shiny
        23
    shiny  
       2015-01-15 19:20:59 +08:00
    @haiyang416 刚才把楼主的问题给修复了。
    其实只要打上 EN-Revision ,对比更新也不是很困难。主要是人手太少。

    这方面比较佩服日本人在手册更新上的工作。
    haiyang416
        24
    haiyang416  
       2015-01-15 19:42:35 +08:00 via Android
    @shiny 看了下资料,你现在也是权限在手。从我个人的经历来说,参与文档翻译还是有门槛的,虽说每个人都可以参与,但是这方面的教程实在是太少了,特别是格式相关的。你们可以考虑写一篇详细的中文教程,引导人参与。我专门去翻了一下,之前文档组朋友给我的格式指南还弄丢了……
    shiny
        25
    shiny  
       2015-01-15 19:52:43 +08:00
    @haiyang416 嗯确实,也是一路踩坑过来的。
    我考虑开个简单的主页,放点资料和教程来引导。
    lvfujun
        26
    lvfujun  
    OP
       2015-01-16 10:01:24 +08:00
    @shiny
    @haiyang416
    @Sunyanzi
    感谢各位大牛的耐心指导.
    lvfujun
        27
    lvfujun  
    OP
       2015-01-16 10:01:57 +08:00
    下了个四月天的文档感觉还不错.
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   4504 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 10:08 · PVG 18:08 · LAX 02:08 · JFK 05:08
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.