Code Monkey home page Code Monkey logo

phprouter's Introduction

Milad Rahimi

Website Twitter Go PHP

website linkedin instagram twitter stackoverflow facebook

phprouter's People

Contributors

adrianke avatar ayrtonvwf avatar felipeumpierre avatar miladrahimi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

phprouter's Issues

Can you nest middleware?

Can I make a middleware group, add some routes and then add another middleware group with other routes?

Get requestpath with variables

Would it be possible to have an $request->getUri() alternative that returns the base path.

Example:

  1. Request to the route /example/{var} with /example/123
  2. $request->getUri() returns /example/123

How would I get the original base (/example/{var})? Maybe $request->getBase()?

Middleware

Hello am following your guide on middleware i am creating a class for middleware rather than storing it in the routes web file and im getting this error

image

here is my code

image

am i missing something thanks again

Is it?

Is it? Possibility to add routes in the array or some list?

Middleware: inject header in next

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();

How to get JSON request data?

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.

QueryStringData Revisited

    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)

Any method not working

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...

Uncaught ReflectionException

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

Support for nested groups

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

Question Again

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

Middleware: choose dynamically next middleware

Would something like this be possible?

<?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
		}
    }
}

Error message when changing the instantiation method $router->dispatch gives error

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();

Container: Reflection failed

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

undefined index QUERY_STRING in Request.php on line 131

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.

Global Middleware

Is this the best way to add global middleware?

$router->group(['middleware' => SimpleMiddleware::class], function (Router $router) {
    // All routes go here
});

Question

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

Is it possible to pass parameters to middleware?

$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?

Changelog for release

Great, thank you for creating another release.

Do you have an changelog available?

Any Service Module/View Parameters

Definitely a great router. But lack of few common features like:

  • Is there is way to pass parameters to views
  • Yield Views
  • Add Partials

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

Route inline middleware

I think in previous versions you could do this $router->get($location, $controller, $middleware);?
How can I do this now?

اجرای route بعدی

سلام
من کدی نوشتم که ادرس های که اخرشون اسلش / داره رو به بدون اسلش هدایت کنه.
$router->get('(.*)', function ....

می خوام بعضی وقت ها که نیاز به هدایت نیست route بعدی اجرا بشه. و این رو نادیده بگیره.
ممنون میشم راهنمایی کنید.

PHP Version

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?

Use Template engine as service?

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.

About $url->make()

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

OPTIONS request type for CORS

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.

Linking Middleware to an external file

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

Exception

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

Group routes: Unable to access route where path is set as prefix root

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
});

Distinguish between HTTP 404 and 405

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.

How to pass the 404 pages as view

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));

ServerRequest in constructor

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;
    }
}

Feature request: Override method

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

Validate Inputs

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?

Obtaining QueryString Data

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

Update Docs: Requests

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(),
]

Question about obtaining list or urls from web file and the method type

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

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.