如果之前已經多次詢問過這個問題,而這在 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粉8074716042024-01-17 16:43:49
與其暗示具體的實現,不如暗示介面,你會得到更多的收益,例如:
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)
,例如:類型/健全性檢查,但該方法的其餘部分仍然相同。 您可以進一步連接此處引用的其他類別[例如:ControllerInterface
、RedirectInterface
等],並進一步簡化您的程式碼。