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

一个 php 的“可变类名”疑问

  •  
  •   kmvan · 2015-01-05 12:28:51 +08:00 · 4218 次点击
    这是一个创建于 3606 天前的主题,其中的信息可能已经有所发展或是发生改变。
    <?php
    class_a::init();
    class class_a{
        public static $other_class_name = 'class_b';
        public static function init(){
            $other_class_name = self::$other_class_name; //一定要这样赋值才能 work 吗?
            $other_class_name::init(); //不能直接写 self::$other_class_name::init(),郁闷
           //有办法不用去赋值,直接写静态变量作为类名来调用 class_b 的方法吗?
        }
    }
    class class_b{
        public static function init(){
            echo 'i am class_b';
        }
    }
    class class_c{
        public static function init(){
            echo 'i am class_c';
        }
    }
    
    19 条回复    2015-01-05 22:44:52 +08:00
    haiyang416
        1
    haiyang416  
       2015-01-05 12:39:03 +08:00   ❤️ 1
    call_user_func(array(self::$other_class_name, 'init'));

    只想到这个,写两行有什么不好么?
    fising
        2
    fising  
       2015-01-05 12:46:32 +08:00   ❤️ 1
    self::$other_class_name::init()

    明显不对啊。

    self::$other_class_name 得到的是字符串 'class_b'

    你能对字符串调用静态方法init?
    hitsmaxft
        3
    hitsmaxft  
       2015-01-05 12:49:54 +08:00   ❤️ 1
    这些属于php语法分析的bug,用 call user func 绕开
    raincious
        4
    raincious  
       2015-01-05 12:51:51 +08:00   ❤️ 2
    PHP现在T_PAAMAYIM_NEKUDOTAYIM的解析有点“未完待续”。5.3的时候连$variable::method();的语法都无法解析。

    到5.6还是不能将::串联起来,必须在函数/方法体内本地化一个变量才可以。哪怕你制造一个静态方法:

    function static class getClass() { return static::$other_class_name; }

    然后 static::getClass()::init(); 都不行。

    所以目前只能用一楼的方法,只是效率比较低。
    kmvan
        5
    kmvan  
    OP
       2015-01-05 13:10:38 +08:00
    @raincious 所以目前只能用一楼的方法,只是效率比较低。
    其实还有一种写法,就是用 eval,不过效率恐怕比一楼的还要低。
    我还想问一下,$other_class_name::init(); 这种写法,应该不是叫可变变量吧,有专用的名词吗?可变变量是 $$name 这样子的。
    kmvan
        6
    kmvan  
    OP
       2015-01-05 13:11:34 +08:00
    @haiyang416 只想到这个,写两行有什么不好么?
    对于病患来说,写多半行都觉得整个人不好了。
    kmvan
        7
    kmvan  
    OP
       2015-01-05 13:14:35 +08:00
    @haiyang416 call_user_func(array(self::$other_class_name, 'init'));
    这个估计不行吧,因为他是静态方法,不会报错吗?
    haiyang416
        8
    haiyang416  
       2015-01-05 13:21:21 +08:00
    @kmvan 不要说你认为不行。你应该先上代码实验或者翻阅对应的手册。
    kmvan
        9
    kmvan  
    OP
       2015-01-05 13:40:07 +08:00
    @haiyang416 不要说你认为不行。你应该先上代码实验或者翻阅对应的手册。
    类型不标准,虽然不是error错误,但也报提示: Strict standards: call_user_func() expects parameter 1 to be a valid callback, non-static method class_b::init() should not be called statically
    picasso250
        10
    picasso250  
       2015-01-05 13:43:18 +08:00
    唯一的办法是给PHP提patch

    @raincious 手工感谢
    raincious
        11
    raincious  
       2015-01-05 14:13:18 +08:00
    @kmvan

    我这里改成这样:
    https://gist.github.com/anonymous/5e7191f4fd142249d06b

    运行没有问题。你可能错在别的地方了,比如init没声明static?

    call_user_func这个函数可以看作支持某种程度上的“多态”。

    比如(如果有错请指正):

    call_user_func('FunctionName'); // 这样是调用函数(静态的)

    call_user_func(array('ClassName', 'MethodName')); // 这样就是调用静态方法。

    $instance = new class();
    call_user_func(array($instance, 'MethodName')); // 这样就是调用实例方法。
    haiyang416
        12
    haiyang416  
       2015-01-05 14:14:36 +08:00
    laoyuan
        13
    laoyuan  
       2015-01-05 14:55:37 +08:00
    好问题,正在看《PHP核心技术与最佳实践》里讲多态的一节
    LuckyHJH
        14
    LuckyHJH  
       2015-01-05 16:49:28 +08:00
    我遇到的问题是,new $class_name() 就会报错,PHP5.3.3,不知道是否同一个问题
    haiyang416
        15
    haiyang416  
       2015-01-05 17:03:34 +08:00   ❤️ 1
    LuckyHJH
        16
    LuckyHJH  
       2015-01-05 17:14:54 +08:00
    感谢15楼,另外话说为什么每次打开这个页面,都总在11楼那里卡一卡 - -
    sumhat
        17
    sumhat  
       2015-01-05 18:50:27 +08:00
    我来歪个楼。不太懂 PHP,但是为什么一定要用静态方法,不能直接扔一个实例进去么?
    ichou
        18
    ichou  
       2015-01-05 22:33:06 +08:00
    为什么我是第一次见这种用法 。。。
    大大们可以解释一下使用场景么?
    kmvan
        19
    kmvan  
    OP
       2015-01-05 22:44:52 +08:00 via Android
    @ichou 为什么我是第一次见这种用法 。。。
    不是吧?php可变变量很常见,很实用,但它可变的不够完全,郁闷啊…不过这点小瘕疵,不影响他是世界上最好的语言
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1056 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 19:45 · PVG 03:45 · LAX 11:45 · JFK 14:45
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.