php laravel 5.1 - 基于字符串动态创建 Class 对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33422627/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
laravel 5.1 - Dynamically create Class object based on string
提问by Nishit Maheta
i want to create object of class base on string which come from URL parameter.
我想基于来自 URL 参数的字符串创建类的对象。
for example :
例如 :
http://localhost/CSWeb/api/search/Slideshare
in above URL Slideshare
is parameter which get in apiController->indexAction
.
在上面的 URL 中Slideshare
是进入的参数apiController->indexAction
。
slideshare.php class
slideshare.php class
<?php
namespace App\Http\API;
class slideshare
{
public function index()
{
return 'any data';
}
}
apiController.php
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 error when i use parameter string to create class object
使用参数字符串创建类对象时出现laravel错误
FatalErrorException in apiController.php line 17: Class 'Slideshare' not found
apiController.php 第 17 行中的 FatalErrorException:找不到“Slideshare”类
if i change code to
如果我将代码更改为
$controller= new Slideshare; it works fine
Thank you in advance
先感谢您
回答by Pedro M. Silva
When creating PHP objects with strings, you must provide the full qualified name of the class (a.k.a include the namespace). So, you should have something like this:
创建带有字符串的 PHP 对象时,您必须提供类的全限定名(也就是包括命名空间)。所以,你应该有这样的东西:
$className = 'App\Http\API\' . $source;
$controller = new $className;
return $controller->index();
Another way to do it, if you are sure that the class you want to instantiate lives in the same namespace as your code, you can use:
另一种方法是,如果您确定要实例化的类与代码位于同一命名空间中,则可以使用:
$className = __NAMESPACE__ . '\' . $source;
$controller = new $className;
return $controller->index();
A more elaborated way of achieving the same results is through the Factory Design Pattern. Basically you create a class that is responsible for instantiating elements, and you delegate the task of actually creating those objects to that class. Something along those lines:
实现相同结果的更详细的方法是通过工厂设计模式。基本上,您创建一个负责实例化元素的类,并将实际创建这些对象的任务委托给该类。沿着这些路线的东西:
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 );
The advantage of this approach is that the responsability of creating the objects now lies in the Factory, and if you ever need to change it, maybe allow for aliases, add some additional security measures, or any other thing, you just need to change that code in one place, but as long as the class signature remains, your code keeps working.
这种方法的优点是现在创建对象的责任在于工厂,如果你需要改变它,可能允许别名,添加一些额外的安全措施,或者任何其他事情,你只需要改变它代码在一个地方,但只要类签名仍然存在,您的代码就可以继续工作。
An interesting tutorial on factories: http://culttt.com/2014/03/19/factory-method-design-pattern/
一个有趣的工厂教程:http: //culttt.com/2014/03/19/factory-method-design-pattern/
Source: http://nl3.php.net/manual/en/language.oop5.basic.php#language.oop5.basic.newhttp://php.net/manual/en/language.namespaces.nsconstants.php
来源:http: //nl3.php.net/manual/en/language.oop5.basic.php#language.oop5.basic.new http://php.net/manual/en/language.namespaces.nsconstants.php