Eu tenho dois controladores SubmitPerformanceController
e PrintReportController
.
No PrintReportController
eu tenho um método chamado getPrintReport
.
Como acessar esse método no SubmitPerformanceController
?
Você pode acessar seu método de controle como este:
app('App\Http\Controllers\PrintReportController')->getPrintReport();
Isso funcionará, mas é ruim em termos de organização do código (lembre-se de usar o espaço para nome certo para o seu PrintReportController
)
Você pode estender o PrintReportController
modo SubmitPerformanceController
herdará esse método
class SubmitPerformanceController extends PrintReportController {
// ....
}
Mas isso também herdará todos os outros métodos de PrintReportController
.
A melhor abordagem será criar trait
(por exemplo, in app/Traits
), implementar a lógica e dizer aos seus controladores para usá-la:
trait PrintReport {
public function getPrintReport() {
// .....
}
}
Diga a seus controladores para usar esta característica:
class PrintReportController extends Controller {
use PrintReport;
}
class SubmitPerformanceController extends Controller {
use PrintReport;
}
Ambas as soluções criam SubmitPerformanceController
um getPrintReport
método para que você possa chamá-lo $this->getPrintReport();
de dentro do controlador ou diretamente como uma rota (se você o mapeou no routes.php
)
Você pode ler mais sobre características aqui .
app('App\Http\Controllers\PrintReportController')->getPrintReport();
pode transformado paraapp(PrintReportController::class')->getPrintReport()
. Solução limpa para mim.Se você precisar desse método em outro controlador, isso significa que você deve abstraí-lo e torná-lo reutilizável. Mova essa implementação para uma classe de serviço (ReportingService ou algo semelhante) e injete-a em seus controladores.
Exemplo:
Faça o mesmo para os outros controladores em que você precisa dessa implementação. Chegar a métodos de controle de outros controladores é um cheiro de código.
fonte
Services
pasta se o projeto não for grande ou uma pasta de recurso chamadaReporting
se for um projeto maior e usarFolders By Feature
estrutura.Método compatível com Laravel 5
Nota: isso não atualizará o URL da página.
É melhor chamar a rota e deixá-la chamar o controlador.
fonte
Você não deveria. É um anti-padrão. Se você possui um método em um controlador que precisa acessar em outro controlador, isso é um sinal de que você precisa refatorar.
Considere re-fatorar o método em uma classe de serviço, que você pode instanciar em vários controladores. Portanto, se você precisar oferecer relatórios de impressão para vários modelos, faça algo assim:
fonte
fonte
Primeiro de tudo, solicitar um método de um controlador de outro controlador é MAU. Isso causará muitos problemas ocultos no ciclo de vida do Laravel.
De qualquer forma, existem muitas soluções para isso. Você pode selecionar uma dessas várias maneiras.
Caso 1) Se você deseja ligar com base em Classes
Caminho 1) O caminho simples
Mas você não pode adicionar nenhum parâmetro ou autenticação dessa maneira.
Caminho 2) Divida a lógica do controlador em serviços.
Você pode adicionar quaisquer parâmetros e algo com isso. A melhor solução para sua vida de programação. Você pode fazer em seu
Repository
lugarService
.Caso 2) Se você deseja ligar com base em rotas
Caminho 1) Use a
MakesHttpRequests
característica usada no Teste de Unidade de Aplicativo.Eu recomendo isso se você tiver um motivo especial para criar esse proxy, poderá usar quaisquer parâmetros e cabeçalhos personalizados . Além disso, este será um pedido interno no laravel. (Solicitação HTTP falsa) Você pode ver mais detalhes sobre o
call
método aqui .No entanto, essa também não é uma solução 'boa'.
Caminho 2) Use o cliente guzzlehttp
Esta é a solução mais terrível que eu acho. Você também pode usar parâmetros e cabeçalhos personalizados . Mas isso faria uma solicitação http extra externa. Portanto, o servidor Web HTTP deve estar em execução.
Finalmente, estou usando o Caminho 1 do Caso 2. Preciso de parâmetros e
fonte
fonte
Você pode usar um método estático no PrintReportController e chamá-lo no SubmitPerformanceController como este;
fonte
Essa abordagem também funciona com a mesma hierarquia de arquivos do Controller:
fonte
Aqui, a característica emula totalmente o controlador em execução pelo roteador laravel (incluindo suporte de middlewares e injeção de dependência). Testado apenas com a versão 5.4
Em seguida, basta adicioná-lo à sua classe e executar o controlador. Observe que a injeção de dependência será atribuída à sua rota atual.
fonte
app()->make(......)
é igual a,app(......)
portanto é mais curto.Você pode acessar o controlador instanciando-o e chamando doAction: (colocado
use Illuminate\Support\Facades\App;
antes da declaração da classe do controlador)Observe também que, ao fazer isso, você não executará nenhum dos middlewares declarados nesse controlador.
fonte
Resposta tardia, mas estou procurando isso há algum tempo. Agora isso é possível de uma maneira muito simples.
Sem parâmetros
Com parâmetros
Documentos: https://laravel.com/docs/5.6/responses#redirecting-controller-actions
De volta à versão 5.0, era necessário todo o caminho, agora é muito mais simples.
fonte