如果之前已经多次询问过这个问题,并且这在 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
等],并进一步简化您的代码。