【问题标题】:How can I access to static class members using $this? [duplicate]如何使用 $this 访问静态类成员? [复制]
【发布时间】:2015-03-15 06:39:27
【问题描述】:

我正在尝试访问另一个类中 ActiveModel 类的静态类成员。

$class = "\ActiveModel\User";
$class::create(); //WORKS!

$this->class = "\ActiveModel\User";
$this->class::create(); //DOESN'T WORK :( - Throws "Incorrect access to static class member" error

使用$this->var 访问它的正确方法是什么?

另一个例子:

【问题讨论】:

    标签: php oop laravel reference static-members


    【解决方案1】:

    PHP 语言禁止这种结构。还有其他例子。 (例如,以前,您不能直接访问函数返回的数组)

    $elem = get_array()[0] // Doesn't work until PHP 5.4.0
    

    这些限制背后的主要原因是解析器不喜欢它。因为它们很复杂,或者会引起歧义,或者他们想保留这样的结构以供将来使用。

    您可以通过分配一个临时变量来简单地解决此限制:

    $className = $this->class;
    $className::create(); // This will work.
    

    【讨论】:

    • 是的,这就是我到目前为止一直在做的事情。但是将变量提取到另一个变量中似乎有点多余(但是阅读阿德里安的回复,我想这是正确的唯一方法现在)
    • ($this->class)::create()
    【解决方案2】:

    你不能做像$this->class::create() 这样的事情。如果您想访问静态成员,您必须使用Class::Member。 Zend PHP 解析器的当前实现仅支持直接在类名或变量上进行的静态方法调用。语法如下:

    %token T_PAAMAYIM_NEKUDOTAYIM ":: (T_PAAMAYIM_NEKUDOTAYIM)"
    
    function_call:
        name argument_list
            { $$ = zend_ast_create(ZEND_AST_CALL, $1, $2); }
    |   class_name T_PAAMAYIM_NEKUDOTAYIM member_name argument_list
            { $$ = zend_ast_create(ZEND_AST_STATIC_CALL, $1, $3, $4); }
    |   variable_class_name T_PAAMAYIM_NEKUDOTAYIM member_name argument_list
            { $$ = zend_ast_create(ZEND_AST_STATIC_CALL, $1, $3, $4); }
    |   callable_expr argument_list
            { $$ = zend_ast_create(ZEND_AST_CALL, $1, $2); }
    

    将类属性或方法声明为静态使它们无需实例化即可访问。声明为静态的属性不能被实例化的类对象访问(尽管静态方法可以)。

    因为静态方法可以在没有创建对象实例的情况下调用,所以伪变量$this 在声明为静态的方法中不可用。

    不能使用箭头运算符->通过对象访问静态属性。

    静态属性示例

    <?php
    class Foo
    {
        public static $my_static = 'foo';
    
        public function staticValue() {
            return self::$my_static;
        }
    }
    
    class Bar extends Foo
    {
        public function fooStatic() {
            return parent::$my_static;
        }
    }
    
    
    print Foo::$my_static . "\n";
    
    $foo = new Foo();
    print $foo->staticValue() . "\n";
    print $foo->my_static . "\n";      // Undefined "Property" my_static 
    
    print $foo::$my_static . "\n";
    $classname = 'Foo';
    print $classname::$my_static . "\n"; // As of PHP 5.3.0
    
    print Bar::$my_static . "\n";
    $bar = new Bar();
    print $bar->fooStatic() . "\n";
    ?>
    

    静态方法示例

    <?php
    class Foo {
        public static function aStaticMethod() {
            // ...
        }
    }
    
    Foo::aStaticMethod();
    $classname = 'Foo';
    $classname::aStaticMethod(); // As of PHP 5.3.0
    ?>
    

    阅读更多:

    http://php.net/manual/en/language.oop5.static.php

    Call static method with class name stored as instance variable

    https://github.com/php/php-src/blob/master/Zend/zend_language_parser.y#L890

    【讨论】:

      【解决方案3】:

      因为 PHP 不支持这种评估在 5.6.2 之前(似乎较新的版本仍然不支持它)。

      如果无论如何你都必须这样做,请像这样使用call_user_func()call_user_func_array()

      call_user_func_array(
          array(
              $this->modalClassName, 
              'create'
          ), 
          array()
      );
      

      并通过使用为您的模态类添加setHasMany 方法

      call_user_func_array(
          array(
              $this->modalClassName, 
              'setHasMany'
          ), 
          array(['user_level'])
      );
      

      而不是直接设置$hasmany变量。

      虽然我不会推荐它。对于这种情况,您可以尝试依赖注入

      【讨论】:

      • 谢谢,但我认为将它提取回变量并使用它更容易......仍然对 TIMTOWTDI 有好处
      • 是的,返回本地变量的方式也不错,而且它似乎比 call_user_func_* 更快:)
      猜你喜欢
      • 2011-04-18
      • 2018-10-05
      • 2014-08-07
      • 2012-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多