Download the PHP package phossa2/route without Composer
On this page you can find all versions of the php package phossa2/route. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download phossa2/route
More information about phossa2/route
Files in phossa2/route
Package route
Short Description A fast and full-fleged routing library for PHP
License MIT
Homepage https://github.com/phossa2/route
Informations about the package route
phossa2/route [ABANDONED]
PLEASE USE phoole/route library instead
phossa2/route is a fast, full-fledged and feature-rich application level routing library for PHP.
It requires PHP 5.4, supports PHP 7.0+ and HHVM. It is compliant with PSR-1, PSR-2, PSR-3, PSR-4, and the proposed PSR-5.
Why another routing library ?
-
Super fast ! If it matters to you.
-
Support different routing strategies and combinations of these strategies.
-
Support different regular expression routing algorithms including the fastRoute algorithm
-
Concise route syntax. Route parameters and optional route segments.
-
Fast routing using path prefix checking in the collectors.
-
Multiple routing collections allowed.
-
Different level of default handlers.
-
Fine control of routing process by multiple level of extensions.
- Route and regex debugging.
Installation
Install via the composer
utility.
or add the following lines to your composer.json
Usage
Inject route definitions (pattern, handler, default values etc.) into the
dispatcher and then call either match()
or dispatch()
.
Or load routes from an array,
Route syntax
-
{Named} parameters
A route pattern syntax is used where
{foo}
specifies a named parameter or a placeholder with namefoo
and default regex pattern[^/]++
. In order to match more specific types, you may specify a custom regex pattern like{foo:[0-9]+}
.Predefined shortcuts can be used for placeholders as follows,
The previous pattern can be rewritten into,
-
[Optional] segments
Optional segments in the route pattern can be specified with
[]
as follows,where optional segments can be NESTED. Unlike other libraries, optional segments are not limited to the end of the pattern, as long as it is a valid pattern like the
[/{action:xd}]
in the example. -
Syntax limitations
- Parameter name MUST start with a character
Since
{2}
has special meanings in regex. Parameter name MUST start with a character. And the use of{}
inside/outside placeholders may cause confusion, thus is not recommended.[]
outside placeholder means OPTIONAL segment only
[]
can not be used outside placeholders as part of a regex pattern, IF YOU DO NEED to use them as part of the regex pattern, please include them INSIDE a placeholder.- Use of capturing groups
()
inside placeholders is not allowed
Capturing groups
()
can not be used inside placeholders. For example{user:(root|phossa)}
is not valid. Instead, you can use either use{user:root|phossa}
or{user:(?:root|phossa)}
. -
Default Values
Default values can be added to named parameters at the end in the form of
{action:xd=list}
. Default values have to be alphanumeric chars. For example,
Routes
-
Defining routes with dispatcher
You may define routes with dispatcher. But, it is actually defining routes with the first route collector in the dispatcher.
addGet()
andaddPost()
are wrappers ofaddRoute(RouteInterface)
. -
Routes can be grouped into different collections by using multiple collectors.
-
Collectors may set a path prefix using
setPathPrefix()
to indicate the exact URI path prefix is handling. Any non-matching prefix found will skip the collector entirely. -
Same route pattern
User can define same route pattern with different http methods.
Dispatching
-
Dispatch with dispatcher's
dispatch()
-
Match instead of dispatching
Instead of executing handler by default in
dispatch()
, more control by user if using thematch()
method
Handlers
-
Route handler
Route is defined with a handler for status
200 OK
only. -
Dispatcher and collectors can have multiple handlers corresponding to different result status.
If the result has no handler set (for example, no match found), then the collector's handler(same status code) will be retrieved. If still no luck, the dispatcher's handler (same status code) will be used if defined.
Dispatcher-level handlers,
Collector-level handlers,
When
addHandler()
with status set to0
will cause this handler be the default handler for other status. -
Handler resolving
Most of the time, matching route will return a handler like
[ 'ControllerName', 'actionName' ]
. Handler resolver can be used to resolving this pseudo handler into a real callable.Users may write their own handler resolver by implementing
Phossa2\Route\Interfaces\ResolverInterface
.
Extensions
Extensions are callables dealing with the matching result or other tasks before or after certain dispatching stages.
Extensions can be added to Dispatcher
, Collector
or even Route
.
-
Use of extensions
Extensions MUST return a boolean value to indicate wether to proceed with the dispatching process or not.
FALSE
means stop and returns to top level.Extensions can be either a
Phossa2\Event\EventableExtensionAbstract
and added withaddExtension()
oraddExt()
, or a callable with signature ofcallableName(Phossa2\Event\EventInterface $event): bool
which can be added as extension viaaddExt(callable, eventName, priority)
.Force authentication for any '/user/' prefixed URL,
-
Examples of extension
Validation of a parameter value on a route,
-
Extension events
Three types of events, dispatcher level, collector level and route level. List of all events in the order of execution.
-
Dispatcher::EVENT_BEFORE_MATCH
before matching starts -
Collector::EVENT_BEFORE_MATCH
before matching in a collector -
Collector::EVENT_AFTER_MATCH
after a successful match in the collector -
Dispatcher::EVENT_AFTER_MATCH
after a successful match at dispatcher level -
Dispatcher::EVENT_BEFORE_DISPATCH
after a sucessful match, before dispatching to any handler -
Route::EVENT_BEFORE_HANDLER
before executing handler(route's or collector's) for this route -
Route::EVENT_AFTER_HANDLER
after handler successfully executed -
Dispatcher::EVENT_AFTER_DISPATCH
back to dispatcher level, after handler executed successfully -
Dispatcher::EVENT_BEFORE_HANDLER
match failed or no handler found for the matching route, before execute dispatcher's default handler Dispatcher::EVENT_AFTER_HANDLER
after dispatcher's default handler executed
-
Debugging
Sometimes, you need to know what went wrong.
Where $logger
is a PSR-3 compatible logger implmenting the interface
Psr\Log\LoggerInterface
. The dispatcher will send logs of dispatching process
to the logger.
Routing strategies
There are a couple of URL based routing strategies supported in this library. Different strategy collectors can be combined together into one dispatcher.
-
Using parameter and value pairs for routing,
Parameters order can be arbitary, but have to appear in pairs. Advantage of this scheme is fast and web crawler friendly. If URL rewriting is used, the above can be written into the following,
Instead of using '/' as the parameter seperator, any URL valid characters except for the '?' and '&' can be used as a seperator.
This strategy is implemented in
Phossa2\Route\Collector\CollectorPPR
class. -
Query Parameter Routing (QPR)
The routing info is directly embedded in the URL query. The advantage of this scheme is fast and clear.
This strategy is implemented in
Phossa2\Route\Collector\CollectorQPR
class. -
Regular Expression Routing (RER)
Regular expression based routing is the default routing strategy for this library and implemented in
Phossa2\Route\Collector\Collector
class.
Regex matching algorithms
Different regex matching algorithms can be used with the RER collector.
-
This Group Count Based algorithm is implemented in
Phossa2\Route\Parser\ParserGcb
class and explained in detail in this article "Fast request routing using regular expressions".phossa-route uses this algorithm by default.
-
Standard algorithm
This algorithm is developed by phossa2/route and a little bit slower than the fastRoute GCB algorithm. It is implemented in
Phossa2\Route\Parser\ParserStd
class.Use this standard algorithm,
-
Comments on routing algorithms
- It does NOT matter that much as you may think.
If you are using routing library in your application, different algorithms may differ only 0.1 - 0.2ms for a single request, which seems meaningless for an application unless you are using it as a standalone router.
- If you DO care about routing speed
Use different routing strategy like Parameter Pairs Routing (PPR) which is much faster than the regex based routing. Also by carefully design your routes, you may achieve better results even if you are using a slower algorithm.
- Try network routing or server routing if you just CRAZY ABOUT THE SPEED.
Change log
Please see CHANGELOG from more information.
Testing
Contributing
Please see CONTRIBUTE for more information.
Dependencies
-
PHP >= 5.4.0
-
phossa2/event >= 2.1.5
- phossa2/shared >= 2.0.27
License
Appendix
-
- Worst-case matching
This benchmark matches the last route and unknown route. It generates a randomly prefixed and suffixed route in an attempt to thwart any optimization. 1,000 routes each with 8 arguments.
This benchmark consists of 14 tests. Each test is executed 1,000 times, the results pruned, and then averaged. Values that fall outside of 3 standard deviations of the mean are discarded.
"Parameter Pairs Routing (PPR)" is fastest and used as baseline.
Test Name Results Time + Interval Change Phossa PPR - unknown route (1000 routes) 998 0.0000724551 +0.0000000000 baseline Phossa PPR - last route (1000 routes) 993 0.0000925307 +0.0000200755 28% slower Symfony2 Dumped - unknown route (1000 routes) 998 0.0004353616 +0.0003629065 501% slower Phroute - last route (1000 routes) 999 0.0006205601 +0.0005481050 756% slower Phossa - unknown route (1000 routes) 998 0.0006903790 +0.0006179239 853% slower FastRoute - unknown route (1000 routes) 1,000 0.0006911943 +0.0006187392 854% slower FastRoute - last route (1000 routes) 999 0.0006962751 +0.0006238200 861% slower Phroute - unknown route (1000 routes) 998 0.0007134676 +0.0006410125 885% slower Symfony2 Dumped - last route (1000 routes) 993 0.0008066097 +0.0007341545 1013% slower Phossa - last route (1000 routes) 998 0.0009104498 +0.0008379947 1157% slower Symfony2 - unknown route (1000 routes) 989 0.0023998006 +0.0023273455 3212% slower Symfony2 - last route (1000 routes) 999 0.0025880890 +0.0025156339 3472% slower Aura v2 - last route (1000 routes) 981 0.0966411463 +0.0965686912 133281% slower Aura v2 - unknown route (1000 routes) 992 0.1070026719 +0.1069302168 147581% slower - First route matching
This benchmark tests how quickly each router can match the first route. 1,000 routes each with 8 arguments.
This benchmark consists of 7 tests. Each test is executed 1,000 times, the results pruned, and then averaged. Values that fall outside of 3 standard deviations of the mean are discarded.
Note Both FastRoute and Phroute implement a static route table, so they are fast at the first route matching (which is a static route)
Test Name Results Time + Interval Change FastRoute - first route 999 0.0000403543 +0.0000000000 baseline Phroute - first route 998 0.0000405911 +0.0000002368 1% slower Symfony2 Dumped - first route 999 0.0000590617 +0.0000187074 46% slower Phossa PPR - first route 977 0.0000678727 +0.0000275184 68% slower Phossa - first route 999 0.0000898475 +0.0000494932 123% slower Symfony2 - first route 998 0.0003983802 +0.0003580259 887% slower Aura v2 - first route 986 0.0004391784 +0.0003988241 988% slower -
URL rewrite
Setup URL rewriting to do routing with
index.php
- Apache
.htaccess
withmod_rewrite
engine is on
and in your
httpd.conf
file to enable using of.htaccess
- Nginx configration in
nginx.conf
- Apache
-
Base on the request informations, such as request device, source ip, request method etc., service provider may direct request to different hosts, servers, app modules or handlers.
- Network level routing
Common case, such as routing based on request's source ip, routes the request to a NEAREST server, this is common in content distribution network (CDN), and is done at network level.
- Web server routing
For performance reason, some of the simple routing can be done at web server level, such as using apache or ngix configs to do simple routing.
For example, if your server goes down for maintenance, you may replace the
.htaccess
file as follows,- App level routing
It solves much more complicated issues, and much more flexible.
Usually, routing is done at a single point
index.php
. All the requests are configured to be handled by this script first and routed to different routines.