php 强制定义类型,PHP中的抽象常量-强制子类定义常量

在PHP中,虽然没有抽象常量的概念,但可以通过自引用常量和异常处理来模拟这一效果。在抽象类中,可以定义一个自引用的常量,然后在子类中覆盖它。如果子类没有定义这个常量,运行时会抛出致命错误。此外,还可以在抽象类的构造函数中检查子类是否定义了特定的常量,如果没有则抛出异常。这种方法可以帮助强制子类定义必要的常量。
摘要由CSDN通过智能技术生成

PHP中的抽象常量-强制子类定义常量

我注意到,PHP中不能有抽象常量。

有没有一种方法可以强制子类定义常量(我需要在抽象类内部方法之一中使用该常量)?

Alex asked 2020-07-25T23:10:52Z

5个解决方案

41 votes

这可能有点“骇客”,但工作量很小,但如果未在子类中声明该常量,则会显示不同的错误消息。

自引用常量声明在语法上是正确的,并且可以毫无问题地进行解析,只有在该声明实际上在运行时执行时才会抛出错误,因此抽象类中的自引用声明必须在子类中被覆盖,否则将发生致命错误 :Foo。

在此示例中,抽象的父类Foo强制其所有子代声明变量Donald。此代码运行良好,输出Donald。但是,如果子类Fooling没有声明该变量,则会触发致命错误。

abstract class Foo {

// Self-referential 'abstract' declaration

const NAME = self::NAME;

}

class Fooling extends Foo {

// Overrides definition from parent class

// Without this declaration, an error will be triggered

const NAME = 'Donald';

}

$fooling = new Fooling();

echo $fooling::NAME;

WebSmithery answered 2020-07-25T23:13:14Z

28 votes

constant是constant; 据我所知,PHP中没有abstract或private常量,但是您可以解决以下问题:

样本摘要类

abstract class Hello {

const CONSTANT_1 = 'abstract'; // Make Abstract

const CONSTANT_2 = 'abstract'; // Make Abstract

const CONSTANT_3 = 'Hello World'; // Normal Constant

function __construct() {

Enforcer::__add(__CLASS__, get_called_class());

}

}

这样会很好

class Foo extends Hello {

const CONSTANT_1 = 'HELLO_A';

const CONSTANT_2 = 'HELLO_B';

}

new Foo();

酒吧将返回错误

class Bar extends Hello {

const CONSTANT_1 = 'BAR_A';

}

new Bar();

Songo将返回错误

class Songo extends Hello {

}

new Songo();

强制类

class Enforcer {

public static function __add($class, $c) {

$reflection = new ReflectionClass($class);

$constantsForced = $reflection->getConstants();

foreach ($constantsForced as $constant => $value) {

if (constant("$c::$constant") == "abstract") {

throw new Exception("Undefined $constant in " . (string) $c);

}

}

}

}

Baba answered 2020-07-25T23:12:44Z

18 votes

不幸的是,不是……一个常数正是它在锡上所说的常数。 一旦定义了它,就无法重新定义,因此,以这种方式,不可能通过PHP的抽象继承或接口来要求对其进行定义。

但是...您可以检查常量是否在父类的构造函数中定义。 如果不是,则抛出异常。

abstract class A

{

public function __construct()

{

if (!defined('static::BLAH'))

{

throw new Exception('Constant BLAH is not defined on subclass ' . get_class($this));

}

}

}

class B extends A

{

const BLAH = 'here';

}

$b = new B();

这是我可以从您的初始描述中想到的最佳方法。

Jamie Rumbelow answered 2020-07-25T23:13:43Z

7 votes

不,但是您可以尝试其他方法,例如抽象方法:

abstract class Fruit

{

abstract function getName();

abstract function getColor();

public function printInfo()

{

echo "The {$this->getName()} is {$this->getColor()}";

}

}

class Apple extends Fruit

{

function getName() { return 'apple'; }

function getColor() { return 'red'; }

//other apple methods

}

class Banana extends Fruit

{

function getName() { return 'banana'; }

function getColor() { return 'yellow'; }

//other banana methods

}

或静态成员:

abstract class Fruit

{

protected static $name;

protected static $color;

public function printInfo()

{

echo "The {static::$name} is {static::$color}";

}

}

class Apple extends Fruit

{

protected static $name = 'apple';

protected static $color = 'red';

//other apple methods

}

class Banana extends Fruit

{

protected static $name = 'banana';

protected static $color = 'yellow';

//other banana methods

}

资源

Songo answered 2020-07-25T23:14:11Z

1 votes

在php 7.2中进行了测试,但从5.3开始,您可以利用后期静态绑定来存档此行为。 由于与大多数情况相同,它会引发致命错误,因为在大多数情况下,您都不希望在运行时处理致命错误。如果需要,可以轻松实现自定义错误处理程序。

所以以下对我有用:

abstract class Foo {

public function __construct() {

echo static::BAR;

}

}

class Bar extends Foo {

const BAR = "foo bar";

}

$bar = new Bar(); //foo bar

如果卸下const,则会得到:

Fatal error: Uncaught Error: Undefined class constant 'BAR' in ...

Code Spirit answered 2020-07-25T23:14:40Z

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值