Как использовать одну индексную функцию для двух разных контроллеров?

Я пытаюсь закодировать сайт социальной сети, такой как facebook, в Laravel 5.8. У меня в /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);
    }

ПрофильКонтроллер.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 в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
0
477
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Попробуйте вызвать метод index из другого controller:

use ProfileController;

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

Это уже пробовал. Это работает, но вызывать метод с одного контроллера на другой не следует. См. здесь: stackoverflow.com/questions/53209299/…

Umut Savas 10.06.2019 12:31

Хм.. Может быть, вам следует написать какой-нибудь вспомогательный класс, который будет делать ту же работу, что и ваш метод index здесь. А затем используйте метод index этого вспомогательного класса в этих двух conrollers

Guga Nemsitsveridze 10.06.2019 12:36
Ответ принят как подходящий

Я не знаю, почему мой ответ был удален здесь администратором .. Но вот снова. Просмотр композитора идеально подходит для этой ситуации. И вы можете зарегистрировать композитор в методе boot либо из AppServiceProvider, либо вы можете создать своего собственного поставщика услуг и зарегистрировать его в массиве config/app.phpproviders.

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);
}

Я пробую ваше решение, и я немного борюсь. Кажется, что функции компоновки недостаточно, мне также понадобится класс FriendListComposer. В этом классе я должен использовать репозиторий. Зачем мне создавать репозиторий? Я видел это в документации laravel здесь: laravel.com/docs/5.8/views#view-композиторы

Umut Savas 10.06.2019 13:03

Да, вам нужно создать класс композитора, я только что дал вам то, что должно быть в вашей функции компоновки. Репозиторий - это шаблон проектирования, вы можете, но не обязаны его использовать. Достаточно того, что я показал вам выше.

nakov 10.06.2019 13:05

И не забудьте заменить это 'App\Http\View\Composers\YourViewComposer' на путь к вашему файлу composer.

nakov 10.06.2019 13:07

Почему нельзя сделать два разных Routes, указывающих на одно и то же действие контроллера?

Нравиться,

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

В чем проблема с этим?

Потому что в каждом контроллере есть другие функции, которые не совпадают.

Umut Savas 10.06.2019 12:55

Вы видели, что я предлагаю? Я просто прошу вас сделать два разных маршрута, указывающих на одну и ту же индексную функцию.

Jay Pandya 10.06.2019 13:02

Другие вопросы по теме