2015-10-29 65 views
3

我想創建來自URL參數的字符串的類對象。laravel 5.1 - 基於字符串動態創建Class對象

例如:

http://localhost/CSWeb/api/search/Slideshare 

在上述網址Slideshare是參數,得到apiController->indexAction。當我使用參數字符串創建類對象在apiController.php線17

FatalErrorException

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錯誤:類 'Slideshare的'沒有找到

如果我改變代碼

$controller= new Slideshare; it works fine 

預先感謝您

回答

20

當字符串創建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); 

這種方法的優點是,現在創建對象的責任在於廠家,如果你需要去改變它,也許允許別名,添加一些額外的安全措施或其他任何東西,只需要在一個地方更改該代碼即可,但只要類簽名保留,代碼就可以繼續工作。

的工廠上有趣的教程: 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

+2

啊,它就在那裏。 +1。 「如果一個包含類的名字的字符串與new一起使用,那麼將創建該類的新實例,如果該類在名稱空間中,則在完成此操作時必須使用完全限定名稱。」 – ceejayoz

+0

@Scorch謝謝。完美的答案它工作正常。你拯救我的一天。試圖從最近1小時內解決這個問題。再次感謝你 。 –

+0

@ceejayoz還有其他方法可以做到嗎? –