Я разрабатываю приложение Laravel 8, и мне нужно создать XML-файлы с данными из базы данных. Поэтому я сначала создал контроллер и метод для генерации XML-файла и протестировал его на правильность работы. Теперь мне нужно вызвать метод exportXML для ExportFileController внутри контроллера PrenotazioneSpedizioneController. Прочитав документацию Laravel и здесь, в Stack, я увидел, что вы можете вызвать метод, подобный этому \App::call('App\Http\Controllers\ExportFileController@exportXML');.

Я тестировал его без параметров, и он работает как положено. Проблема, с которой я столкнулся сейчас, заключается в следующем: можно ли передать параметр методу exportXML, который я вызываю:

\App::call('App\Http\Controllers\ExportFileController@exportXML');?

Я думал что-то вроде \App::call('App\Http\Controllers\ExportFileController@exportXML')->with('racc', $racc);.

Буду признателен за любые предложения или советы.

  • PrenotazioneSpedizioneController
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\CodiciPrenotazione;
use App\Models\Raccomandata;
use App\Models\Prenotazioni;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class PrenotazioniSpedizioniController extends Controller
{

    // dashboard delle prenotazioni
    public function index()
    {
        $page_title = 'Resoconto prenotazioni';
        $page_description = 'Pagina di resoconto delle prenotazioni effettuate';
        $logo = config('dz.public.logo');
        $logoText = config('dz.public.logo_text');
        $active = "active";
        $action = 'dashboard_4';

        $total = CodiciPrenotazione::count();
        
        $free = CodiciPrenotazione::where('stato', 0)->count();

        $codici = CodiciPrenotazione::select('*')->get()->toArray();

        return view('prenotazioni.dashboard', compact('page_title', 'page_description', 'logo', 'logoText', 'active', 'action'))
        ->with('total', $total)
        ->with('free', $free)
        ->with('codici', $codici);
    }

    // GESTIONE DELLE SPEDIZIONI
    public function gestisciSpedizione(Request $request){
       
        try{

            set_time_limit(-1);

            //devo recuperare le raccomandate dal DB con isGenerated = 0 e per data e lotto

            //prendo la data odierna, devo spedire quelle con data precedente.
            $date = date('Y-m-d');
            //recupero le raccomandate
            $racc = Raccomandata::select('*')
            ->where([
                ['isGenerated', '=', '0'], //non generate
                ['created_at', '>', $date.' 00:00:00'], //la data di creazione deve essere precedente la data odierna
                ['idCliente', '=', '1'], //selezioniamo le raccomandate solo per il cliente
            ])
            ->get();
            //raggruppiamo per idCommessa e cronologico
            $racc = $racc->groupBy(['idCommessa', 'cronologico'])->toArray();
            

            //passo alla creazione dei file
            //richiamo la procedura per generare i file .xml
            return \App::call('App\Http\Controllers\ExportFileController@exportXML'); // here i want pass $racc variable.





            //loggiamo l'evento e redirectiamo con il messaggio di success dell'operazione
            Log::channel('custom_log')->info('L\'utente '.Auth::user().' ha prenotato con successo la spedizione numero: '.$request->input('codice_prenotazione').' FILE :');

            return redirect()->back()->with('success', 'Prenotazione della spedizione effettuata con successo');

        }catch(\Exception $e){
            Log::channel('custom_log')->info('L\'utente '.Auth::user().' non è riuscito a prenotare la spedizione COD:'.$request->input('codice_prenotazione').' ERRORE:'.$e);

            return redirect()->back()->with('error', 'Non è stato possibile prenotare la spedizione numero: '.$request->input('codice_prenotazione'));
        }
    }
0
64Bit1990 17 Сен 2021 в 13:48

3 ответа

Лучший ответ

Вы не должны вызывать контроллеры внутри других контроллеров.

Вы столкнулись с этой проблемой, потому что вы помещаете бизнес-логику в свои контроллеры (и это хорошо известная плохая практика).

Решение состоит в том, чтобы использовать другой класс, называемый классом обслуживания, в который вы помещаете логику. Затем вы вызываете этот класс там, где вам нужно (в вашем случае, в PrenotazioniSpedizioniController и ExportFileController).

Это быстрый пример:

Создайте файл app\Services\ExportService.php:

class ExportService {
    public function exportXML($arguments)
    {
        //something
    }
}

Тогда в ваших контроллерах:

use App\Http\Controllers\ExportFileController;

class PrenotazioniSpedizioniController extends Controller
{
     public function yourMethod(Request $request){
         app(ExportService::class)->exportXML($arguments);
     }
}

Таким образом вы сохраните чистые контроллеры и получите более тестируемый код.

Имейте в виду, что это минимальный пример решения вашей проблемы, и я могу только посоветовать вам углубиться в архитектуру проекта и шаблоны проектирования.

4
toyi 17 Сен 2021 в 11:26

Попробуйте что-то вроде этого

\App::call('App\Http\Controllers\ExportFileController@exportXML',['racc'=>$racc])
0
omar esmaeel 17 Сен 2021 в 11:16

Вы не должны вызывать контроллеры внутри других контроллеров.

Вы столкнулись с этой проблемой, потому что вы помещаете бизнес-логику в свои контроллеры (и это хорошо известная плохая практика).

Решение состоит в том, чтобы использовать другой класс, называемый классом обслуживания, в который вы помещаете логику. Затем вы вызываете этот класс там, где вам нужно (в вашем случае, в PrenotazioniSpedizioniController и ExportFileController).

Это быстрый пример:

You should not call controllers inside another controllers.

You are facing this problem because you are putting business logic inside your controllers (and it is a well known bad practice).

The solution is to use another class, called a service class, where you put the logic. You then call this class where you need to (in your case, in PrenotazioniSpedizioniController and ExportFileController).

This is a quick example:

Create the file app\Services\ExportService.php:

class ExportService {
    public function exportXML($arguments)
    {
        //something
    }
}
Then, in your controllers:

use App\Http\Controllers\ExportFileController;

class PrenotazioniSpedizioniController extends Controller
{
     public function yourMethod(Request $request){
         app(ExportService::class)->exportXML($arguments);
     }
}
This way you keep clean controllers and have a more testable code.

Keep in mind this is a minimal example to solve your problem and I can only advise you to dig further on project architecture and design patterns.

Таким образом вы сохраните чистые контроллеры и получите более тестируемый код.

Имейте в виду, что это минимальный пример решения вашей проблемы, и я могу только посоветовать вам углубиться в архитектуру проекта и шаблоны проектирования.

0
Fahad Ahmad 17 Сен 2021 в 11:51