How can I find my route to GET/users in Symfony 4 - php

I get an error message, that no route is found for "GET/users":
Level: Error, Channel: request, Message: Uncaught PHP Exception
Symfony\Component\HttpKernel\Exception\NotFoundHttpException: "No
route found for "GET /users"" at
/Users/work/project/vendor/symfony/http-kernel/EventListener/RouterListener.php
line 139
But I actually set a route for "users", so I do not know how to solve this:
<?php
namespace App\Controller;
use DataTables\DataTablesInterface;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Request;
/**
*
* #Route("/users", name="users")
*
* #param Request $request
* #param DataTablesInterface $datatables
* #return JsonResponse
*/
class DataTableController extends Controller
{
const ID = 'users';
public function usersAction(Request $request, DataTablesInterface $datatables): JsonResponse
{
try {
// Tell the DataTables service to process the request,
// specifying ID of the required handler.
$results = $datatables->handle($request, 'users');
return $this->json($results);
}
catch (HttpException $e) {
// In fact the line below returns 400 HTTP status code.
// The message contains the error description.
return $this->json($e->getMessage(), $e->getStatusCode());
}
}
}

The annotation on top of the class only defines a prefix, not the actual route. The reason why becomes clear when you have multiple methods in the class. How can the router identify which one to call?
In other words you either have to move the annotation to the method or add another one like this to the action:
<?php declare(strict_types = 1);
namespace App\Controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
/**
* #Route("/users", name="users_")
*/
class UserController
{
/**
* #Route("", name="list")
*/
public function index()
{
return new Response('TODO: Add user list');
}
}
This will append the route definition from the action to the one on the class, like one would expect from a prefixed route.
If you want to know which routes Symfony recognizes you can use the debug command in the console:
php bin/console debug:router
or for a specific route:
php bin/console debug:router users
This is the output I get in my demo application:
php bin/console debug:router
------------ -------- -------- ------ --------
Name Method Scheme Host Path
------------ -------- -------- ------ --------
users_list ANY ANY ANY /users
------------ -------- -------- ------ --------
php bin/console debug:router users_list
+--------------+---------------------------------------------------------+
| Property | Value |
+--------------+---------------------------------------------------------+
| Route Name | users_list |
| Path | /users |
| Path Regex | #^/users$#sD |
| Host | ANY |
| Host Regex | |
| Scheme | ANY |
| Method | ANY |
| Requirements | NO CUSTOM |
| Class | Symfony\Component\Routing\Route |
| Defaults | _controller: App\Controller\UserController::index |
| Options | compiler_class: Symfony\Component\Routing\RouteCompiler |
+--------------+---------------------------------------------------------+
If you want to find out which URL-path matches to which route you can also use the following command:
php bin/console router:match "/users"
Optionally you can specify additional parameters like the method using CLI-option:
php bin/console router:match "/users" --method="POST" --scheme="https" --host="example.com"

Related

Symfony page not found (Symfony 3)

I am new in Symfony and i am working on existing project. I have created crud with doctrine:generate:crud, but application returns me 404 page not found. I was debugging it with debug:router and router:match and everything was okay.
Here is my controller
<?php
namespace AppBundle\Controller\Backend;
use AppBundle\Controller\BackendController;
use AppBundle\Entity\CsobApiUsers;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Component\HttpFoundation\Request;
/**
* CsobApiUsers controller.
*
* #Route("csobApiUsers")
*/
class CsobApiUsersController extends BackendController
{
/**
* Lists all csobApiUser entities.
*
* #Route("/", name="csobapiusers_index")
* #Method("GET")
*/
public function indexAction()
{
die(var_dump("x"));
$em = $this->getDoctrine()->getManager();
$csobApiUsers = $em->getRepository('AppBundle:CsobApiUsers')->findAll();
return $this->render('csobapiusers/index.html.twig', array(
'csobApiUsers' => $csobApiUsers,
));
}
Controller is as same as another controller that works correctly.
Here is my router:match
php bin/console router:match /backend/csobApiUsers/
[OK] Route "csobapiusers_index" matches
+--------------+---------------------------------------------------------+
| Property | Value |
+--------------+---------------------------------------------------------+
| Route Name | csobapiusers_index |
| Path | /backend/csobApiUsers/ |
| Path Regex | #^/backend/csobApiUsers/$#s |
| Host | ANY |
| Host Regex | |
| Scheme | ANY |
| Method | GET |
| Requirements | NO CUSTOM |
| Class | Symfony\Component\Routing\Route |
| Defaults | _controller: AppBundle:Backend\CsobApiUsers:index |
| Options | compiler_class: Symfony\Component\Routing\RouteCompiler |
+--------------+---------------------------------------------------------+
Here is debug:router for my controller
csobapiusers_index GET ANY ANY /backend/csobApiUsers/
csobapiusers_new GET|POST ANY ANY /backend/csobApiUsers/new
csobapiusers_show GET ANY ANY /backend/csobApiUsers/{id}
csobapiusers_edit GET|POST ANY ANY /backend/csobApiUsers/{id}/edit
csobapiusers_delete DELETE ANY ANY /backend/csobApiUsers/{id}
I calling https://my-address.com/backend/csobApiUsers/
Does anybody know where can be problem? Thanks
I think you're missing slash in controller route annotation, check here https://symfony.com/blog/new-in-symfony-3-4-prefix-all-controller-route-names
#Route("/csobApiUsers")
Did you try changing your indexAction() to index() instead ?

Symfony5 throws 404 in browser, but route is found in cli

Iam using react+symfony with webpack. Everything works with simple url eg. one slash in url ("/aboutus","/moodle") but when i try access route with multiple slashes("/admin/users") i get NotFoundResource Error. But with router:matchi will find it.
Server log:
|WARN | SERVER GET (404) /admin/users
|ERROR| REQUES Uncaught PHP Exception Symfony\Component\HttpKernel\Exception\NotFoundHttpException: "No route found for "GET /admin/users"" at /home/rtkpf/Programming/Niners/vendor/symfony/http-kernel/EventListener/RouterListener.php line 136
router:match /admin/users
(master) [1]> bin/console router:match /admin/users
[OK] Route "index" matches
+--------------+---------------------------------------------------------+
| Property | Value |
+--------------+---------------------------------------------------------+
| Route Name | index |
| Path | /{reactRouting} |
| Path Regex | {^/(?P<reactRouting>.+)?$}sDu |
| Host | ANY |
| Host Regex | |
| Scheme | ANY |
| Method | GET |
| Requirements | reactRouting: .+ |
| Class | Symfony\Component\Routing\Route |
| Defaults | _controller: App\Controller\UserController::index() |
| | reactRouting: NULL |
| Options | compiler_class: Symfony\Component\Routing\RouteCompiler |
| | utf8: true |
+--------------+---------------------------------------------------------+
Component:
class DefaultController extends AbstractController
{
/**
* #Route("/{reactRouting}", name="index", defaults={"reactRouting": null}, methods="GET", requirements={"reactRouting":".+"})
*/
public function index()
{
return $this->render('default/index.html.twig');
}
}
Has someone experienced this before? Where can be a mistake?
P.S.: Ia m using symfony server
It says App\Controller\UserController::index() in router:match while your controller shows DefaultController, is this a possible problem?
There could also be a priority issue, since 5.1 you can use priorities in routing (https://symfony.com/blog/new-in-symfony-5-1-route-annotations-priority), perhaps try adding priority=-10, in the router annotation to prioritize it lower (0 is default) or priority=10, in case you want to increase the priority somewhere else.

Symfony 3.4: Route Matches but no route found in url

I've just created a new controller as i usually do but, this time I got a problem with routing.
In profiler route matches but I can't reach them and get No route found for "GET /prezzi/listino"
Controller
<?php
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Routing\Annotation\Route;
class PricesController extends Controller {
/**
* #Route("/prezzi/listino", name="prezzi_listino")
*/
public function pricesListAction()
{
$list = $this->getDoctrine()->getRepository('AppBundle:Prices')->findAll();
return $this->render('prices/list.html.twig', [
'items' => $list
]);
}
}
Debug Router
$ php bin/console debug:router
----------------------------------- ---------- -------- ------ -------------------------------------------------------
Name Method Scheme Host Path
----------------------------------- ---------- -------- ------ -------------------------------------------------------
[..]
prezzi_listino ANY ANY ANY /prezzi/listino
[..]
----------------------------------- ---------- -------- ------ -------------------------------------------------------
Router Match
$ php bin/console router:match --method GET /prezzi/listino
[OK] Route "prezzi_listino" matches
+--------------+---------------------------------------------------------+
| Property | Value |
+--------------+---------------------------------------------------------+
| Route Name | prezzi_listino |
| Path | /prezzi/listino |
| Path Regex | #^/prezzi/listino$#sD |
| Host | ANY |
| Host Regex | |
| Scheme | ANY |
| Method | ANY |
| Requirements | NO CUSTOM |
| Class | Symfony\Component\Routing\Route |
| Defaults | _controller: AppBundle:Prices:pricesList |
| Options | compiler_class: Symfony\Component\Routing\RouteCompiler |
| Callable | AppBundle\Controller\PricesController::pricesListAction |
+--------------+---------------------------------------------------------+
Any ideas of where is the error? I think is a distraction cause I haven't see this problem.
Since I've tried to add the route in another controller that actually work, and doesn't seems to work, I've just come to the conclusion that I can't add any new route so it's meaning that is a cache error.
Running php bin/console cache:clear --env=dev --no-warmup solve the problem.

Laravel middleware not working

I have a middleware class :-
<?php
namespace App\Http\Middleware;
use Closure;
class isAdmin
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if(auth()->user()->getIsAdminAttribute()){
return $next($request);
}
abort(404);
}
}
In Kernel.php file:-
<?php
namespace App\Http;
use App\Http\Middleware\isAdmin;
protected $routeMiddleware = [
'isAdmin' => isAdmin::class,
];
In web.php route file:-
Route::get('users/list', 'UsersController#listUsers')->name('List_Users')->middleware('isAdmin');
I've tried to dump the
dd(auth()->user()->getIsAdminAttribute());
Nothing happen , like I am not assigning isAdmin middleware to that route at all.
You could check your routes and middleware assigned to them with this command :
php artisan route:list
Should look like :
+--------+----------+-------------+------------+-------------------------------------------------+--------------+
| Domain | Method | URI | Name | Action | Middleware |
+--------+----------+-------------+------------+-------------------------------------------------+--------------+
| | GET|HEAD | / | | Closure | web |
| | GET|HEAD | users/list | List_Users | App\Http\Controllers\UsersController#listUsers | web,isAdmin |
+--------+----------+-------------+------------+-------------------------------------------------+--------------+
Note the isAdmin in the middleware column.
i know it's late for you but maybe someone else will benefit from it,
i had the same issue, and after some debugging i found that the problem the middlware wasn't fired and appear in route:list due to the Route::get('post/{id}') even if i put this route after the route who was facing the issue Route::get('post/create'), i changed the show route from post to posts and the middleware get fired again.

Laravel Controller Dependency Injection

I'm trying to do dependency injection in Laravel to keep my controllers and models as slim as possible. The goal is to have repositories to handle the fetching of data attributed to certain models.
To this end I'm trying to follow the example from the documentation here and a popular Laravel boilerplate here
But I don't understand where the $user is coming from.
So looking at the boilerplate we have two files:
The ProfileController here
Excerpt below:
use App\Repositories\Frontend\Access\User\UserRepository;
/**
* Class ProfileController.
*/
class ProfileController extends Controller
{
/**
* #var UserRepository
*/
protected $user;
/**
* ProfileController constructor.
*
* #param UserRepository $user
*/
public function __construct(UserRepository $user)
{
$this->user = $user;
}
This looks a lot like the dependency injection mentioned in the docs, which is this:
class UserController extends Controller {
/**
* The user repository instance.
*/
protected $users;
/**
* Create a new controller instance.
*
* #param UserRepository $users
* #return void
*/
public function __construct(UserRepository $users)
{
$this->users = $users;
}
My problem is I don't understand where the $user is coming from.
In the UserRepository there is no $user defined as a parameter of the class itself. No where in the code is there any Auth::user() so I'm confused as to where the user instance is coming from.
In Laravel dependency injection is handled by the Container. I'm simplifying, but you can think of the container as a source of objects. If there is a singleton, its stored in the container. Otherwise the container knows how to instantiate objects for you. Whenever Laravel calls a method (like in a controller) or instantiates an object for you it will inspect the constructor and look for type hinted dependencies. If it sees a dependency it knows how to retrieve or create it will do so and pass it in for you.
So when Laravel instantiates the controller it looks at the constructor
public function __construct(UserRepository $user)
{
$this->user = $user;
}
The container uses Type Hinting to see that it requires a UserRepository so it will instantiate a new one for you. It also does this recursively. So when it creates a new UserRepository it looks at that constructor and sees that it requires a RoleRepository so it will instantiate that as well.
TLDR: The service container inspects your dependencies and will instantiate them for you.
Welcome to the dubious magic of Laravel. The basic idea with these dependency injections is that, depending on how you define your routes & controllers, Laravel can perform some automagical parsing of urls, identification of ids in those urls, and database fetching of objects.
My problem is I don't understand where the $user is coming from.
You should probably read the docs on the service container. You can also get a better idea of how your route definitions translate into parameter-laden urls with this command:
php artisan route:list
On one of my projects, this results in this output:
+--------+-----------+----------------------------+--------------------+-------------------------------------------------+--------------+
| Domain | Method | URI | Name | Action | Middleware |
+--------+-----------+----------------------------+--------------------+-------------------------------------------------+--------------+
| | GET|HEAD | / | | Closure | web |
| | GET|HEAD | api/user | | Closure | api,auth:api |
| | GET|HEAD | categories | categories.index | App\Http\Controllers\CategoryController#index | web |
| | POST | categories | categories.store | App\Http\Controllers\CategoryController#store | web |
| | GET|HEAD | categories/create | categories.create | App\Http\Controllers\CategoryController#create | web |
| | GET|HEAD | categories/{category} | categories.show | App\Http\Controllers\CategoryController#show | web |
| | PUT|PATCH | categories/{category} | categories.update | App\Http\Controllers\CategoryController#update | web |
| | DELETE | categories/{category} | categories.destroy | App\Http\Controllers\CategoryController#destroy | web |
| | GET|HEAD | categories/{category}/edit | categories.edit | App\Http\Controllers\CategoryController#edit | web |
| | GET|HEAD | products | products.index | App\Http\Controllers\ProductController#index | web |
| | POST | products | products.store | App\Http\Controllers\ProductController#store | web |
| | GET|HEAD | products/create | products.create | App\Http\Controllers\ProductController#create | web |
| | GET|HEAD | products/{product} | products.show | App\Http\Controllers\ProductController#show | web |
| | PUT|PATCH | products/{product} | products.update | App\Http\Controllers\ProductController#update | web |
| | DELETE | products/{product} | products.destroy | App\Http\Controllers\ProductController#destroy | web |
| | GET|HEAD | products/{product}/edit | products.edit | App\Http\Controllers\ProductController#edit | web |
+--------+-----------+----------------------------+--------------------+-------------------------------------------------+--------------+
And all those routes and their uris and parameters are generated from only a couple of very simple routes definitions. Here's my routes file:
$ cat routes/web.php
<?php
Route::get('/', function () {
return view('master');
});
Route::resource('products', 'ProductController');
Route::resource('categories', 'CategoryController');
If you look at the list of URIs in the routes output above, you'll see parameters named in the URIs like {category} and {product}. These correspond to ids/keys in the URI which Laravel identifies. Laravel is "smart" enough to look at my Controller files, see the type-hinting in the various functions and detect that my function is expecting a depedency to be injected.
For instance, the Category controller's show method looks like this:
public function show(Tree $category)
{
var_dump($category);
}
My controller might seem a little unusual because I'm type hinting that I want an object of type Tree, but Laravel is smart enough to recognize that I do in fact want a Model of type Tree, so it parses out the url and finds the id in it and automatically fetches the record in my db table trees with id matching the {category} fragment of my url and injects that into my function.
Note that I had some trouble when I tried to name the input parameter $tree instead of $category. That other thread may help answer your question a bit too.
The bottom line is that Laravel does a lot of "magic" to hopefully free you up from the tedious of manually defining your own code and queries to retrieve the objects you want.

Categories