I'm not sure if this is what you're asking for, but if I were you I'd use something well-tested and from a well-known framework. Even if you have customly coded PHP application, no frameworks used, you can install only the component(s) you need via composer
.
Let's take symfony/ruoting
as an example. In order to take HTTP request context it will also require symfony/http-foundation
. In order to install both, proceed to your project root directory, install composer if it's not yet installed and then
composer require symfony/http-foundation
composer require symfony/routing
then you need to include vendor/autoload.php
in your project entry point and that's it, you can use symfony/routing
now. The good thing is that since symfony2 is a component framework, you don't need to install all the framework, just those two packages.
Now if you create a test file with the following code:
require_once(realpath(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'autoload.php'));
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Matcher\UrlMatcher;
use Symfony\Component\Routing\RequestContext;
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
$routes = new RouteCollection();
$route = new Route('/{endpoint}/{subendpoint}/{subsubendpoint}');
$route->setDefaults(array(
'endpoint' => null,
'subendpoint' => null,
'subsubendpoint' => null,
));
$routes->add('main', $route);
$context = new RequestContext();
// this is optional and can be done without a Request instance
$context->fromRequest(Request::createFromGlobals());
$matcher = new UrlMatcher($routes, $context);
$parameters = $matcher->match('/hello');
var_dump($parameters);
$parameters = $matcher->match('/');
var_dump($parameters);
$parameters = $matcher->match('/campaigns/24566/pictures');
var_dump($parameters);
$parameters = $matcher->match('/campaigns/24566/users');
var_dump($parameters);
$parameters = $matcher->match('/users/23445646');
var_dump($parameters);
$parameters = $matcher->match('/users/campaigns');
var_dump($parameters);
and try to open it, you will see something like:
array(4) {
["endpoint"]=>
string(5) "hello"
["subendpoint"]=>
NULL
["subsubendpoint"]=>
NULL
["_route"]=>
string(4) "main"
}
array(4) {
["endpoint"]=>
NULL
["subendpoint"]=>
NULL
["subsubendpoint"]=>
NULL
["_route"]=>
string(4) "main"
}
array(4) {
["endpoint"]=>
string(9) "campaigns"
["subendpoint"]=>
string(5) "24566"
["subsubendpoint"]=>
string(8) "pictures"
["_route"]=>
string(4) "main"
}
array(4) {
["endpoint"]=>
string(9) "campaigns"
["subendpoint"]=>
string(5) "24566"
["subsubendpoint"]=>
string(5) "users"
["_route"]=>
string(4) "main"
}
array(4) {
["endpoint"]=>
string(5) "users"
["subendpoint"]=>
string(8) "23445646"
["subsubendpoint"]=>
NULL
["_route"]=>
string(4) "main"
}
array(4) {
["endpoint"]=>
string(5) "users"
["subendpoint"]=>
string(9) "campaigns"
["subsubendpoint"]=>
NULL
["_route"]=>
string(4) "main"
}
If you then integrate it into your REST API entry script, you can pass $_SERVER['REQUEST_URI']
into ::match()
method and then something like:
if(!empty($parameters['subsubendpoint'])) {
//instantiate the "leaf"-subclass
} elseif(!empty($parameters['subendpoint'])) {
//instantiate the "middle"-subclass
} else {
//instantiate the "main" class
}