I have a controller prefixed with a namespace. How can I execute that controller? Without necessarily make a Request object on the fly. What should I do?
I have found this solution on the net:
$app = app();
$controller = $app->make(ucfirst("MyNamespace")."\\".ucfirst($controller_name)."Controller");
return $controller->callAction($controller, $parameters = array());
I get an error that says `callAction()`'s first parameter must be of type `Container`.
How should I execute a controller in Laravel from inside another controller?
Related
I want to use route localization like said here https://codeigniter.com/user_guide/outgoing/localization.html#in-routes
So I need to add route rule like:
$routes->get('{locale}/books', 'App\Books::index');
But I want to make this rule for all controllers - not to specify rules for all controllers. So I added the rule:
$routes->add('{locale}/(:segment)(:any)', '$1::$2');
I have controller Login with method index(). When I go to mydomain.com/Login method index() is loaded successfull. But when I go to mydomain.com/en/Login (as I expect to use my route) I got 404 Error with message - "Controller or its method is not found: \App\Controllers$1::index". But locale is defined and set correctly.
If I change my route to $routes->add('{locale}/(:segment)(:any)', 'Login::$2'); then mydomain.com/en/Login is loaded successfull as I want. But in this way I have to set routes for every controller and I want to set one route to work with all controllers.
Is it possible to set route with setting of dynamic controller name?
I'm not sure it is possible directly, but here is a workaround:
$routes->add('{locale}/(:segment)/(:any)', 'Rerouter::reroute/$1/$2');
Then, your Rerouter classlooks like this:
<?php namespace App\Controllers;
class Rerouter extends BaseController
{
public function reroute($controllerName, ...$data)
{
$className = str_replace('-', '', ucwords($controllerName)); // This changes 'some-controller' into 'SomeController'.
$controller = new $className();
if (0 == count($data))
{
return $controller->index(); // replace with your default method
}
$method = array_shift($data);
return $controller->{$method}(...$data);
}
}
For example, /en/user/show/john-doe will call the controller User::show('john-doe').
I am working in Laravel 5.2 and i want to access URL segments in my controller. I am using
echo Request::segment(2);
but nothing is print. How can i get values from url in controller.
In laravel 5.2 you can do it this way..
echo request()->segment(2);
request() is one of the several helper functions provided in Laravel 5.2. It returns the current request object thus you don't need use statement for the facade on the top of your class.
In Laravel 7, I am using this to get segments
public function my_function(Request $request )
{
// By using this, we can get the second segment in route
// Example: example.com/hh/kk
$segment = $request->segment(2);
// By using this we will get "kk"
}
In Laravel, we can get route name from current URL via this:
Route::currentRouteName()
But, how can we get the route name from a specific given URL?
Thank you.
A very easy way to do it Laravel 5.2
app('router')->getRoutes()->match(app('request')->create('/qqq/posts/68/u1'))->getName()
It outputs my Route name like this slug.posts.show
Update: For method like POST, PUT or DELETE you can do like this
app('router')->getRoutes()->match(app('request')->create('/qqq/posts/68/u1', 'POST'))->getName()//reference https://github.com/symfony/http-foundation/blob/master/Request.php#L309
Also when you run app('router')->getRoutes()->match(app('request')->create('/qqq/posts/68/u1', 'POST')) this will return Illuminate\Routing\Route instance where you can call multiple useful public methods like getAction, getValidators etc. Check the source https://github.com/illuminate/routing/blob/master/Route.php for more details.
None of the solutions above worked for me.
This is the correct way to match a route with the URI:
$url = 'url-to-match/some-parameter';
$route = collect(\Route::getRoutes())->first(function($route) use($url){
return $route->matches(request()->create($url));
});
The other solutions perform bindings to the container and can screw up your routes...
I don't think this can be done with out-of-the-box Laravel. Also remember that not all routes in Laravel are named, so you probably want to retrieve the route object, not the route name.
One possible solution would be to extend the default \Iluminate\Routing\Router class and add a public method to your custom class that uses the protected Router::findRoute(Request $request) method.
A simplified example:
class MyRouter extends \Illuminate\Routing\Router {
public function resolveRouteFromUrl($url) {
return $this->findRoute(\Illuminate\Http\Request::create($url));
}
}
This should return the route that matches the URL you specified, but I haven't actually tested this.
Note that if you want this new custom router to replace the built-in one, you will likely have to also create a new ServiceProvider to register your new class into the IoC container instead of the default one.
You could adapt the ServiceProvider in the code below to your needs:
https://github.com/jasonlewis/enhanced-router
Otherwise if you just want to manually instantiate your custom router in your code as needed, you'd have to do something like:
$myRouter = new MyRouter(new \Illuminate\Events\Dispatcher());
$route = $myRouter->resolveRouteFromUrl('/your/url/here');
It can be done without extending the default \Iluminate\Routing\Router class.
Route::dispatchToRoute(Request::create('/your/url/here'));
$route = Route::currentRouteName();
If you call Route::currentRouteName() after dispatchToRoute call, it will return current route name of dispatched request.
In Laravel, we can get route name from current URL via this:
Route::currentRouteName()
But, how can we get the route name from a specific given URL?
Thank you.
A very easy way to do it Laravel 5.2
app('router')->getRoutes()->match(app('request')->create('/qqq/posts/68/u1'))->getName()
It outputs my Route name like this slug.posts.show
Update: For method like POST, PUT or DELETE you can do like this
app('router')->getRoutes()->match(app('request')->create('/qqq/posts/68/u1', 'POST'))->getName()//reference https://github.com/symfony/http-foundation/blob/master/Request.php#L309
Also when you run app('router')->getRoutes()->match(app('request')->create('/qqq/posts/68/u1', 'POST')) this will return Illuminate\Routing\Route instance where you can call multiple useful public methods like getAction, getValidators etc. Check the source https://github.com/illuminate/routing/blob/master/Route.php for more details.
None of the solutions above worked for me.
This is the correct way to match a route with the URI:
$url = 'url-to-match/some-parameter';
$route = collect(\Route::getRoutes())->first(function($route) use($url){
return $route->matches(request()->create($url));
});
The other solutions perform bindings to the container and can screw up your routes...
I don't think this can be done with out-of-the-box Laravel. Also remember that not all routes in Laravel are named, so you probably want to retrieve the route object, not the route name.
One possible solution would be to extend the default \Iluminate\Routing\Router class and add a public method to your custom class that uses the protected Router::findRoute(Request $request) method.
A simplified example:
class MyRouter extends \Illuminate\Routing\Router {
public function resolveRouteFromUrl($url) {
return $this->findRoute(\Illuminate\Http\Request::create($url));
}
}
This should return the route that matches the URL you specified, but I haven't actually tested this.
Note that if you want this new custom router to replace the built-in one, you will likely have to also create a new ServiceProvider to register your new class into the IoC container instead of the default one.
You could adapt the ServiceProvider in the code below to your needs:
https://github.com/jasonlewis/enhanced-router
Otherwise if you just want to manually instantiate your custom router in your code as needed, you'd have to do something like:
$myRouter = new MyRouter(new \Illuminate\Events\Dispatcher());
$route = $myRouter->resolveRouteFromUrl('/your/url/here');
It can be done without extending the default \Iluminate\Routing\Router class.
Route::dispatchToRoute(Request::create('/your/url/here'));
$route = Route::currentRouteName();
If you call Route::currentRouteName() after dispatchToRoute call, it will return current route name of dispatched request.
If I have a route in Laravel
Route::post('/user/{user}/project/{project}/git-add', 'GitController#stageFiles');
How do I access the user and project variables from the controller function being called?
Also, do I need to specify that I am returning a JSON object in the routes file, or is that all taken care of in the controller?
For following route:
Route::post('/user/{user}/project/{project}/git-add', 'GitController#stageFiles');
You need to create stageFiles method in GitController and from your stageFiles method:
public function stageFiles($user, $project)
{
// $user && $project both are available in this method as parameters
}
This is how you access them:
$user = Input::get('user');
$project = Input::get('project');
And Laravel will understand your json just fine.