iT邦幫忙

0

laravel一個控制器有多個class使用疑問

最近在研究laravel的服務容器概念,
文章:https://laravel-china.org/topics/789/laravel-learning-notes-the-magic-of-the-service-container

有一個疑問不是很理解,麻煩各位大大說明
使用的是Laravel 5.2版本。
我現在有一個controller SuperModuleFactoryController.php。
SuperModuleFactoryController.php 裡面會有兩個不同的class
SuperModuleFactoryController 跟 XPower 這兩個class 。

<?php

namespace App\Http\Controllers;

use App\Http\Controllers\SuperModuleFactoryController;
use App\Http\Controllers\XPower;
use Illuminate\Routing\Controller as BaseController;

class SuperModuleFactoryController extends BaseController
{
	public function makeModule($moduleName, $options)
	{
	    switch ($moduleName) {
	        case 'Fight':   return new Fight($options[0], $options[1]);
	        case 'Force':   return new Force($options[0]);
	        case 'Shot':    return new Shot($options[0], $options[1],
            $options[2]);
	    }
	}
   
}

interface SuperModuleInterface
{
    /**
     * 超能力激活方法
     *
     * 任何一个超能力都得有该方法,并拥有一个参数
     *@param array $target 针对目标,可以是一个或多个,自己或他人
     */
    public function activate(array $target);
}

/**
 * X-超能量
 */
class XPower extends BaseController implements SuperModuleInterface 
{
    public function activate(array $target)
    {
        // 这只是个例子。。具体自行脑补
    }
}

/**
 * 终极炸弹 (就这么俗)
 */
class UltraBomb implements SuperModuleInterface
{
    public function activate(array $target)
    {
        // 这只是个例子。。具体自行脑补
    }
}


class Fight
{
    protected $speed;
    protected $holdtime;
    public function __construct($speed, $holdtime) {
    	$this->speed = $speed; 
    	$this->holdtime = $holdtime;
    }
}

class Force
{
    protected $force;
    public function __construct($force) {
    	$this->force = $force;
    }
}

class Shot
{
    protected $atk;
    protected $range;
    protected $limit;
    public function __construct($atk, $range, $limit) {
    	$this->atk = $atk;
    	$this->range = $range;
    	$this->limit = $limit;
    }
}

我想要在另一個控制器 TestController.php檔案裡面,
使用SuperModuleFactoryController.php 檔案裡面的兩個不同class。
class XPower
class SuperModuleFactoryController

所以我在TestController.php檔案裡面

<?php
namespace App\Http\Controllers;

use App\Http\Controllers\TestController;
use App\Http\Controllers\SuperModuleFactoryController;
use App\Http\Controllers\SupermanController;

class TestController extends BaseController
{
    use AuthorizesRequests, DispatchesJobs, ValidatesRequests;

    public function __construct()
    {
    	$this->middleware('web');
    }

    public static function superman()
    {
        // 超能力模组 
        $superModule = new XPower;   
        //這邊會顯示 Class 'App\Http\Controllers\XPower' not found
    }
}

如果我需要 new 另一個class XPower 要怎麼做呢?
$superModule = new XPower;
laravel會顯示
Class 'App\Http\Controllers\XPower' not found

PS:如果一個class 一個controller 可以解決,
在SuperModuleFactoryController.php 底下使用兩個不同的class也可以解決。

但如果要跨不同的controller 在laravel 5.2的架構下,要怎麼寫才是對的呢?

在不同的controller (TestController.php)
呼叫另一個SuperModuleFactoryController (SuperModuleFactoryController.php)

底下的兩個不同class要怎麼做呢?

看更多先前的討論...收起先前的討論...
weiclin iT邦高手 4 級 ‧ 2018-05-30 16:44:04 檢舉
為什麼你會有一堆 class 擠在一個檔案裡?
q00153 iT邦新手 3 級 ‧ 2018-05-30 17:10:04 檢舉
一個檔案請保有一個 class 就好,
如果有共用的 class 請單獨拆出來,
再將其 use 進來使用 @@

對了~那個教學網址
他把 class 寫在一起只是為了方便學習
實務上是不會這樣做的
會有這需要是因為,在看教學說明時候,想到在laravel框架下不是像以前一樣我們直接require檔案,就可以用了,現在多了命名空間 跟use的方法,因為有些class只有幾條程式碼放一個檔案很浪費,所以想要知道說,如果一個檔案放多個class,在laravel格式下,要怎麼讓別的controller呼叫另一個controller底下的不同class
weiclin iT邦高手 4 級 ‧ 2018-05-30 23:59:09 檢舉
建議你研究一下 composer 的 autoload
抱歉有點不太理解您的意思,我在使用laravel5.2時候,原本就有用composer當做加載的工具,在composer.json 有在classmap加入一些自己定義的model,不過這些model也是一個php檔案,對應一個class。
不是很理解,如果我一個php檔案裡面有多個class ,在laravel composer的架構下要怎麼用呢@@?
weiclin iT邦高手 4 級 ‧ 2018-05-31 15:52:46 檢舉
你說你有用 composer 的 classmap, 那你有沒有加入你這有好幾個類別的檔案? 更新完程式以後有沒有執行過 composer update 去更新 class map?
抱歉我說明的可能不是很清楚
我的疑惑是在laravel底下,檔案只要放在App\Http\Controllers\ 這個目錄底下,就可以直接使用對應檔案的class。(應該不需要額外在classmap在寫一次檔名才對@@?)

現在的問題是我在App\Http\Controllers\SuperModuleFactoryController.php檔案,這個SuperModuleFactoryController.php裡面,寫了好幾個class。

其中第一個跟檔案名稱相同的class SuperModuleFactoryController 可以存取到,但是其他的class存取不到 EX: XPower (如上面程式碼)

所以有點疑惑在laravel5.2情況下 如果要在一個檔案放多個class ,要怎麼做才能取得同一個檔案內不同class去new
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 個回答

0
weiclin
iT邦高手 4 級 ‧ 2018-06-01 13:38:31
最佳解答

Laravel Controller 用的是 Composer 的 Autoloading,採用的是 PSR-4 標準。這點可以從 composer.json 中看到:

"autoload": {
    "classmap": [
        "database/seeds",
        "database/factories"
    ],
    "psr-4": {
        "App\\": "app/"
    }
}

所以你只要按照規定的地方放類別檔案,就可以自動載入類別。

但是你現在的作法完全不符合 PSR-4 標準,PSR-4 要求原始碼得要按照命名空間以及類別名稱去放置到對應的路徑與檔案名稱。也就是不管類別有多短,你都得獨立放一個檔案,而你並沒有打算照這個規定做。

要達成你的目的,Composer 的 Classmap 剛好符合需求。因為他不是按照路徑去找類別,而是直接建立類別與檔案的對應表去找到要讀取的檔案。我想你應該已經知道怎麼用,就不說明了。

結論就是你既不照 PSR-4 走,又不肯把你的檔案加入 Classmap,那當然人家找不到你的類別。

對的,就是想說有沒有類似的做法,可以達到這個需求,
其實一個類別一個檔案的做法是可以做得沒錯~感謝您。

我要發表回答

立即登入回答