如何在此 Laravel 应用程序中从 child 控制器覆盖 parent 控制器中的变量?

How can I overwrite a variable in the parent controller from a child controller in this Laravel application?

我正在开发一个包含用户和帖子的 Laravel 8 应用程序。

我有一个PostsController和一个FeaturedPostsController

我想在 FeaturedPostsController 中使用 PostsController 的逻辑,只向 child 控制器添加什么是 spaciffic它。为此,我有:

namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Post;

class PostsController extends Controller {
    public function index(Request $request){
        $viewData = $this->loadViewData();
        $viewData['page_title'] = "Posts";
        $viewData['posts'] = $this->posts($request);
        return view('posts', $viewData);
    }
}


namespace App\Http\Controllers;
use App\Http\Controllers\PostsController;
use Illuminate\Http\Request;

class FeaturedPostsController extends PostsController {
    public function __construct(Request $request) {
        parent::index($request);
    }
    
    public function index(Request $request){
        $viewData['page_title'] = "Featured posts";
    }
}

在死记硬背文件中:

Route::get('/posts', [PostsController::class, 'index'])->name('posts');
Route::get('/featured-posts', [FeaturedPostsController::class, 'index']);

posts 视图中我有:

<h1 class="page-title">{{ $page_title }}</h1>

目标

目标是在 /featured-posts 路线上将“精选帖子”作为页面标题页。

换句话说,我希望$viewData['page_title'] = "Posts"$viewData['page_title'] = "Featured posts"覆盖

问题

精选帖子页面上,我根本看不到posts视图,除非我注释掉FeaturedPostsController.

index 方法

我的错误在哪里?

1- 您不一定需要两个控制器。由于您有两条路线,您可以将它们指向 PostController 中的两个不同方法。此外,您不需要覆盖 index 方法,因为精选帖子会有不同的逻辑,但如果有,您可以将重复逻辑移到另一个方法中。但是,您肯定不需要在 FeaturedController class 中有构造函数,也不需要调用 parent 的索引 class.

建议方法 1:

class PostsController extends Controller {
 public function index(Request $request){
     $viewData = $this->viewData($request, "Posts");
     return view('posts', $viewData);
 }
 public function featuredPosts(Request $request){
     $viewData = $this->viewData($request, "Featured Posts");
     return view('posts', $viewData);
 }

 private function viewData($request, $pageTitle){
    $viewData = $this->loadViewData(); //maybe you can use this existing function?
    $viewData['page_title'] = $pageTitle;
    $viewData['posts'] = $this->posts($request);
    return $viewData;
 }
}

//in route
Route::get('/posts', [PostsController::class, 'index'])->name('posts');
Route::get('/featured-posts', [PostsController::class, 'featuredPosts']);

2- 如果您必须有两个控制器,您可以将标题分配给 PostController 中的 class 变量。所以,建议2:

class PostsController extends Controller {
 public $title = "Posts";
 public function index(Request $request){
    $viewData = $this->loadViewData();
    $viewData['page_title'] = $this->title;
    $viewData['posts'] = $this->posts($request);
    return view('posts', $viewData);
 }
}
class FeaturedPostsController extends PostsController {

 public function __construct(){
   $this->title = "Featured Posts";
 }
}

并且由于 PostsController 有一个 index 方法,如果没有逻辑变化,你不需要重新声明。