miladrahimi / phprouter Goto Github PK
View Code? Open in Web Editor NEWPhpRouter is a full-featured yet very fast HTTP URL router for PHP projects
License: MIT License
PhpRouter is a full-featured yet very fast HTTP URL router for PHP projects
License: MIT License
Hello hope this can get answered i have recently found your script and i think its amazing my issue is
when i place the middleware class within my routing files called web.php it runs the middleware script however if i do the following
$router->get('/users', 'Users@index',\App\Middleware\AuthMiddleware::class);
im getting this
Fatal error: Uncaught MiladRahimi\PhpRouter\Exceptions\InvalidMiddlewareException: Invalid middleware for route: {"name":null,"uri":"/users","method":"GET","controller":"App\Models\Users@index","middleware":["App\Middleware\AuthMiddleware"],
any help would be greatly appreciated
cant see it in your documentation but does the routing support using ?keyword=mike im trying to setup a search page for users and it doesnt seem to be picking up and results to the catch and gives my custom error page which is just page not found
my form path is : /admin/search and then as a get method throws up ?keyword=
my route at the moment as i thought it might work is /admin/search/?keywork={keyword}
tia
Refer to the code below, it seems that I have to call Router
class for each controller class and if I have two components in my system: Users and Product so I will have to replicate the below code for each class, is this true? How come I come up with a separate routes.php
file similar to Laravel by using your code?
use MiladRahimi\PhpRouter\Router;
class UsersController
{
function index()
{
return 'Class: UsersController & Method: index';
}
function handle()
{
return 'Class UsersController.';
}
}
$router = Router::create();
// Controller: Class=UsersController Method=index()
$router->get('/method', [UsersController::class, 'index']);
// Controller: Class=UsersController Method=handle()
$router->get('/class', UsersController::class);
$router->dispatch();
Would it be possible to have an $request->getUri()
alternative that returns the base path.
Example:
/example/{var}
with /example/123
$request->getUri()
returns /example/123
How would I get the original base (/example/{var}
)? Maybe $request->getBase()
?
This error pops up as there is no correct route, is it supposed to be this way?
Fatal error: Uncaught MiladRahimi\PhpRouter\Exceptions\RouteNotFoundException in I:\www\udemy\vendor\miladrahimi\phprouter\src\MiladRahimi\PhpRouter\Router.php:225 Stack trace: #0 I:\www\udemy\Public\index.php(50): MiladRahimi\PhpRouter\Router->dispatch() #1 {main} thrown in I:\www\udemy\vendor\miladrahimi\phprouter\src\MiladRahimi\PhpRouter\Router.php on line 225
Is this possible?
I get this error Fatal error: Uncaught ArgumentCountError: Too few arguments to function App\Controllers\Controller::__construct(), 0 passed ...
class Controller
{
protected $request;
/**
* Provide access for child classes
*
* @return void
*/
public function __construct(ServerRequest $request)
{
// Load request
// $this->request = $request;
}
}
$router->group(['middleware' => [AuthMiddleware::class]], function(Router $router) {
$router->get('/admin', function () {
return 'Admin API';
});
});
If I wanted to pass some parameters to AuthMiddleware, for example requiredGroup='admin', how could I do this?
Hello,
in html forms, most browsers can't handle DELETE, PUT or PATCH as request method.
Laravel has a feature that if there's a POST request with a hidden field named _method
, it overrides the real method.
this would require an additional check for $_POST["_method"]
I'd really appreciate if a feature like this could be implemented, so this logic doesn't have to be implemented in each controller
Thanks in advance,
Moritz
Using $request->getBody()
it is possible to get multipart form data, but how do I get data submitted in JSON format.
Note: I have also set the Content-Type: application/json
header.
How do I inject custom headers before calling $next?
use MiladRahimi\PhpRouter\Router;
use Psr\Http\Message\ServerRequestInterface;
use Laminas\Diactoros\Response\JsonResponse;
class AuthMiddleware
{
public function handle(ServerRequestInterface $request, Closure $next)
{
if ($request->getHeader('Authorization')) {
// HOW: add header "X-Hello-World: true"
return $next($request);
}
return new JsonResponse(['error' => 'Unauthorized!'], 401);
}
}
$router = Router::create();
// The middleware attribute takes an array of middleware, not a single one!
$router->group(['middleware' => [AuthMiddleware::class]], function(Router $router) {
$router->get('/admin', function () {
return 'Admin API';
});
});
$router->dispatch();
Hi So as of now i am still using your Router ive been out of it for a while however it seems that $keyword = $request->getQueryParams()['keyword']; this no longer works ansd gives Undefined array key "id" , i have changed the word keyword to id.
i have tried wrapping it in an iseset and nothing seems to be changing has something changed on yours or laminas side for this to not work anymore
Originally posted by @mbamber1986 in #35 (comment)
Hi again i was just wondering can i use $url->make("address.page",['usernarmae'=>$username]) go to a post variable or is this only set up to do get variables if so do you have anyway in your script that can pull / http Post requests
Currently the router throws a RouteNotFoundException
either if it doesn't find a route with a matching pattern or a matching method. My suggestion is to introduce either a property on RouteNotFoundException
or a new MethodMismatchException
to differentiate between a 404 Not Found
and a 405 Method Not Allowed
error.
Example:
<?php
use MiladRahimi\PhpRouter\Router;
use Laminas\Diactoros\Response\HtmlResponse;
use MiladRahimi\PhpRouter\Exceptions\RouteNotFoundException;
require __DIR__ . "/vendor/autoload.php";
$router = Router::create();
$router->get('/', function() use ($twig) {
return new HtmlResponse("<h1>Test</h1>\n");
});
try {
$router->dispatch();
} catch (RouteNotFoundException $ex) {
// We have no way to tell if it really is a 404 or 405 error...
$router->getPublisher()->publish(new HtmlResponse('Not found.', 404));
} catch (\Throwable $e) {
$router->getPublisher()->publish(new HtmlResponse('Internal error.', 500));
}
If we POST http://<DOMAIN>/
we get a HTTP/1.1 404 Not Found
, despite it actually resembeling a 405 error.
Proposal:
<?php
use MiladRahimi\PhpRouter\Router;
use Laminas\Diactoros\Response\HtmlResponse;
use MiladRahimi\PhpRouter\Exceptions\RouteNotFoundException;
use MiladRahimi\PhpRouter\Exceptions\MethodMismatchException;
require __DIR__ . "/vendor/autoload.php";
$router = Router::create();
$router->get('/', function() use ($twig) {
return new HtmlResponse("<h1>Test</h1>\n");
});
try {
$router->dispatch();
} catch (RouteNotFoundException $ex) {
$router->getPublisher()->publish(new HtmlResponse('Not found.', 404));
} catch (MethodMismatchException $ex) {
$router->getPublisher()->publish(new HtmlResponse('Cannot ' . htmlentities($_SERVER["REQUEST_METHOD"]) . " " . htmlentities($_SERVER["REQUEST_URI"]), 405));
} catch (\Throwable $e) {
$router->getPublisher()->publish(new HtmlResponse('Internal error.', 500));
}
If we now POST http://<DOMAIN>/
we correctly get a HTTP/1.1 405 Method Not Allowed
.
<?php
namespace App\Middleware;
use MiladRahimi\PhpRouter\Middleware;
class YesOrNoMiddleware extends Middleware
{
/**
* Choose next middleware based on var value.
*
* @param $request
* @param $next
*
* @return mixed
*/
public function handle($request, $next)
{
$var = true;
if ($var) {
return YesMiddleware::class;
} else {
return NoMiddleware::class
}
}
}
Is it possible?
try {
$router->dispatch();
} catch (RouteNotFoundException $e) {
// It's 404!
...
} catch (Throwable $e) {
// Log and report...
...
}
Tested with 5.1.4
Not sure what is causing the issue?
$router->group(['prefix' => '/admin'], function(Router $router) {
$router->get('/', [PageController::class, 'main']); // /admin throws MiladRahimi\PhpRouter\Exceptions\RouteNotFoundException
$router->get('/dashboard', [PageController::class, 'dashboard']); // /admin/dashboard works
});
I think in previous versions you could do this $router->get($location, $controller, $middleware);
?
How can I do this now?
Can I make a middleware group, add some routes and then add another middleware group with other routes?
سلام
من کدی نوشتم که ادرس های که اخرشون اسلش / داره رو به بدون اسلش هدایت کنه.
$router->get('(.*)', function ....
می خوام بعضی وقت ها که نیاز به هدایت نیست route بعدی اجرا بشه. و این رو نادیده بگیره.
ممنون میشم راهنمایی کنید.
Hi,
Is there a way to handle multi language?
Thanks
Is this the best way to add global middleware?
$router->group(['middleware' => SimpleMiddleware::class], function (Router $router) {
// All routes go here
});
You say that the package is compatible with PHP 7.4 but "laminas/laminas-diactoros": "^2.2", only works in PHP 8 >
Is there any way to work in PHP 7.4?
Definitely a great router. But lack of few common features like:
Also is there any feature like when we wish to pass any parameter but do not wish to show on url like Wordpress, where can we use
www.example.com/hello-world
insteadof
www.example.com/post/hello-world
Both url has same meaning. but we can omit the "post" parameter.
Also it will be very helpful for new users if you could show any example like how can we use database driven urls like wordpress.
Like :
hello-world
this-is-my-frst-post
etc.
Thank you
Rana
Hi,
Thanks for your amazing router, I use it in my project and it's really good!
But I am using Twig templating and I was thinking of a way to incorporate it to your router? Is there any way to add it as a service or something like this and in this way I could render my view in my controller?
Thanks for your work.
Would it be possible to add Laravel like input validation to this?
$this->validate($request, [
'title' => 'required|unique:posts|max:255',
'body' => 'required',
]);
How would you recommend doing this?
Is it? Possibility to add routes in the array or some list?
if route contains name of functions (like count, current etc) then i have that error
Fatal error: Uncaught ReflectionException: Cannot determine default value for internal functions in B:\OpenServer\domains\region.loc\vendor\miladrahimi\phpcontainer\src\Container.php:191 Stack trace: #0 B:\OpenServer\domains\region.loc\vendor\miladrahimi\phpcontainer\src\Container.php(191): ReflectionParameter->getDefaultValue() #1 B:\OpenServer\domains\region.loc\vendor\miladrahimi\phpcontainer\src\Container.php(164): MiladRahimi\PhpContainer\Container->resolveParameters() #2 B:\OpenServer\domains\region.loc\vendor\miladrahimi\phpcontainer\src\Container.php(110): MiladRahimi\PhpContainer\Container->call() #3 B:\OpenServer\domains\region.loc\vendor\miladrahimi\phpcontainer\src\Container.php(181): MiladRahimi\PhpContainer\Container->get() #4 B:\OpenServer\domains\region.loc\vendor\miladrahimi\phpcontainer\src\Container.php(164): MiladRahimi\PhpContainer\Container->resolveParameters() #5 B:\OpenServer\domains\region.loc\vendor\miladrahimi\phprouter\src\Dispatching\Caller.php(111): MiladRahimi\PhpContainer\Container->call() in B:\OpenServer\domains\region.loc\vendor\miladrahimi\phpcontainer\src\Container.php on line 166
example:
$router->get('/catalog/{name}', [CatalogController::class]);
and if go to localhost/catalog/count or localhost/catalog/current we get this error
Hey,
first of all thank you for this great library, it's really easy to work with.
The problem I encountered is that i can't nest groups properly:
$router->group(['prefix' => '/api', 'middleware' => $middleware], function (Router $router) {
// /api/test/ - unreachable
$router->group(['prefix' => '/test'], function (Router $router) {
$router->get('/', TestController::class);
}
// /api/api/ - reachable?!
$router->group(['prefix' => '/api'], function (Router $router) {
$router->get('/', TestController::class);
}
}
Tested with 3.0.4.
Is there any chance to support nested groups?
Cheers
dak4mi
Hi I was wondering is there a way in your code to stop it giving the scripts error message for example if i tell it i was int values only on the routing and i type string i get uncaught errors anyway i can formward this to a 404 page etc
If you have a get request with no querystring php will write a
Notice: Undefined index: QUERY_STRING in ..\vendor\miladrahimi\phprouter\src\MiladRahimi\PHPRouter\Request.php on line 131
I think that you should just add a default value if $_SERVER['QUERY_STRING'] does not exists.
Hello, i am wondering how pass the 404/500 error view after a catch response.
` $this->router->get('/', [HomeController::class,'show']);
$this->router->get('/404', function (View $view){
return $view->make('error.404',);
});$this->router->get('/500', function (View $view){
return $view->make('error.500');
});
try {
$this->router->dispatch();
}
catch (RouteNotFoundException $e) {
// It's 404!
$this->router->getPublisher()->publish(new HtmlResponse('Not Found', 404));
} catch (Throwable $e) {
// Log and report...
$this->router->getPublisher()->publish(new HtmlResponse('Internal error.', 500));
}`
Use $this->router->get('/404', function (View $view){ return $view->make('error.404',); })
Instead of $this->router->getPublisher()->publish(new HtmlResponse('Not Found', 404));
Currently $next($request) can't be intercepted, would be nice to be able to intercept and add header cookies to the response for example.
When trying to get container it fails with an reflection error
$this->router->getContainer()->singleton(\CQ\Config\Config::class, \CQ\Config\Config::class);
$this->container->has(\CQ\Config\Config::class); // Returns true
$this->container->get(\CQ\Config\Config::class); // Returns Reflection failed for CQ\Config\Config
Any method isn't working, give me "Methods must be set in" error
$router->any("/", function () {
echo 'Hello';
});
And i liked this library, very lite and perfect syntax.
Thanks...
I am looking at your examples and this one in question
$router = Router::create();
$router->get('/about', [AboutController::class, 'show'], 'about');
$router->get('/post/{id}', [PostController::class, 'show'], 'post');
$router->get('/links', function (Url $url) {
return new JsonResponse([
'about' => $url->make('about'), /* Result: /about /
'post1' => $url->make('post', ['id' => 1]), / Result: /post/1 /
'post2' => $url->make('post', ['id' => 2]) / Result: /post/2 */
]);
});
$router->dispatch();
when i follow the links /links i get the json information when i go /links/about or admin in my case it says page not found(my cyustom error handler)
how would i get this to redirect to the page in querstiuon also where the [id =>1] can this take variables
im sorry for the all the questions i really appreciate this script that you have done as its really amazing i would always recommend this
tia
Could you add $router->options('/', 'ExampleClass@options');
support?
CORS sends an Pre-Flight request using the OPTIONS
HTTP method.
The only way to catch this currently is using the $router->any()
method.
But this removes the ability to create an RESTful endpoint.
Because I can no longer create seperate routes for GET,POST,PUT,PATCH and DELETE.
Hello again my friend i have a question more of an issue, still loving your router heres the case of use
i am planning on building a roles, and rules system for my website and i want to base it on the url that it is currently at.
so in this case i i can pull all the array values from $url, and the current value if i was to use ROUTE anyway i need to know if there is anyway i can simply pull just the path and the type of method it is
so i can do soemthing like this in kmy admin panel
foreach($url as $path)
{
echo "Path : $path['path'] . "Add rules" . "Method type " . $path['method']
}
i litterly need to detect the url and the method post get etc
and the rest i will do via middleware
thanks in advance
https://github.com/miladrahimi/phprouter#requests
The request object has more methods accessible than shown in the docs.
Maybe you could add these:
[
'getAttribute' => $request->getAttribute('attributeName', 'attributeFallbackValue'),
'getAttributes' => $request->getAttributes(),
'getBody' => $request->getBody(),
'getContents' => $request->getBody()->getContents(),
'getMetadata' => $request->getBody()->getMetadata(),
'getSize' => $request->getBody()->getSize(),
'getCookieParams' => $request->getCookieParams(),
'getHeader' => $request->getHeader('host'),
'getHeaderLine' => $request->getHeaderLine('host'),
'getHeaders' => $request->getHeaders(),
'getMethod' => $request->getMethod(),
'getParsedBody' => $request->getParsedBody(),
'getProtocolVersion' => $request->getProtocolVersion(),
'getQueryParams' => $request->getQueryParams(),
'getRequestTarget' => $request->getRequestTarget(),
'getServerParams' => $request->getServerParams(),
'getUploadedFiles' => $request->getUploadedFiles(),
'getUri' => $request->getUri(),
'getAuthority' => $request->getUri()->getAuthority(),
'getFragment' => $request->getUri()->getFragment(),
'getHost' => $request->getUri()->getHost(),
'getPath' => $request->getUri()->getPath(),
'getPort' => $request->getUri()->getPort(),
'getQuery' => $request->getUri()->getQuery(),
'getScheme' => $request->getUri()->getScheme(),
'getUserInfo' => $request->getUri()->getUserInfo(),
]
Hi, i havent made an issue in a while however i have come across a wierd bug and hoping you can possibly assist or fix it.
the issue im having is i have created a custom requests class which works without the router in place however when i use the router and try and load my request class it doesnt display unless the root path is /
for example if i use /users/?username=martin : this displays nothing
where as if i make the url /?username=martin it outputs the value of $username
is this normal behaviour or does it need fixing.
As title says im gettin errors
i used your sample code and i get the following error
Fatal error: Uncaught MiladRahimi\PhpRouter\Exceptions\RouteNotFoundException in /var/www/html/vendor/miladrahimi/phprouter/src/Dispatching/Matcher.php:50 Stack trace: #0 /var/www/html/vendor/miladrahimi/phprouter/src/Router.php(145): MiladRahimi\PhpRouter\Dispatching\Matcher->find(Object(Laminas\Diactoros\ServerRequest), Array) #1 /var/www/html/Storage/configs/web.php(12): MiladRahimi\PhpRouter\Router->dispatch() #2 /var/www/html/Storage/configs/init.php(11): require_once('/var/www/html/S...') #3 /var/www/html/public_html/index.php(4): require_once('/var/www/html/S...') #4 {main} thrown in /var/www/html/vendor/miladrahimi/phprouter/src/Dispatching/Matcher.php on line 50
i am using this to see if it works
use MiladRahimi\PhpRouter\Router;
$router = Router::create();
$router->get('/', function () {
return 'This is homepage!';
});
$router->dispatch();
Great, thank you for creating another release.
Do you have an changelog available?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.