Download the PHP package chuchiy/phpex without Composer
On this page you can find all versions of the php package chuchiy/phpex. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download chuchiy/phpex
More information about chuchiy/phpex
Files in chuchiy/phpex
Package phpex
Short Description lightweight, flexible, developer friendly micro web framework
License The MIT License (MIT)
Informations about the package phpex
The PHPex Web Framework
PHPex is a lightweight, flexible, developer friendly micro web framework written in PHP.
Features
- High-order function based powerful plugin(middleware) with flexible process chain
- Class method annotation and function callback based url routing with parameters and pattern matching
- The all-in-one cycle object handle PSR-7 request, response, dependency injection and more.
- Request handler can return string, stream, iterable or anything you want with the help of plugin
- Lazy template rendering for complex web page composition
Installation
Use Composer to install PHPex.
Getting Started
Single file demo, don't use it in production:
Save above contents to index.php and test with the built-in PHP server:
Visit http://localhost:8080/hello/world will display hello world.
Visit http://localhost:8080/get?id=123 will get jsonize result {"name": "foo", 'id': 123}
Visit http://localhost:8080/console/send/foobar will log text foobar to server console
Configuration
nginx + php-fpm
PHPex utilize php-fpm's special param SCRIPT_FILENAME for front controller setting. Set the SCRIPT_FILENAME to the entrypoint file and php-fpm will passthrough all http traffic to that file.
Routing & Handler
Routing Mechanisms
PHPex gives you 2 difference routing mechanisms and 2 level routing dispatch to increase performance.
For small projects, you can just set function handler for routing:
If you want handlers organize as group to mount at specific path and share plugins:
$pex->attach($path)
will mount all routing staff in method chaining tp the attached path.
->with($plugin)
in a method chaining will install a plugin for all routing in that method chaining.
So http://localhost:8080/path-at/a will display A (with the help of strtoupper plugin) and http://localhost:8080/a will give you 404 not found http status code.
In real world projects, we always use difference classes to process application logic. Put all routing and handler stuff in one file would mess the whole project. PHPex provides ability to add routing and set handler with classes.
In front controller, just set as:
And all request start with /api/ will goes to \NS\Api
and request start with /site/ will goes to \NS\Site
.
Below is how the class looks like:
PHPex provides two mechanisms to add route for a class:
- You can use annotation command such as @get/@post/@route to add route(this way will also be used in method plugin install).
- You can add route in __invoke magic method(and you can install class-level plugin here).
For a large project, it's convenience to use difference dedicate class to handle logical relevant requests and combine them for more complex business logical. With PHPex, you can just setup 1st level mountpoint dispatch map at front controller and write real routing and process in code in different classes.
Request Handler
A request handler in PHPex is a callable to process http request. Request handler receive one cycle object as parameter and natively return string, callable, traversable, generator, stream or nothing(if you direct write to reponse body). Request handler, in most case, is wrapped by some plugins, then became the process chain.
The plugins can alter the parameter and return of request handler with ease. In real world development, the most widely use return type of request handler is assoc-array. And the plugins will transform the assoc-array to json string or html page in different scenario and plugin configurations.
Plugin(Middleware)
Plugin(Middleware) is the key concept in PHPex. Plugin is a high-order function which receive an inner request handler($run
) and return a new request handler who wrap the inner request handler. Plugins and request-handler build up the process chain.
The following plugin check the type of inner callable return value. if the return value is stdClass then json_encode it.
Plugin can also implement with class. just use __invoke magic method to receive the callable and return new handler. PHPex provides a abstract class \Pex\Plugin\BasePlugin
for handy class-style plugin implemention.
Plugin has 4 effective scope:
Global Level Plugin
Global plugin install via $pex->install
, such plugins will apply to all http request.
Group Level Plugin
Group plugin install with routing method chain, which will apply to handler in method chain.
Class Level Plugin
Class plugin install at class's __invoke method, which will aplyy to all method handler in class.
Method Level Plugin
Method plugin install with method annotation, $pex->bindAnnotation
or $route->bindAnnotation
should be called to bind a annotation command to a high-order plugin. High-order plugin is a callable receive annotation command name and args pass to annotation command, return a valid plugin, so you can utilize the args pass to annotation command
The Cycle Object
Request handler only has one parameter: an all-in-one $cycle
object. Cycle object can be used to:
- Get input parameters from path/cookie/post/get
- Dependency Injection & Service Container
- Wrapper for PSR-7 compatible HTTP Request/Response and handy way for request/response process
Parameters
You can get parameters by using $cycle->want('arg')
and $cycle->get('arg')
. ArrayAccess
like $cycle["args"]
, isset($cycle["args"])
is also available. Cycle will get the parameters with the order: parameters in request path, cookie, post and get.
$cycle->want($name)
will thrown InvaidArgumentException if the parameter name is not found. $cycle->get($name, $default=null)
will return $default
when parameter name is not found.
Dependency Injection & Service Container
Plugin/request-handler use $cycle
to inject and get service. You can use inject/register method to inject a callable as service.
The difference between inject and register is:
If you use inject, everytime you use $cycle->srvname
the relevant callable will be called and you get the new return value.
If you use register, the callable will only be called at the first time, and the result will be cached, you will always get the same result in latter $cycle->srvname
.
Use callable for injection give your ability of lazy initialization, the service is create only when you actual use it.
Request and Response
You can get PSR-7 compatible HTTP Request/Response use $cycle->request()
and $cycle->response()
.
Cycle also provides $cycle->client()
to get a \Pex\Client
instance with some handy method to retrieve common http header.
If you want to add headers to response, use $cycle->reply()->setHeader()
to add headers, ArrayAccess operator is also available, the added headers will dump to client after end of process chain.
Cycle object is also callable. Just like python wsgi's start_response, call the $cycle($status, $headers)
immediately flush the status code and headers to client and return a callable writer which can be used to send contents to client. $cycle->response()
will return the created http response only after $cycle
is called.
$cycle->interrupt($status, $headers=[], $body=null)
will throw a \Pex\Exception\HttpException
.
After install \Pex\Plugin\CatchHttpException
plugin at global scope, you can use $cycle->interrupt
to interrupt current process and CatchHttpException
will catch the exception and send the given $status
, $headers
and $body
to client.
Useful Built-in Plugins
Templater & TwigPlugin
PHPex comes with \Pex\Plugin\Templater
for plain php template render and \Pex\Plugin\TwigPlugin
for twig template render.
Template plugin will use the return data of request handler to render every template arguments pass to annotation command.
The most important feature of built-in template plugin is lazy rendering.
Although the template plugin is the method plugin and should render the request handler's return before global/group plugins. The return of template plugin is not actual template rendered result, it returns \Pex\ViewRender
, a callable subclass of ArrayObject.
The outter plugins can manipulate the returned ViewRender
as array. So in template file we can use all variables that process chain plugins insert into the view render.
After the process chain finish execute, because ViewRender
is callable, the framework will try to call the result and get the real rendered result.
Template plugin will also inject a template instance to $cycle
with the annotation name. In the above example, request handler can use $cycle->view->render($context, $templateFile)
to direct render template.
Jsonize & CatchHttpException
The Jsonize plugin will json_encode all assoc-array return value and by-pass other type of result. So it's safe to install the Jsonize plugin at the very early global level.
CatchHttpException need to install as the first plugin of whole process chain. This plugin will catch the \Pex\Exception\HttpException
and properly send response to client.