我正在创建一个库。
我的目标是使该库非常易于使用,不需要大量的编程知识,并且系统架构师可以生成其代码。 (低代码库)
我的一些函数是静态的,因为我应该通过
call_user_func()
或任何可以运行仅包含字符串参数且不带任何参数的类函数的方法来调用它们。
我的问题是我想将静态函数的主体代码放在库中,并且代码中继承的类将执行相同的函数代码,但使用继承类的值。
我还希望继承的类需要最少的更改,并且在大多数情况下,只需定义其中的值就足够了。
在库中,我使用了类、抽象类、接口和污点,并将值定义为 const 和 static 变量。但这些案例都无济于事。
这是我的library代码的简化示例:
class ParentClass { // OR abstract class OR interface OR trait
public const TABLE = 'placeholder'; // OR public static $TABLE = 'placeholder'; OR remove this line!
public static function save() {
echo "saving " . self::TABLE . ' ...' . PHP_EOL;
}
// and a lot of same functions...
}
这是我的代码主代码的简化示例:
class ChildClass extends /* OR implements (for interface) */ ParentClass {
// use ParentClass; (for trait)
public const TABLE = 'users'; // OR public static $TABLE = 'users'; (using static variable)
}
call_user_func(['ChildClass', 'save']);
// ChildClass::save();
错误:
使用
trait
和 static variable
;错误:ChildClass 和 ParentClass 定义相同的属性 ($TABLE)
使用
trait
和 const
;错误:特征不能有常量
使用
abstract class
或 class
与 static variable
或 const
;我得到的是“占位符”而不是“用户”
使用
interface
;错误:接口函数ParentClass::save()不能包含body
使用
interface
和 static variable
;错误:接口可能不包含属性
您想要做的事情的奇特术语是“后期静态绑定”:
对当前类的静态引用(如 self:: 或 CLASS)使用函数所属的类进行解析,如定义函数的位置...
后期静态绑定试图通过引入一个引用最初在运行时调用的类的关键字来解决该限制。
您可以在链接的手册页上阅读完整的详细信息,但简短的答案是,您需要编写
self::
,而不是 static::
。这适用于类常量和静态属性:
class ParentClass { // whether it's abstract or not makes no difference
public const TABLE = 'fallback_const_if_wanted';
public static string $table = 'fallback_var_if_wanted';
public static function demo() {
echo 'self::TABLE is ', self::TABLE, "\n";
echo 'self::$table is ', self::$table, "\n";
echo 'static::TABLE is ', static::TABLE, "\n";
echo 'static::$table is ', static::$table, "\n";
}
}
class ChildClass extends ParentClass {
public const TABLE = 'child_const';
public static string $table = 'child_var';
}
ChildClass::demo();
正如您在这个现场演示中看到的,结果是:
self::TABLE is fallback_const_if_wanted
self::$table is fallback_var_if_wanted
static::TABLE is child_const
static::$table is child_var
如果您没有在父类中定义值,则使用
self::
会出现错误,但 static::
仍会正确解析:
abstract class ParentClass {
public static function demo() {
echo 'static::TABLE is ', static::TABLE, "\n";
echo 'static::$table is ', static::$table, "\n";
}
}
class ChildClass extends ParentClass {
public const TABLE = 'child_const';
public static string $table = 'child_var';
}
ChildClass::demo();
给予:
static::TABLE is child_const
static::$table is child_var