Create Core/Router and public/index then test the Router
This commit is contained in:
parent
6b5fe0eadf
commit
ffea1b6b6c
95
Core/Router.php
Normal file
95
Core/Router.php
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
<?php
|
||||||
|
namespace Core;
|
||||||
|
|
||||||
|
class Router
|
||||||
|
{
|
||||||
|
private
|
||||||
|
$routes = [],
|
||||||
|
$params = [];
|
||||||
|
|
||||||
|
public function getRoutes()
|
||||||
|
{
|
||||||
|
return $this->routes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getParams()
|
||||||
|
{
|
||||||
|
return $this->params;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function add($route, $params = [])
|
||||||
|
{
|
||||||
|
$route = preg_replace('/\//', '\/', $route);
|
||||||
|
$route = preg_replace('/\{([a-z]+)\}/', '(?P<\1>[a-z-]+)', $route);
|
||||||
|
$route = preg_replace('/\{([a-z]+):([^\}]+)\}/', '(?P<\1>\2)', $route);
|
||||||
|
$route = '/^'.$route.'$/';
|
||||||
|
|
||||||
|
if ($this->routes[$route] = $params) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function match($url)
|
||||||
|
{
|
||||||
|
$url = htmlspecialchars($url);
|
||||||
|
|
||||||
|
foreach ($this->routes as $route => $params) {
|
||||||
|
if (preg_match($route, $url, $matches)) {
|
||||||
|
foreach ($matches as $key => $match) {
|
||||||
|
if (is_string($key)) {
|
||||||
|
$params[$key] = $match;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($putParams = $this->params = $params) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function dispatch($url)
|
||||||
|
{
|
||||||
|
$url = $this->removeQueryStringVariable($url);
|
||||||
|
if ($this->match($url)) {
|
||||||
|
$controller = $this->params['controller'];
|
||||||
|
$controller = $this->convertToStudlyCaps($controller);
|
||||||
|
$controller = $this->getNamespace($controller);
|
||||||
|
|
||||||
|
if (class_exists($controller)) {
|
||||||
|
$object = new $controller();
|
||||||
|
|
||||||
|
$action = $this->params['action'];
|
||||||
|
$action = $this->convertToCamelCaps($action);
|
||||||
|
|
||||||
|
if (is_callable([$object, $action])) {
|
||||||
|
$object->$action();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function removeQueryStringVariable($url)
|
||||||
|
{
|
||||||
|
$parts = explode('&', $url);
|
||||||
|
return $url = $parts[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
private function convertToStudlyCaps($string)
|
||||||
|
{
|
||||||
|
return str_replace(' ', '', ucwords(str_replace('-', ' ', $string)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getNamespace($controller)
|
||||||
|
{
|
||||||
|
return $namespace = 'App\Controllers\\' . $controller;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function convertToCamelCaps($string)
|
||||||
|
{
|
||||||
|
return lcfirst($this->convertToStudlyCaps($string));
|
||||||
|
}
|
||||||
|
}
|
69
_tests/unit/RouterTest.php
Normal file
69
_tests/unit/RouterTest.php
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
<?php
|
||||||
|
namespace Core;
|
||||||
|
|
||||||
|
class RouterTest extends \PHPUnit\Framework\TestCase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Data provider for matchingRouteSuccess
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function routeProvider()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
[
|
||||||
|
'',
|
||||||
|
['controller' => 'Data', 'action' => 'index'],
|
||||||
|
'',
|
||||||
|
['controller' => 'Data', 'action' => 'index']
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'{controller}/{action}',
|
||||||
|
[],
|
||||||
|
'home/index',
|
||||||
|
['controller' => 'home', 'action' => 'index']
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'{controller}/{id:\d+}/{action}',
|
||||||
|
[],
|
||||||
|
'home/150/index',
|
||||||
|
['controller' => 'home', 'action' => 'index', 'id' => '150']
|
||||||
|
]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @test
|
||||||
|
* @dataProvider routeProvider
|
||||||
|
*/
|
||||||
|
public function matchingRouteSuccess($route, $params, $url, $expected_param)
|
||||||
|
{
|
||||||
|
$router = new Router();
|
||||||
|
|
||||||
|
$router->add($route, $params);
|
||||||
|
|
||||||
|
$this->assertTrue($router->match($url));
|
||||||
|
|
||||||
|
$this->assertEquals($expected_param, $router->getParams());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @test
|
||||||
|
* @dataProvider routeProvider
|
||||||
|
*/
|
||||||
|
public function dispatchingRouteSuccess($route, $params, $url)
|
||||||
|
{
|
||||||
|
// $url = 'home/index';
|
||||||
|
|
||||||
|
$router = new Router();
|
||||||
|
|
||||||
|
// $router->add('{controller}/{action}');
|
||||||
|
$router->add($route, $params);
|
||||||
|
|
||||||
|
$this->assertTrue($router->match($url));
|
||||||
|
|
||||||
|
$this->assertFalse($router->dispatch($url));
|
||||||
|
}
|
||||||
|
}
|
9
public/index.php
Normal file
9
public/index.php
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
<?php
|
||||||
|
$router = new Router();
|
||||||
|
|
||||||
|
$router->add('', ['controller' => 'Data', 'action' => 'index']);
|
||||||
|
$router->add('{controller}/{action}');
|
||||||
|
$router->add('{controller}/{id:\d+}/{action}');
|
||||||
|
|
||||||
|
$url = $_SERVER['QUERY_STRING'];
|
||||||
|
$router->dispatch($url);
|
Loading…
Reference in New Issue
Block a user