dev-master
9999999-devA tiny single class RAD PSR-7 web application "framework"
MIT
The Requires
The Development Requires
by Andrew Breksa
A tiny single class RAD PSR-7 web application "framework"
A tiny single class RAD PSR-7 web application "framework", (*1)
Unicorn is essentially a wrapper around zendframework/zend-diactoros and a couple of The PHP League packages: league/event, league/container, and league/route that provides support for the entire application lifecycle., (*3)
Still in it's infancy, Unicorn was born from my frustrations of wanting a framework to handle the plumbing for me, but not force a specific architecture or style, as applications tend to get very domain specific (as they should be)., (*4)
Application
object adds itself to the service container so your class constructor dependencies are auto-wired if created via the container. I would include support for middleware by default, but I feel this is not always required by a PSR-7 application, and therefore outside of the Unicorn mission statement)Unicorn attempts to do only the minimum, providing a service container, a router, a few event hooks for the various stages of the application lifecycle, and a PSR-7 implementation. And if you'd like, consider it an anti-framework framework. You might have to write some code... ;), (*5)
composer require andrewbreksa/unicorn
, (*6)
Check out the example index.php to see how to setup a basic app. (And I mean basic)., (*7)
As defined in \Unicorn\App\Application, (*8)
const EVENT_BOOTSTRAP = 'app.bootstrap'; const EVENT_DISPATCH = 'app.dispatch'; const EVENT_ROUTE_EXCEPTION = 'app.route.exception'; const EVENT_DISPATCH_EXCEPTION = 'app.dispatch.exception'; const EVENT_RENDER = 'app.render'; const EVENT_EMIT_EXCEPTION = 'app.emit.exception'; const EVENT_FINISH = 'app.finish';
Each event is emitted before the action takes place (if any, Application::EVENT_RENDER
doesn't do anything), and the event manager is accessible via Application::getInstance()->getEventEmitter()
. Fairly simple, see the league/event documentation., (*9)
You can access the router via Application::getInstance()->getRouteCollection()
. From there check out the league/route docs for more info., (*10)
A note on the return values of methods/closures/etc called on dispatch: If NULL
is returned (or nothing at all, implied) then Application->$response
is not updated, but the emitting process is carried out. However, if you return FALSE
, the emitting process is not carried out and Application::EVENT_RENDER
(needless to say, Application::EVENT_EMIT_EXCEPTION
) is not emitted either. This can be used to run other, "non-Unicorn", code or frameworks on specific routes., (*11)
Really? Ok, well checkout php-fig.org for more info., (*12)
Configuration is (can be) stored in ./config/autoload
. Any *.php
or *.json
file here will either be include
d or parsed and added to Application::getInstance()->getConfig()
. And as always, feel free to completely ignore this convention and do whatever you please., (*13)
Regardless of how the configuration is set, on Application->bootstrap()
(after EVENT_BOOTSTRAP
), if there is any of services
, routes
, or eventListeners
in Application->getConfig()
, the values of these keys are passed to Application->bootstrapServices()
, Application->bootstrapRoutes()
and Application->bootstrapEventListeners()
respectively., (*14)
Unicorn uses league/container, which follows the container-interop standard. All of the Application::getInstance()->get*()
objects are also available via the container (Application::getInstance()->getContainer()
) as Unicorn registers itself as a delegate (except the container itself, baseDir
, and data
. The dependency container is also set to use the League\Container\ReflectionContainer
as a delegate, so constructor dependencies should be automatically set if available more on auto-wiring., (*15)
As the architecture and use cases of Unicorn are still being fleshed out, I've yet to put together thorough documentation. It's more of a pet project really that I'm using for RAD on a couple of personal projects., (*16)
Event listeners attached to the various Application::EVENT_*
events are passed a \League\Event\Event
and the Application instance by default. EVENT_*_EXCEPTION
events are passed an additional \Exception
parameter., (*17)
Unicorn is supposed to do just about nothing, or in short, everything you should need for any PHP web application. If you're tired of fitting your domain requirements to a framework or needing to write hacky workarounds to problems caused by lack of control, you just might enjoy working with Unicorn., (*18)
Feel free to fork and open pull requests against this repo. I don't claim to know what I'm doing, and I feel Unicorn would best serve the community evolving as a project defined by common project requirements instead of a specific set of design patterns and 'full-featured' mentality., (*19)
A tiny single class RAD PSR-7 web application "framework"
MIT