父类函数引用异常:buildTableName无法将FooRepository转为foo
问题排查:buildTableName()返回空字符串的原因
问题核心在于buildTableName()方法里的self::class用法错误:
- 在抽象类
Repository中,self始终指向当前类(Repository),而非调用该方法的子类FooRepository。 - 反射获取到的短类名是
Repository,用str_replace移除Repository后直接变成空字符串,最终返回空。 - 子类
FooRepository的query()方法里用self::class是正确的,因为这里的self指向子类本身,所以打印的类名正常。
修复方案
利用PHP的后期静态绑定,将self::class替换为static::class,让它指向实际调用方法的子类:
abstract class Repository { protected function buildTableName(): string { $shortName = (new \ReflectionClass(static::class))->getShortName(); $tableName = str_replace('Repository', '', $shortName); return strtolower($tableName); } } class FooRepository extends Repository { public function query() { echo "my class is ".self::class; echo $this->buildTableName(); } } (new FooRepository())->query();
替代方案(无需反射)
通过get_class($this)直接获取当前对象的类名,再提取短类名:
abstract class Repository { protected function buildTableName(): string { $fullClassName = get_class($this); $shortName = substr($fullClassName, strrpos($fullClassName, '\\') + 1); $tableName = str_replace('Repository', '', $shortName); return strtolower($tableName); } }
内容的提问来源于stack exchange,提问作者MadCatERZ
相关产品推荐
相关产品推荐

