使用不同參數的 Laravel PHP 重寫方法
P粉863295057
P粉863295057 2024-01-16 17:22:48
0
1
462

如果之前已經多次詢問過這個問題,而這在 Laravel/PHP 中根本不可行,那麼我們深表歉意。

在我的 Laravel 應用程式中,我有一個 PostController,它使用 Laravel 豐富的命名約定。我還有一個 CommentController,它主要以各種方式複製 PostController,因此我決定 CommentController 應該擴展 PostController.

到目前為止唯一的區別是 store() 方法需要接受不同的 FormRequest 對象,因為它們有不同的驗證規則。因此,我重寫了store() 方法以期望CommentFormRequest 而不是PostFormRequest (兩者都擴展了FormRequest) .

這會引發一個錯誤,即重寫方法參數需要與基本方法相符。

這是預期的嗎?對於我想做的事情有一個合理的解決方案嗎?

從此處編輯

#我剛開始設計這個項目,用戶可以在其中建立貼文、問題、投票、廣告等,並且可以對其中任何內容發表評論。

所有這些都是Post類型。有些與其他模型有關係,例如Poll 可能與 PredefinedAnswer 模型有關係,而通用 Post 可能沒有關係。

有些可能需要不同的驗證邏輯,例如使用者可以決定是否允許對通用 Post 發表評論,但可能永遠不允許對 Advert 發表評論。

在我的資料庫中,我認為這些都可以儲存在 post 表中,但具有不同的 postable_type

在我的控制器中,我認為這些不同類型之間的大多數 CRUD 邏輯是相同的。在某些情況下,可能存在差異,可能需要重寫方法。

因此,在我的 PostController 中,我目前有一個非常簡單的 store() 方法:

class PostController extends Controller
{

    protected $postableType;


    public function __construct()
    {
        $this->postableType = PostType::GENERIC;
    }

    public function store(PostStoreRequest $request): RedirectResponse
    {
        $validated = $request->validated();

        $post = new Post();
        $post->message = $validated['message'];
        $post->user_id = $request->user()->id;

        $post->postable_type = $this->postableType;

        $post->save();

        return Redirect::route('feed');
    }
}

假設我的 AdvertController 有相同的邏輯,但有我所想的不同的驗證規則:

class AdvertController extends PostController
{

    protected $postableType;

    public function __construct()
    {
        $this->postableType = PostType::ADVERT;
    }

    public function store(AdvertStoreRequest $request): RedirectResponse
    {
        $validated = $request->validated();

        $advert= new Advert();
        $advert->message = $validated['message'];
        $advert->user_id = $request->user()->id;

        $advert->postable_type = $this->postableType;
        $advert->save();

        return Redirect::route('feed');
    }

P粉863295057
P粉863295057

全部回覆(1)
P粉807471604

與其暗示具體的實現,不如暗示介面,你會得到更多的收益,例如:

interface StoreRequestInterface {
  public function validated(): RedirectResponse;
  public function user();
  // etc
}

class PostStoreRequest implements StoreRequestInterface {/* ... */}
class AdvertStoreRequest  implements StoreRequestInterface {/* ... */}

abstract class Controller {
    protected $postableType;

    public function store(StoreRequestInterface $request): RedirectResponse
    {
        // ...
    }
}

class PostController extends Controller
{
    public function __construct()
    {
        $this->postableType = PostType::GENERIC;
    }
}

class AdvertController extends PostController
{
    public function __construct()
    {
        $this->postableType = PostType::ADVERT;
    }
}

這樣你:

  • 不必使用略有不同的參數提示來重新定義相同的方法體。
  • 在需要一些特殊處理的情況下可以呼叫 parent::store($request),例如:類型/健全性檢查,但該方法的其餘部分仍然相同。
  • 可以避免定義「上帝」類別的陷阱,大量應用程式類別必須追蹤其血統。您可以透過簡單地實現預期的介面來定義獨立的直接替換。

您可以進一步連接此處引用的其他類別[例如:ControllerInterfaceRedirectInterface等],並進一步簡化您的程式碼。

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板