Ich habe zwei Controller SubmitPerformanceController
und PrintReportController
.
In habe PrintReportController
ich eine Methode aufgerufen getPrintReport
.
Wie kann ich in auf diese Methode zugreifen SubmitPerformanceController
?
Sie können wie folgt auf Ihre Controller-Methode zugreifen:
app('App\Http\Controllers\PrintReportController')->getPrintReport();
Dies wird funktionieren, ist jedoch in Bezug auf die Code-Organisation schlecht (denken Sie daran, den richtigen Namespace für Ihre zu verwenden PrintReportController
).
Sie können das erweitern PrintReportController
, SubmitPerformanceController
um diese Methode zu erben
class SubmitPerformanceController extends PrintReportController {
// ....
}
Dies erbt aber auch alle anderen Methoden von PrintReportController
.
Der beste Ansatz besteht darin, ein trait
(z. B. in app/Traits
) zu erstellen , die Logik dort zu implementieren und Ihre Controller anzuweisen, sie zu verwenden:
trait PrintReport {
public function getPrintReport() {
// .....
}
}
Sagen Sie Ihren Controllern, dass sie dieses Merkmal verwenden sollen:
class PrintReportController extends Controller {
use PrintReport;
}
class SubmitPerformanceController extends Controller {
use PrintReport;
}
Beide Lösungen SubmitPerformanceController
verfügen über eine getPrintReport
Methode, mit der Sie sie $this->getPrintReport();
innerhalb des Controllers oder direkt als Route aufrufen können (wenn Sie sie in der routes.php
) zugeordnet haben.
Sie können mehr über Züge lesen hier .
app('App\Http\Controllers\PrintReportController')->getPrintReport();
kann umgewandelt werdenapp(PrintReportController::class')->getPrintReport()
. Saubere Lösung für mich.Wenn Sie diese Methode in einem anderen Controller benötigen, müssen Sie sie abstrahieren und wiederverwendbar machen. Verschieben Sie diese Implementierung in eine Serviceklasse (ReportingService oder ähnliches) und fügen Sie sie in Ihre Controller ein.
Beispiel:
Machen Sie dasselbe für die anderen Controller, auf denen Sie diese Implementierung benötigen. Das Erreichen von Controller-Methoden von anderen Controllern ist ein Code-Geruch.
quelle
Services
Ordner, wenn das Projekt nicht groß ist, oder ein Feature-Ordner, der aufgerufen wird,Reporting
wenn es sich um ein größeres Projekt handelt undFolders By Feature
Struktur verwendet.Laravel 5 kompatible Methode
Hinweis: Dadurch wird die URL der Seite nicht aktualisiert.
Es ist besser, stattdessen die Route aufzurufen und den Controller anrufen zu lassen.
quelle
Das solltest du nicht. Es ist ein Anti-Muster. Wenn Sie in einem Controller eine Methode haben, auf die Sie in einem anderen Controller zugreifen müssen, ist dies ein Zeichen, das Sie neu faktorisieren müssen.
Ziehen Sie in Betracht, die Methode in eine Serviceklasse umzuwandeln, die Sie dann in mehreren Controllern instanziieren können. Wenn Sie also Druckberichte für mehrere Modelle anbieten müssen, können Sie Folgendes tun:
quelle
quelle
Zuallererst ist es böse, eine Methode eines Controllers von einem anderen Controller anzufordern. Dies wird viele versteckte Probleme in Laravels Lebenszyklus verursachen.
Dafür gibt es viele Lösungen. Sie können eine dieser verschiedenen Möglichkeiten auswählen.
Fall 1) Wenn Sie basierend auf Klassen anrufen möchten
Weg 1) Der einfache Weg
Auf diese Weise können Sie jedoch keine Parameter oder Authentifizierung hinzufügen .
Weg 2) Teilen Sie die Controller-Logik in Dienste.
Sie können damit beliebige Parameter und etwas hinzufügen . Die beste Lösung für Ihr Programmierleben. Sie können
Repository
stattdessen machenService
.Fall 2) Wenn Sie basierend auf Routen anrufen möchten
Weg 1) Verwenden Sie das
MakesHttpRequests
Merkmal, das beim Testen von Anwendungseinheiten verwendet wurde.Ich empfehle dies, wenn Sie einen besonderen Grund für die Erstellung dieses Proxys haben. Sie können beliebige Parameter und benutzerdefinierte Header verwenden . Auch dies wird eine interne Anfrage in Laravel sein. (Gefälschte HTTP-Anfrage) Weitere Details zur
call
Methode finden Sie hier .Dies ist jedoch auch keine „gute“ Lösung.
Weg 2) Verwenden Sie den guzzlehttp-Client
Dies ist die schrecklichste Lösung, die ich denke. Sie können auch beliebige Parameter und benutzerdefinierte Header verwenden . Dies würde jedoch eine externe zusätzliche http-Anfrage stellen. Der HTTP-Webserver muss also ausgeführt werden.
Schließlich verwende ich Weg 1 von Fall 2. Ich benötige Parameter und
quelle
quelle
Sie können eine statische Methode in PrintReportController verwenden und sie dann wie folgt vom SubmitPerformanceController aus aufrufen.
quelle
Dieser Ansatz funktioniert auch mit derselben Hierarchie von Controller-Dateien:
quelle
Hier emuliert das Merkmal die laufende Steuerung durch den Laravel-Router vollständig (einschließlich der Unterstützung von Middleware und der Abhängigkeitsinjektion). Nur mit Version 5.4 getestet
Fügen Sie es dann einfach Ihrer Klasse hinzu und führen Sie den Controller aus. Beachten Sie, dass die Abhängigkeitsinjektion Ihrer aktuellen Route zugewiesen wird.
quelle
app()->make(......)
gleich ist,app(......)
also kürzer.Sie können auf den Controller zugreifen, indem Sie ihn instanziieren und doAction aufrufen: (
use Illuminate\Support\Facades\App;
vor die Controller-Klassendeklaration setzen)Beachten Sie auch, dass Sie auf diese Weise keine der auf diesem Controller deklarierten Middlewares ausführen.
quelle
Späte Antwort, aber ich habe seit einiger Zeit danach gesucht. Dies ist jetzt auf sehr einfache Weise möglich.
Ohne Parameter
Mit Parametern
Dokumente: https://laravel.com/docs/5.6/responses#redirecting-controller-actions
In 5.0 war der gesamte Pfad erforderlich, jetzt ist es viel einfacher.
quelle