如何使用$ this访问静态类成员?

时间:2015-03-15 06:39:28

标签: php oop laravel reference static-members

我正在尝试访问另一个类中的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访问它的正确方法是什么?

另一个例子: enter image description here

3 个答案:

答案 0 :(得分:5)

PHP语言禁止这种构造。还有其他例子。 (例如,之前,您无法直接访问函数返回的数组)

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

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

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

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

答案 1 :(得分:4)

您无法执行$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); }

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

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

使用箭头操作符->无法通过对象访问静态属性。

静态属性示例

<?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

答案 2 :(得分:2)

因为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变量。

我不会推荐它。对于这样的情况,你可以尝试像依赖注入这样的东西。