An open API service indexing awesome lists of open source software.

https://github.com/inanepain/routing

HTTP Routing using attributes.
https://github.com/inanepain/routing

inane library php routing

Last synced: 9 months ago
JSON representation

HTTP Routing using attributes.

Awesome Lists containing this project

README

          

# Readme: Routing

> $Id$ ($Date$)

HTTP Routing using php **Attributes**.

NOTE: examples updated to use RouteMatch.

## Intro: Attributes

What is an **Attribute**? It's a class just like any other class only with the `Attribute` **Attribute**. So why are you treating it more like an `enum` or `Map` that can only hold a few values describing something? You don't do it with the classes you uses your custom attributes on! But I don't blame you, it all comes down to some pour choices in wording used by the documentation.

So how should I be think of **Attributes**? As classes naturally. Classes to object that get things done to be more exact. That `#[Route(name: 'home', path: '/')]` like might make more sense when you start looking at it like this: `$route = new Route('/', 'home');`. Here a fun experiment to try; remove the `Attribute` from `Route` then have the `Router` take an array of `Route` parameters as argument. Easy, wasn't it and you understand Attributes and with practice you spot many more classes you can use as such.

Hope that gets you thinking about **Attributes** in a new, more realistic manor that leads to you adding that `#[Attribute]` line to a good many more classes.

## Install

`composer require inanepain/routing`

## Usage

Quick overview showing the bits relating to the `Route` `Attribute` in two examples. Neither are complete, though the simple example would run with minimum fuss. Check the Appendix for the `.htaccess` file you will need to use with the `index.php` file.

## Example: Simple

Super simple example using **php** built in web server, `php -S localhost:8080 -t public index.php`.

**MainController.php:**

```php
class MainController {
...

#[Route(path: '/', name: 'home')]
public function home(): void {
...
echo <<addRoutes([MainController::class]);

if ($match = $router->match()) {
$controller = new $match->class();
$controller->{$match->method}($match->params);
} else {
throw new Exception('Request Error: Unmatched `file` or `route`!');
}

```

## Example: Application

Slightly more complex example.

#### The various pieces

**IndexController.php:**

```php
class IndexController extends AbstractController {
...

#[Route(path: '/', name: 'home')]
public function indexTask(): array {
...
}

...

#[Route(path: '/product/{product}', name: 'product', )]
public function productTask(): array {
...
}

...

#[Route(path: '/product/{product}/review/{id<\d+>}', name: 'product-review')]
public function reviewTask(): array {
...
}

...
}
```

**index.phtml (view template):**

```phtml
...
=$item['name_long']?>
...
```

**website (rendered view):**

```html
Mega Maid (Household Robot Helper)
```

#### Putting it all together

**Application.php:**

```php
class Application {
...

protected function initialise(): void {
...
$this->router = new Router([
IndexController::class,
...
WhoopsController::class,
...
]);
...
}

...

public function run(): void {
...
if ($match = $this->router->match()) {
$controller = new $match->class($match['params']);
$data = $controller->{$match['method']}();
...
// since 1.4.0: using the RouteMatch we can now easily get the template
$body = $this->renderer->render($match->template, $data);
...
}
...
}

...
}
```

## Appendix: .htaccess

You will also need to do some magic in your `.htaccess` file so that `index.php` handles all requests.

```appache
RewriteEngine On
# The following rule tells Apache that if the requested filename exists, simply serve it.
RewriteCond %{REQUEST_FILENAME} -s [OR]
RewriteCond %{REQUEST_FILENAME} -l [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^.*$ - [L]

# The following rewrites all other queries to index.php. The
# condition ensures that if you are using Apache aliases to do
# mass virtual hosting or installed the project in a subdirectory,
# the base path will be prepended to allow proper resolution of
# the index.php file; it will work in non-aliased environments
# as well, providing a safe, one-size fits all solution.
RewriteCond %{REQUEST_URI}::$1 ^(/.+)/(.*)::\2$
RewriteRule ^(.*) - [E=BASE:%1]
RewriteRule ^(.*)$ %{ENV:BASE}/index.php [L]

# Deprecated apache 2.2 syntax:
# Order Allow,Deny
# Allow from all
# Apache > 2.4 requires:
Require all granted

```