Tengo dos controladores SubmitPerformanceController
y PrintReportController
.
En PrintReportController
tengo un método llamado getPrintReport
.
¿Cómo acceder a este método en SubmitPerformanceController
?
Puede acceder a su método de controlador de esta manera:
app('App\Http\Controllers\PrintReportController')->getPrintReport();
Esto funcionará, pero es malo en términos de organización del código (recuerde usar el espacio de nombres correcto para su PrintReportController
)
Puede extender el PrintReportController
modo SubmitPerformanceController
heredará ese método
class SubmitPerformanceController extends PrintReportController {
// ....
}
Pero esto también heredará todos los demás métodos de PrintReportController
.
El mejor enfoque será crear un trait
(por ejemplo, en app/Traits
), implementar la lógica allí y decirles a sus controladores que lo usen:
trait PrintReport {
public function getPrintReport() {
// .....
}
}
Dígale a sus controladores que usen este rasgo:
class PrintReportController extends Controller {
use PrintReport;
}
class SubmitPerformanceController extends Controller {
use PrintReport;
}
Ambas soluciones SubmitPerformanceController
tienen un getPrintReport
método para que pueda llamarlo $this->getPrintReport();
desde dentro del controlador o directamente como una ruta (si lo asignó en elroutes.php
)
Puedes leer más sobre los rasgos aquí .
app('App\Http\Controllers\PrintReportController')->getPrintReport();
puede transformarse aapp(PrintReportController::class')->getPrintReport()
. Solución limpia para mi.Si necesita ese método en otro controlador, eso significa que debe abstraerlo y hacerlo reutilizable. Mueva esa implementación a una clase de servicio (ReportingService o algo similar) e inyéctela en sus controladores.
Ejemplo:
Haga lo mismo para los otros controladores donde necesita esa implementación. Alcanzar métodos de controlador desde otros controladores es un olor a código.
fuente
Services
carpeta si el proyecto no es grande o una carpeta de características llamadaReporting
si es un proyecto más grande y usaFolders By Feature
estructura.Método compatible con Laravel 5
Nota: esto no actualizará la URL de la página.
Es mejor llamar a la ruta y dejar que llame al controlador.
fuente
No deberías Es un antipatrón. Si tiene un método en un controlador al que necesita acceder en otro controlador, entonces esa es una señal que necesita re-factorizar.
Considere volver a factorizar el método en una clase de servicio, que luego puede instanciar en múltiples controladores. Entonces, si necesita ofrecer informes impresos para varios modelos, podría hacer algo como esto:
fuente
fuente
En primer lugar, solicitar un método de un controlador de otro controlador es MAL. Esto causará muchos problemas ocultos en el ciclo de vida de Laravel.
De todos modos, hay muchas soluciones para hacerlo. Puede seleccionar una de estas diversas formas.
Caso 1) Si desea llamar según las clases
Camino 1) El camino simple
Pero no puede agregar ningún parámetro o autenticación de esta manera.
Forma 2) Divida la lógica del controlador en servicios.
Puede agregar cualquier parámetro y algo con esto. La mejor solución para tu vida de programación. Puedes hacer en su
Repository
lugarService
.Caso 2) Si desea llamar por rutas
Forma 1) Use el
MakesHttpRequests
rasgo que utilizó en la Prueba de la Unidad de Aplicación.Recomiendo esto si tiene una razón especial para hacer este proxy, puede usar cualquier parámetro y encabezado personalizado . También será una solicitud interna en laravel. (Solicitud HTTP falsa) Puede ver más detalles para el
call
método aquí .Sin embargo, esta tampoco es una "buena" solución.
Manera 2) Usar el cliente guzzlehttp
Esta es la solución más terrible, creo. También puede usar cualquier parámetro y encabezados personalizados . Pero esto sería hacer una solicitud http externa adicional. Por lo tanto, el servidor web HTTP debe estar ejecutándose.
Finalmente estoy usando el camino 1 del caso 2. Necesito parámetros y
fuente
fuente
Puede usar un método estático en PrintReportController y luego llamarlo desde SubmitPerformanceController de esta manera;
fuente
Este enfoque también funciona con la misma jerarquía de archivos del controlador:
fuente
Aquí el rasgo emula completamente el controlador en ejecución mediante un enrutador laravel (incluido el soporte de middlewares y la inyección de dependencia). Probado solo con la versión 5.4
Luego solo agrégalo a tu clase y ejecuta el controlador. Tenga en cuenta que esa inyección de dependencia se asignará con su ruta actual.
fuente
app()->make(......)
es igual aapp(......)
lo que es más corto.Puede acceder al controlador instanciando y llamando a doAction: (poner
use Illuminate\Support\Facades\App;
antes de la declaración de clase del controlador)También tenga en cuenta que al hacer esto no ejecutará ninguno de los middlewares declarados en ese controlador.
fuente
Respuesta tardía, pero he estado buscando esto por algún tiempo. Esto ahora es posible de una manera muy simple.
Sin parámetros
Con parámetros
Documentos: https://laravel.com/docs/5.6/responses#redirecting-controller-actions
En 5.0, requería todo el camino, ahora es mucho más simple.
fuente