【问题标题】:How to use one index function for two different controllers?如何为两个不同的控制器使用一个索引功能?
【发布时间】:2019-06-10 10:18:31
【问题描述】:

我正在尝试在 Laravel 5.8 中编写像 facebook 这样的社交媒体网站。 我在/home/profile 中有相同的朋友列表,但有两个不同的控制器(HomeController 和 ProfileController)。我不想为两个不同的控制器复制粘贴相同的代码。我该如何解决它,所以我只需要使用我的代码一次?

HomeController.php

public function index()
    {
        $friends = [];
        $friendsID = Person_has_person::select('person2')->where('person1', Auth::user()->id)->get();
        foreach ($friendsID as $friendID)
            $friends[] = User::find($friendID->person2);

        return view('home')->with('friends', $friends);
    }

ProfileController.php

public function index()
    {
        $friends = [];
        $friendsID = Person_has_person::select('person2')->where('person1', Auth::user()->id)->get();
        foreach ($friendsID as $friendID)
            $friends[] = User::find($friendID->person2);

        return view('profile')->with('friends', $friends);
    }

在我的 web.php 文件中,我有我的路线。

Route::get('/home', 'HomeController@index');
Route::get('/profile', 'ProfileController@index');

在我的模板中,我用它来向我的朋友们展示。

@if(count($friends) > 0)
    @foreach($friends as $friend)
        <ul>
            <li>
                <a href="/profile/{{$friend->id}}">{{$friend->firstname . ' ' . $friend->lastname}}</a>
                <a class="text-danger"
                   href="/removeFriend/{{Auth::user()->id . '/' . $friend->id}}">[unfriend]</a>
            </li>
        </ul>
    @endforeach
@else
    <p>No friends available</p>
@endif

如您所见,我在两个不同的控制器中有相同的代码。这不是一个好的解决方案。你能给我一个建议,我该如何编码,所以我只有一次?

【问题讨论】:

    标签: php laravel controller


    【解决方案1】:

    我不知道为什么我的答案在这里被管理员删除了。但又来了。 View Composer 非常适合这种情况。您可以在AppServiceProviderboot 方法中注册作曲家,也可以创建自己的服务提供者并将其注册到config/app.php providers 数组中。

    View::composer(
        ['home', 'profile'],
        'App\Http\View\Composers\YourViewComposer'
    );
    

    和 compose 方法共享相同的代码:

    /**
    * Bind data to the view.
    *
    * @param  View  $view
    * @return void
    */
    public function compose(View $view)
    {
        $friends = [];
        $friendsID = Person_has_person::select('person2')->where('person1', Auth::user()->id)->get();
    
        foreach ($friendsID as $friendID)
        {
           $friends[] = User::find($friendID->person2);
        }
    
        $view->with('friends', $friends);
    }
    

    【讨论】:

    • 我正在尝试您的解决方案,但我有点挣扎。似乎 compose 功能还不够,我还需要一个 FriendListComposer 类。在这个类中,我必须使用存储库。为什么我必须创建一个存储库?我在这里的 laravel 文档中看到了这一点:laravel.com/docs/5.8/views#view-composers
    • 是的,你需要创建一个作曲家类,我只是给了你在你的 compose 函数中需要的东西。存储库是一种设计模式,你可以但你不必使用它。我在上面向您展示的就足够了。
    • 别忘了将'App\Http\View\Composers\YourViewComposer' 替换为您的作曲家的路径。
    【解决方案2】:

    尝试从其他controller调用index方法:

    use ProfileController;
    
    class HomeController {
        public function index()
        {
             ProfileController::index();
        }
    }
    

    【讨论】:

    • 已经试过了。它确实有效,但不应使用从一个控制器到另一个控制器调用方法。见这里:stackoverflow.com/questions/53209299/…
    • 嗯.. 可能你应该写一些帮助类,它会做同样的工作,你的index 方法在这里做什么。然后在这两个conrollers中使用这个助手类的index方法
    【解决方案3】:

    为什么不能让两个不同的Routes 指向同一个Controller 动作?

    喜欢,

    Route::get('/home', 'ProfileController@index'); Route::get('/profile', 'ProfileController@index');

    这有什么问题?

    【讨论】:

    • 因为每个控制器中还有其他功能不一样。
    • 你看到我的建议了吗?我只是要求你创建两条不同的路线指向同一个索引函数。
    猜你喜欢
    • 2011-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-13
    • 2020-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多