laravel 5.1 - 基于字符串动态创建Class对象

Nis*_*eta 9 php laravel-5.1

我想在来自URL参数的字符串上创建类的对象.

例如 :

 http://localhost/CSWeb/api/search/Slideshare
Run Code Online (Sandbox Code Playgroud)

在上面的URL Slideshare是进入的参数apiController->indexAction.

slideshare.php class

<?php

namespace App\Http\API;

class slideshare 
{

    public function index()
    {
         return 'any data'; 

    }

}
Run Code Online (Sandbox Code Playgroud)

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
    }

}
Run Code Online (Sandbox Code Playgroud)

当我使用参数字符串创建类对象时laravel错误

apiController.php第17行中的FatalErrorException:找不到类'Slideshare'

如果我改变代码

$controller=  new Slideshare; it works fine
Run Code Online (Sandbox Code Playgroud)

先感谢您

Ped*_*lva 34

使用字符串创建PHP对象时,必须提供类的完整限定名称(也包括命名空间).所以,你应该有这样的事情:

$className = 'App\\Http\\API\\' . $source;

$controller =  new $className;

return $controller->index();
Run Code Online (Sandbox Code Playgroud)

另一种方法是,如果您确定要实例化的类与代码位于同一名称空间中,则可以使用:

$className = __NAMESPACE__ . '\\' . $source;

$controller =  new $className;

return $controller->index();
Run Code Online (Sandbox Code Playgroud)

实现相同结果的更详细的方法是通过工厂设计模式.基本上,您创建了一个负责实例化元素的类,并将实际创建这些对象的任务委托给该类.这些方面的东西:

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 );
Run Code Online (Sandbox Code Playgroud)

这种方法的优点是创建对象的责任现在位于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

  • 啊,就是这样.+1."如果包含类名称的字符串与new一起使用,则将创建该类的新实例.如果该类在命名空间中,则在执行此操作时必须使用其完全限定名称." (2认同)