dev-buildtest
dev-buildtest
The Development Requires
by Mike Timms
dev-core-framework
dev-core-framework
The Development Requires
by Mike Timms
An experiment in writing a [small] RESTful framework for PHP. Makes use of the Burlap container for dependencies., (*1)
Named for the Planck time and length - the smallest measurements of time and length, respectively, that have any meaning., (*2)
NB: This is an ongoing project in its infancy, so expect much to be missing and much not to work ;), (*3)
This is an open source effort, and although its only a pet project of mine contributions are welcome! So fork and PR away :), (*4)
Feel free to add issues to leave suggestions and comments., (*5)
Take a look at LICENSE.md for more info (MIT)., (*6)
Planck is designed to be minimal and to help you quickly get working with RESTful responses., (*7)
The routing of RESTful requests is still the responsibility of your router and routes, but with the default Junction router that's easy to achieve., (*8)
All your application code will live in the /src/App
folder, with the exception of any routes, services or listeners you define., (*9)
Planck expects only two things in order to get you up and running:, (*10)
For example:, (*11)
// config/routes.php $router->add('GET /hello', function () { return [ 'controller' => 'Hello', 'action' => 'hello', 'vars' => func_get_args(), ]; });
// src/App/Controller/HelloController.php namespace Planck\App\Controller; class HelloController { public function hello() { return 'hello, world'; } }
Controllers in Planck are the entry and exit points for your business logic. Since we're concerned with RESTful applications we expect a controller to return some data, which can be done in two ways:, (*12)
$this->set('property_name', 'property_value');
inline within a controller, to set return values in a peacemeal fashionreturn ['property' => 'value', 'result' => 1234];
Planck's default behaviour is to return responses as JSON, but this can be changed by using one of the other built in ResponseFormatters
, or rolling your own., (*13)
Planck includes a RESTController
which you can extend to get access to some useful convenience methods - for example:, (*14)
$this->ok()
- set the response code as 200$this->created()
- set the response code as 201 $this->created(false)
- set the response code as 202 (accepted, will be created later)$this->blank()
- set the response code as 204 (no message body)$this->unchanged()
- set the response code as 304 (removes message body)The RESTController also includes a handy afterAction
callback which will sniff your request method and try to set approriate codes and body content for you. For example:, (*15)
If these don't suit your needs you can currently override the behavior by having an empty (or custom) afterAction
function in your controller. In future I aim to make the process more flexible., (*16)
If there's an error condition in your app (the record with $id doesn't exist for example), throw an exception to capture this and return an appropriate HTTP coded message, all wrapped up in a nice neat package., (*17)
Planck includes exceptions for the most common RESTful error responses, covering:, (*18)
Errors are returned in a neat package, handled by defining a service with the name errorResponseBuilder
, which returns a function accepting a single argument - the exception that has been thrown., (*19)
The default package is an array with items for "error" and "code", showing the exception message and HTTP status code respectively. You can change this to be whatever you want simply be redefining the service., (*20)
Planck is agnostic about the container you use, though it does expect it to implement the Container Interoperability Interface., (*21)
By default Planck uses the lightweight Burlap container., (*22)
A controller's dependencies are drawn from the container, and can be injected by simply referencing container services as the arguments for the controller's init()
function, e.g.:, (*23)
// controller code // inject the service labelled as "db" into this function public function init($db) { $this->db = $db; } // more controller code
Planck implements a simple event system, which you can extend with your own app specific events., (*24)
Event listeners are defined in the config/listeners.php
file, and by convention Planck expects these to live in the src/App/Listener
folder, but this is up to you., (*25)
//src/App/Listener/ExampleListener.php <?php namespace Planck\App\Listener; use Planck\Core\Event\IEventListener; class ExampleListener implements IEventListener { public function attachedEvents() { return [ 'controller.beforeAction' => 'doSomething', // core Planck event, triggered before the controller function resolved from the route is called 'app.hello' => 'hello', // app specific event ]; } public function doSomething($controller) { $controller->set([ 'externalListener' => true, ]); } public function hello($controller, $name) { $controller->set([ "hello.message" => "Why hello $name! How you doin'? :)" ]); } }
// src/App/Controller/HelloController use Planck\Core\Event\Event; public function hello($name) { echo "Hello, $name"; // emit an event and pass the current object plus some more stuff. you can pass anything you want here Event::emit('app.welcomed', [$this, $moreData]); } // more goodness
An ever changing list of things to look at! :), (*26)