PHP 通过多层类实现方法的固有性

  • 本文关键字:实现 方法 固有性 PHP php
  • 更新时间 :
  • 英文 :


我的代码在大量归结时看起来很像这样:

abstract class Car {
public abstract static function parts();
protected static function getParts() {
$parts = [];
$properties = (new ReflectionClass(static::class))->getProperties();
foreach ($properties as $property) {
$parts[] = $property->getName();
}
return $parts;
}
}
class Ford extends car {
public $wheels;
public $body;
public static function parts() {
return self::getParts();
}
}
class FordTruck extends Ford {
public $truckBed;
}
function getBaseParts($cartype) {
return $cartype::parts();
}

但是当我打电话给getBaseParts("FordTruck")时,我回来了

array(3) {
[0]=>
string(8) "truckBed"
[1]=>
string(6) "wheels"
[2]=>
string(4) "body"
}

实际上,我只想回到"轮子"和"身体",而不是过去Ford课中添加的"无关紧要"的东西。我认为在我关心的部分的类中创建一个parts()方法,然后调用self::getParts(),进而从static获取属性,这意味着"静态"所指的类将是Ford类。但这更像是在召唤FordTruck班的parts()

有没有办法通过此设置获得我正在寻找的功能?我能想到的"最简单的"方法是将"getParts()"方法移动到Ford类中,并让它调用自我的反射类,但我有几十个类可以扩展Ford如果我以这种方式修复它,它们都只是复制的代码。

我不是这个解决方案的粉丝,你宁愿改变你的解决方案背后的心态,但这里有一个简单的解决方案来解决你的问题

<?php
abstract class Car {
public abstract static function parts();
protected static function getParts($class = null) {
return array_keys(get_class_vars($class ?? static::class));
}
}
class Ford extends car {
public $wheels;
public $body;
public static function parts() {
return self::getParts(Ford::class);
}
}
class FordTruck extends Ford {
public $truckBed;
}
function getBaseParts($cartype) {
return $cartype::parts();
}
var_dump(getBaseParts("FordTruck"));

测试 : https://3v4l.org/s8Aar

static::class 总是会返回相关对象实例化的"最低级别"类。因此,static::class 总是会返回 FordTruck,即使它是在 Car 中定义的,并且函数本身是在 Ford 中调用

的。另一方面,self::class 返回它所定义的类的类名。所以福特的self::class将返回福特,即使这个对象在技术上是福特卡车。

获得所需功能的最简单方法是将 self::class 的值从 Ford 传递给 getParts(),并在 Reflection() 中使用它。

因此,例如:

<?php
abstract class Car {
public abstract static function parts();
protected static function getParts(string $className) {
$parts = [];
$properties = (new ReflectionClass($className))->getProperties();
foreach ($properties as $property) {
$parts[] = $property->getName();
}
return $parts;
}
}
class Ford extends Car {
public $wheels;
public $body;
public static function parts() {
return self::getParts(self::class);
}
}
class FordTruck extends Ford {
public $truckBed;
}

function getBaseParts($cartype) {
return $cartype::parts();
} 

我设法找到了这个有效的"解决方法",但我不太确定它是最好的解决方案。

abstract class Car {
public static function getParts() {
$carModel = array_reverse(array_values(class_parents(static::class)))[1];
$parts = [];
$properties = (new ReflectionClass(new $carModel))->getProperties();
foreach ($properties as $property) {
$parts[] = $property->getName();
}
return $parts;
}
}
class Ford extends car {
public $wheels;
public $body;
}
class FordTruck extends Ford {
public $truckBed;
}
function getBaseParts($cartype) {
return $cartype::getParts();
}
getBaseParts("FordTruck");

相关内容

  • 没有找到相关文章

最新更新