我希望在PHP中将字符串转换为类名,如下所示。 但我得到错误类名必须是有效对象或字符串它可能是错误,因为表仍然是一个字符串。
$table = Teller::select('*')->where('user_id','=', $this->user_id)->first();
$modelName = trim($table->tables,'"');
$loan = $modelName::select('*')->where('id','=', $id)->get();
答案 0 :(得分:1)
考虑这个简单场景:
<?php
class SomeClass{
public static $a = 12;
public static $b = "some value";
public static $c = "another value";
public static function getSomeData(){
return self::$a . " " . self::$b . " " . self::$c;
}
}
$b = SomeClass::getSomeData();
//DUMPS '12 some value another value' TO THE OUTPUT STREAM...
var_dump($b);
$strClassName = "SomeClass";
//STILL DUMPS '12 some value another value' TO THE OUTPUT STREAM...
var_dump(call_user_func($strClassName. "::getSomeData"));
将此知识扩展到您的独特案例,您可能希望执行以下操作:
<?php
$table = Teller::select('*')->where('user_id','=', $this->user_id)->first();
$modelName = trim($table->tables,'"');
$implicitCall = call_user_func($modelName. "::select", '*');
$implicitCall = call_user_func($modelName. "::where", array('id', '=', $id));
$loan = call_user_func($modelName. "::get");
?>
任选地;你甚至可以更进一步。因为我们知道您正在使用流利 Setters;很明显,第一个隐式调用将返回Class的一个实例,所以我们可以这样做:
<?php
$table = Teller::select('*')->where('user_id','=', $this->user_id)->first();
$modelName = trim($table->tables,'"');
// THIS SHOULD RETURN AN INSTANCE OF THE CLASS IN QUESTION: THE MODEL CLASS
$implicitCall = call_user_func($modelName. "::select", '*');
// DO YOU DOUBT IT? WELL, DOUBT IS THE BEGINNING OF ALL KNOWLEDGE.
// I DOUBT IT TOO; SO LET'S CONFIRM OUR DOUBTS
var_dump($implicitCall); // EXPECTED TO DUMP THE CLASS IN QUESTION.
// NOW WE CAN JUST USE THE $implicitCall VARIABLE AS IF IT WAS AN INSTANCE OF THE MODEL CLASS LIKE SO:
$loan = $implicitCall->where('id','=', $id)->get();
?>
我希望这些答案对你有用并且对你有用...; - )
答案 1 :(得分:1)
可以从字符串转换为类名
PHP中没有类名概念。
你有一个字符串,如果有一个具有该名称的类,那么你可以使用该字符串来创建该类的对象或调用该类的静态方法。
您发布的代码对我来说是正确的。我甚至写了一个小类并测试了类似的代码,它工作正常。我可以看到有两个原因导致代码因PHP错误而失败:
$modelName
不是字符串;对于您发布的代码,这是不可能的。使用trim()
返回的值初始化$modelName
,trim()
始终返回字符串。$modelName
仅包含类名,但发布的代码是在命名空间中声明的函数或方法的一部分;在这种情况下,$modelName
必须包含the full name of the desired class,从根命名空间开始;完整的班级名称中不需要初始\
,但可以使用它。这个使用类的完整名称的要求听起来像是解释器的怪癖但却不是; use
声明只是一种快捷方式,它允许程序员在代码中使用较短的名称。 use
声明不生成任何代码,在运行时,所有类名都完全限定了它们的名称空间。