PHP const/static 变量不能在父类的静态上下文中使用

发布于 2024-10-17 17:17:08 字数 857 浏览 3 评论 0原文

由于某种原因(哪个?),子类中定义的 PHP const/static 变量不能在父类的静态上下文中使用。

为什么?

示例 1:

class Model{
  function getAll(){
    $query = "SELECT * FROM " . self::DATABASE_TABLE_NAME;
    // ...
  }
}

class Post extends Model{
  const DATABASE_TABLE_NAME = 'post';
}

$p = Post::getAll();

当我运行时,我得到:(

Fatal error: Undefined class constant 'DATABASE_TABLE_NAME' on line 3 

带有 $query = ... 的行)

示例 2:

class Model{
    function getAll(){
        $query = "SELECT * FROM " . self::$DATABASE_TABLE_NAME;
        // ...
    }
}

class Post extends Model{
    static $DATABASE_TABLE_NAME = 'post';
}

$p = Post::getAll();

然后我得到:(

Fatal error: Access to undeclared static property: Model::$DATABASE_TABLE_NAME on line 3

同一行)

For some reason (which?), PHP const/static variables defined in a child class are not usable in a static context by the parent class.

Why?

Example 1:

class Model{
  function getAll(){
    $query = "SELECT * FROM " . self::DATABASE_TABLE_NAME;
    // ...
  }
}

class Post extends Model{
  const DATABASE_TABLE_NAME = 'post';
}

$p = Post::getAll();

When I run that I get:

Fatal error: Undefined class constant 'DATABASE_TABLE_NAME' on line 3 

(The row with $query = ...)

Example 2:

class Model{
    function getAll(){
        $query = "SELECT * FROM " . self::$DATABASE_TABLE_NAME;
        // ...
    }
}

class Post extends Model{
    static $DATABASE_TABLE_NAME = 'post';
}

$p = Post::getAll();

Then I get:

Fatal error: Access to undeclared static property: Model::$DATABASE_TABLE_NAME on line 3

(Same row)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

花开浅夏 2024-10-24 17:17:08

PHP5.3 引入了晚期静态绑定 - 这就是你在寻找什么。

class ParentClass {
    public function getAll() {
        var_dump('Get all from ' . static::TABLE_NAME);
    }
}

class ChildClass extends ParentClass {
    const TABLE_NAME = 'my_table_name';
}

$c = new ChildClass();
$c->getAll(); // Get all from my_table_name

编辑:

但是你应该设计你的类有点不同。上述解决方案依赖于语言动态(您可以引用甚至不存在的东西(例如类常量))。在这样一个简单的例子中,一切都很好,但在实际情况下,这会导致生成可怕且难以维护的代码。

最好强制传递的类 (ChildClass) 实现一些返回表名称的方法:

abstract class ParentClass {
   // getAll function

   abstract protected function getTableName();
}

class ChildClass extends ParentClass {
    // You have to implement this method
    protected function getTableName() {
        return 'table name';
    }
}

PHP5.3 introduced late static binding — that's what you're looking for.

class ParentClass {
    public function getAll() {
        var_dump('Get all from ' . static::TABLE_NAME);
    }
}

class ChildClass extends ParentClass {
    const TABLE_NAME = 'my_table_name';
}

$c = new ChildClass();
$c->getAll(); // Get all from my_table_name

EDIT:

However you should design your classes a little bit different. The above solution relies on language dynamics (you can refer to something (eg. a class constant) that doesn't even exists). In such a simple example everything is fine but in real word cases this leads to producing horrible and hard to maintain code.

It'd be better to force the delivered class (ChildClass) to implement some method that returns table name:

abstract class ParentClass {
   // getAll function

   abstract protected function getTableName();
}

class ChildClass extends ParentClass {
    // You have to implement this method
    protected function getTableName() {
        return 'table name';
    }
}
七色彩虹 2024-10-24 17:17:08

我在这里找到了答案:
如何从扩展 PHP 中的静态调用获取类名类?

解决方案:

class Model{
    function getAll(){
        $class = get_called_class();
        $query = "SELECT * FROM " . $class::$DATABASE_TABLE_NAME;
        // ...
    }
}

class Post extends Model{
    static $DATABASE_TABLE_NAME = 'post';
}

$p = Post::getAll();

I found the answer here:
How can I get the classname from a static call in an extended PHP class?

Solution:

class Model{
    function getAll(){
        $class = get_called_class();
        $query = "SELECT * FROM " . $class::$DATABASE_TABLE_NAME;
        // ...
    }
}

class Post extends Model{
    static $DATABASE_TABLE_NAME = 'post';
}

$p = Post::getAll();
天生の放荡 2024-10-24 17:17:08

都有可用的。

在静态上下文下,您应该使用后期静态绑定 这样代码就会变成:

$query = "SELECT * FROM " . static::$DATABASE_TABLE_NAME;

出于理智原因,我还建议您使用常量。

There all available.

Under the static context you should be using late static binding so that the code would become:

$query = "SELECT * FROM " . static::$DATABASE_TABLE_NAME;

i would also advise you to use constants for sanity reasons.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文