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

时间:2015-10-29 19:06:58

标签: php laravel-5.1

我想在来自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

提前谢谢

1 个答案:

答案 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