Filenames

Handlers can be a String representing the filename of another PHP file, route parameters will be available at the global $params variable:

index.php

Route\get('/hello/{name}','pages/home.php');

pages/home.php

echo'Hello '.$params['name'];

Resources

CRUD routes can be auto-magically be defined for convenience using the Rails and Laravel pattern.

Given this resource declaration:

Route\resource('/users','api/users');

Siler will look for files at path/to/files matching the HTTP URI according to the table below:

HTTP Verb

URI

File

GET

/users

/api/users/index.php

GET

/users/create

/api/users/create.php

POST

/users

/api/users/store.php

GET

/users/{id}

/api/users/show.php

GET

/users/{id}/edit

/api/users/edit.php

PUT

/users/{id}

/api/users/update.php

DELETE

/users/{id}

/api/users/destroy.php

The file structure should look like:

index.php

/api

└── /users

├─ index.php

├─ create.php

├─ store.php

├─ show.php

├─ edit.php

├─ update.php

└─ destroy.php

Files

You can also let Siler create the routes recursively looking for files at a base path. Then the files names will be used to define the method and the path.

Route\files('controllers');

Siler will interpret periods (.) as slashes and also maintain folder structure at HTTP path:

Filename

Method

Path

index.get.php

GET

/

index.post.php

POST

/

foo.get.php

GET

/foo

bar/index.get.php

GET

/bar

foo.bar.get.php

GET

/foo/bar

foo/bar.get.php

GET

/foo/bar

foo/bar/index.get.php

GET

/foo/bar

Since { and } are valid chars in a filename, route parameters should work as well, but you can define required parameters prefixing with $ and optional parameters using @:

Filename

Method

Path

foo.{slug}.get.php

GET

/foo/{slug}

foo.$slug.get.php

GET

/foo/{slug}

foo.@slug.get.php

GET

/foo/{slug?}

Any method is valid, it is guessed based on the penultimate "token":

Filename

Method

Path

foo.options.php

OPTIONS

/foo

foo.x-custom.php

X-CUSTOM

/foo

Note on handlers

When creating routes, be careful about early and lazy evaluations.

Route\get('/foo',[newFooController(),'index']);

The example above is early, which means it will call FooController constructor for each request even if it's not a request to /foo.

To make it lazy you can wrap inside a Closure:

Route\get('/foo',function(){

$controller=newFooController();

return$controller->index();

});

Now FooController is called only when there is a match for route /foo.
One downside is that now you have to explicitly manage path parameters, on the other hand is a best practice to do so.
It is a good time to validate parameters, convert plain string parameters to meaningful types on your domain or resolve dependencies.

Route\get('/users/{id}',function(array$params)use($ioc){

if(!preg_match('/[0-9]+/',$params['id']){

$controller=$ioc->resolve(ErrorController::class);

return$controller->invalid('IDs must be numbers');

}

$controller=$ioc->resolve(UsersController::class);

return$controller->show($params['id']);

});

Request

Body

You can grab the raw request body using:

useSiler\Http\Request;

​

$body= Request\raw();

Parse as URL-encoded data using:

$params= Request\params();

Parse as JSON using:

$resource= Request\json();

$_GET and $_POST superglobals

Or get data from a Form and from the Query String using:

$input= Request\post('input');

$searchTerm= Request\get('q');

Calling them without arguments will tell Siler to return all the values as an array:

$data= Request\post();

$queryString= Request\get();

You can also pass a default value if the key isn't present in the GET or POST super-globals: