我想在来自URL参数的字符串上创建类的对象。
例如:
http://localhost/CSWeb/api/search/Slideshare
上面的网址Slideshare
中的是进入apiController->indexAction
的参数。
slideshare.php class
<?php
namespace App\Http\API;
class slideshare
{
public function index()
{
return 'any data';
}
}
apiController.php
namespace App\Http\Controllers\API;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use Auth;
use App\Http\API\Slideshare;
class apiController extends Controller
{
public function index($source)
{
$controller= new $source;
return $controller->index();
// if i change code to $controller= new Slideshare; it works fine
}
}
当我使用参数字符串创建类对象时,laravel错误
apiController.php第17行中的FatalErrorException:Class 找不到'Slideshare'
如果我将代码更改为
$controller= new Slideshare; it works fine
提前谢谢
答案 0 :(得分:26)
使用字符串创建PHP对象时,必须提供类的完全限定名称(a.k.a包括命名空间)。所以,你应该有这样的东西:
$className = 'App\\Http\\API\\' . $source;
$controller = new $className;
return $controller->index();
另一种方法是,如果您确定要实例化的类与代码位于同一名称空间中,则可以使用:
$className = __NAMESPACE__ . '\\' . $source;
$controller = new $className;
return $controller->index();
通过工厂设计模式,更详细的实现相同结果的方法。基本上,您创建了一个负责实例化元素的类,并将实际创建这些对象的任务委托给该类。这些方面的东西:
class Factory {
function __construct ( $namespace = '' ) {
$this->namespace = $namespace;
}
public function make ( $source ) {
$name = $this->namespace . '\\' . $source;
if ( class_exists( $name ) ) {
return new $name();
}
}
}
$factory = new Factory( __NAMESPACE__ );
$controller = $factory->make( $source );
这种方法的优点是创建对象的责任现在位于Factory中,如果您需要更改它,可能允许别名,添加一些额外的安全措施或任何其他东西,您只需要在一个地方更改该代码,但只要类签名仍然存在,您的代码就会继续工作。
有关工厂的有趣教程: http://culttt.com/2014/03/19/factory-method-design-pattern/
来源: http://nl3.php.net/manual/en/language.oop5.basic.php#language.oop5.basic.new http://php.net/manual/en/language.namespaces.nsconstants.php