如果之前已经多次询问过这个问题,并且这在 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');
} Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
与其暗示具体的实现,不如暗示接口,你会得到更多的收益,例如:
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等],并进一步简化您的代码。