Skip to content

An automatic routing without using routing table #118

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
logs
!logs/.keep
vendor

composer.lock
12 changes: 12 additions & 0 deletions App/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,18 @@ class Config
*/
const DB_PASSWORD = 'your-database-password';

/**
* Default controller value
* @var string
*/
const DEFAULT_CONTROLLER = 'Home';

/**
* Default action value
* @var string
*/
const DEFAULT_ACTION = 'index';

/**
* Show or hide error messages on screen
* @var boolean
Expand Down
2 changes: 1 addition & 1 deletion App/Controllers/Home.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class Home extends \Core\Controller
*
* @return void
*/
public function indexAction()
public function indexAction($params)
{
View::renderTemplate('Home/index.html');
}
Expand Down
60 changes: 59 additions & 1 deletion Core/Router.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,13 @@
*/
class Router
{

/**
* Request URI index constants
*/
const CONTROLLER_URI_INDEX = 1;
const ACTION_URI_INDEX = 2;
const ID_URI_INDEX = 3;

/**
* Associative array of routes (the routing table)
* @var array
Expand Down Expand Up @@ -131,6 +137,58 @@ public function dispatch($url)
}
}

/**
* Dispatch the request URI, creating the controller object
* and running the action method with id and other params.
* An automatic routing without using routing table
*
* Request URI format:
* [/controller[/action[/id]]][?param1=value1[&param2=value2...]]
*
* @param string|null $requestUri The request URI
*
* @return void
*/
public function dispatchRequest($requestUri = null)
{
// Parse request URI
$requestUri = $requestUri ?? $_SERVER['REQUEST_URI'];
[$request, $query] = strpos($requestUri, '?') === false ? [$requestUri, ''] : explode('?', $requestUri);
$request = strpos($request, '/') === false ? [] : explode('/', $request);
$queryParams = [];
parse_str($query, $queryParams);

// Dispatch request
$controller = !empty($request[self::CONTROLLER_URI_INDEX]) ? $request[self::CONTROLLER_URI_INDEX] : \App\Config::DEFAULT_CONTROLLER;
$controller = $this->convertToStudlyCaps($controller);
$this->params['controller'] = $controller;
$controller = $this->getNamespace() . $controller;
$action = !empty($request[self::ACTION_URI_INDEX]) ? $request[self::ACTION_URI_INDEX] : \App\Config::DEFAULT_ACTION;
$action = $this->convertToCamelCase($action);
$this->params['action'] = $action;
if ($id = $request[self::ID_URI_INDEX] ?? null) {
if (array_key_exists('id', $queryParams)) {
$queryParams['id'] = $id;
} else {
$queryParams = ['id' => $id] + $queryParams;
}
}
$this->params['id'] = $id;
$this->params['queryParams'] = $queryParams;

if (class_exists($controller)) {
$controller_object = new $controller($this->params);

if (preg_match('/action$/i', $action) == 0) {
$controller_object->$action($queryParams);
} else {
throw new \Exception("Method $action in controller $controller cannot be called directly - remove the Action suffix to call this method");
}
} else {
throw new \Exception("Controller class $controller not found");
}
}

/**
* Convert the string with hyphens to StudlyCaps,
* e.g. post-authors => PostAuthors
Expand Down
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ You can also specify a namespace for the controller:
$router->add('admin/{controller}/{action}', ['namespace' => 'Admin']);
```

Another way - an automatic routing without using routing table:
```php
$router->dispatchRequest($_SERVER['REQUEST_URI']); die;
```

## Controllers

Controllers respond to user actions (clicking on a link, submitting a form etc.). Controllers are classes that extend the [Core\Controller](Core/Controller.php) class.
Expand Down
5 changes: 4 additions & 1 deletion public/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,11 @@
*/
$router = new Core\Router();

// Uncomment the next line for an automatic routing without using routing table
//$router->dispatchRequest($_SERVER['REQUEST_URI']); die;

// Add the routes
$router->add('', ['controller' => 'Home', 'action' => 'index']);
$router->add('{controller}/{action}');

$router->dispatch($_SERVER['QUERY_STRING']);
$router->dispatch($_SERVER['QUERY_STRING'] ?? '');
7 changes: 0 additions & 7 deletions vendor/autoload.php

This file was deleted.

Loading