如何在 PHP 5.2 中的子类中创建一个常量,以便在父类中找到的方法中使用?

发布于 2024-10-07 06:11:02 字数 890 浏览 4 评论 0原文

编辑:
*注意:不幸的是,我暂时使用 PHP 5.2。我找不到提供 5.3 的像样便宜主机...


在 PHP 中,self 指的是定义被调用方法的类。这意味着,如果您不重写子类中的方法,则关键字 self 将引用父类,即使从子类调用也是如此。

例如,此代码:

<?php

class ParentClass {
  const NAME = "ParentClass";
  public function showName() {
    echo self::NAME . "<br />\n";
  }
}

class ChildClass extends ParentClass {
  const NAME = "ChildClass";
  public function __construct() {
    echo self::NAME . "<br />\n";
  }
}

$test = new ChildClass();
$test->showName();

?>

将创建此输出:

ChildClass
ParentClass

我想要做的是创建一个默认方法(例如上例中的 showName() ),该方法存在于父类中,并具有定义默认值的常量使用。在子级中,我希望能够重写这些常量(请注意上面子级定义中的 const),并在我在子级实例上调用方法时使用这些值。

简而言之,我怎样才能使上述示例的输出...

ChildClass
ChildClass

...而不必在子级中复制父级的代码?

Edit:
*Note: I'm using PHP 5.2 for the time being, unfortunately. I can't find a decent cheap host offering 5.3...


In PHP, self refers to the class in which the called method is defined. This means that if you don't override a method in the child class, the keyword self will refer to the parent class, even when called from the child.

For example, this code:

<?php

class ParentClass {
  const NAME = "ParentClass";
  public function showName() {
    echo self::NAME . "<br />\n";
  }
}

class ChildClass extends ParentClass {
  const NAME = "ChildClass";
  public function __construct() {
    echo self::NAME . "<br />\n";
  }
}

$test = new ChildClass();
$test->showName();

?>

Will create this output:

ChildClass
ParentClass

What I want to do is to create a default method (e.g. showName() in the example above) which exists in a parent class with constants defining default values to use. In the child, I want to be able to override these constants (note the const in the child definition above), and have those values be used when I call the method on an instance of the child.

In short, how can I make it so that the output of the above sample would be...

ChildClass
ChildClass

...without having to duplicate the code of the parent within the child?

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

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

发布评论

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

评论(4

本宫微胖 2024-10-14 06:11:02

尝试

function showName() {
   return static::NAME;
}

使用后期静态绑定

从 PHP 5.3.0 开始,PHP 实现了
称为后期静态绑定的功能
可以用来参考
在静态上下文中调用类
继承。

更准确地说,后期静态绑定
通过存储命名的类来工作
最后一个“非转接呼叫”。如果出现以下情况
静态方法调用,这是类
明确命名(通常是
:: 运算符的左侧);以防万一
非静态方法调用中,它是
对象的类。一个“转发
call” 是静态的,即
自我介绍::, 家长::,
static::,或者,如果在班级中上升
层次结构,forward_static_call()。这
函数 get_used_class() 可以是
用于检索字符串
被调用类的名称和 static::
介绍其范围。

编辑:对于 5.2.x

如果您没有 5.3.0,您将无法利用此功能。一种常见的hack解决方案是创建一个由子类名引用的静态缓存(例如private static $statics = array())。它要求您跟踪对象继承以覆盖 __construct 上的值,并显式定义哪些静态是“可继承的”。例如,SilverStripe 在 Sapphire ORM 中使用此技术来绕过 PHP 静态绑定限制。他们定义了一个基本对象类,以及各种静态变量管理功能。

Try

function showName() {
   return static::NAME;
}

This uses late static binding:

As of PHP 5.3.0, PHP implements a
feature called late static bindings
which can be used to reference the
called class in a context of static
inheritance.

More precisely, late static bindings
work by storing the class named in the
last "non-forwarding call". In case of
static method calls, this is the class
explicitly named (usually the one on
the left of the :: operator); in case
of non static method calls, it is the
class of the object. A "forwarding
call" is a static one that is
introduced by self::, parent::,
static::, or, if going up in the class
hierarchy, forward_static_call(). The
function get_called_class() can be
used to retrieve a string with the
name of the called class and static::
introduces its scope.

EDIT: For 5.2.x

If you don't have 5.3.0 you won't be able to take advantage of this. One common hack solution is to create a static cache (e.g. private static $statics = array()) referenced by child class name. It requires you to track object inheritance to override the value on __construct, and to explicitly define which statics are 'inheritable'. For example, SilverStripe uses this technique in the Sapphire ORM to get around PHP static binding limitations. They define a base Object class, and various static var management functions.

爱你不解释 2024-10-14 06:11:02

我相信您的情况的相应语法盐是:

print constant(get_class($this)."::NAME");

I believe the according syntactic salt for your case is:

print constant(get_class($this)."::NAME");
浅暮の光 2024-10-14 06:11:02

也许这只是因为你的例子很短,但“自我”引用似乎并不需要。

我只想这样做:

class ParentClass {
  public function showName() {
    echo $this->name() . "<br />\n";
  }

  public static function name() {
    return "ParentClass";
  }
}

class ChildClass extends ParentClass {
  public function __construct() {
    echo $this->name() . "<br />\n";
  }
  public static function name() {
    return "ChildClass";
  }
}

$test = new ChildClass();
$test->showName();

输出:

ChildClass
ChildClass

Maybe it's just because of your short example but the "self" referencing doesn't seem needed.

I would just do this:

class ParentClass {
  public function showName() {
    echo $this->name() . "<br />\n";
  }

  public static function name() {
    return "ParentClass";
  }
}

class ChildClass extends ParentClass {
  public function __construct() {
    echo $this->name() . "<br />\n";
  }
  public static function name() {
    return "ChildClass";
  }
}

$test = new ChildClass();
$test->showName();

Output:

ChildClass
ChildClass
放我走吧 2024-10-14 06:11:02

使用static::CONSTNAME将返回正确的值。

Using static::CONSTNAME will return the right value.

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