dev-master
9999999-dev https://github.com/phossa2/frameworkA modern PHP framework built-upon configuration, dependency injection and middlewares.
MIT
The Requires
by Hong Zhang
framework phossa phossa2
A modern PHP framework built-upon configuration, dependency injection and middlewares.
phossa2/framework is a modern PHP framework built-upon configuration, dependency injection and middlewares., (*1)
It requires PHP 5.4, supports PHP 7.0+ and HHVM. It is compliant with PSR-1, PSR-2, PSR-3, PSR-4, and other proposed PSR standards., (*2)
Install via the composer
utility., (*3)
# cd installation_dir/ # composer create-project phossa2/framework PROJECT
phossa2/framework is delivered with the single server installation
directory structure. It also can be restructured to fit different requirements
by modifying directory settings in the .env
file., (*4)
Single server installation, (*5)
Default framework distribution is for a single server installation., (*6)
|--- .env the environment file +--- PROJECT/ the project directory |--- phossa2 the utility script |--- app/ app installation dir |--- config/ where all the config files located |--- plugin/ where all the plugins installed |--- public/ where public stuff located | |--- asset/ | +--- index.php single public entry |--- runtime/ runtime related stuff | |--- local/ host-specific storage | | |--- cache | | +--- session | +--- log/ log file directory |--- system/ system files | +--- bootstrap.php bootstrap file +--- vendor/ third-party libs
Multiple servers installation, (*7)
The framework can also be installed across multiple servers to provide capabilities such as load balancing, central app managment (NFS mounted) etc., (*8)
|--- .env host-specific environments |--- local host-specific local storage | |--- cache/ | +--- session/ | |--- PROJECT/ shared among servers (NFS mounted) | |--- phossa2 | |--- app/ | |--- config/ | |--- plugin/ | |--- public/ | |--- system/ | +--- vendor/ | +--- runtime/ shared runtime stuff (NFS mounted) |--- log/host1 host-specific log dir |--- upload/ upload dir +--- static/ generated static html files
Application execution path, (*9)
Single app entry point. Load system/bootstrap.php
file and
then process the app middleware queue defined in config/middleware.php
, (*10)
<?php // public/index.php // Load bootstrap file require dirname(__DIR__) . '/system/bootstrap.php'; // execute the main middleware queue $response = Service::middleware()->process( ServerRequestFactory::fromGlobals(), new Response() );
Required by public/index.php
or phossa2 utility script.
Bootstrap all required stuff, including, (*11)
set basic environments., (*12)
start autloading., (*13)
load other environments from .env
file., (*14)
start $config and $container which read configs from
the config/
directory., (*15)
Environment file installled at one level upper of PROJECT
directory. This
file is host specific and may differ on different servers., (*16)
See phossa2/env and phossa2/config for detail., (*17)
To change app environment, (*18)
Change the value of PHOSSA2_ENV
to implement different servers, such as
production server, dev server or staging servers., (*19)
To restructure the framework, (*20)
By changing directory settings in this file, user may be able to restructure the framework., (*21)
$config
and $container
Configurations are grouped into files and located in the directory
config/
., (*23)
See phossa2/config for detail., (*24)
phossa2/di provides a PSR-11 compliant container implementation built upon phossa2/config., (*26)
Container objects are configured in config/di.php
or scattered in the
'di' section of different files such as config/db.php
., (*27)
A service locator Phossa2\Di\Service
is also provided., (*28)
The container object is available as Service::container()
. The
configuration object is available as Service::config()
., (*29)
use Phossa2\Di\Service; $config = Service::config(); $container = Service::container(); // get the db configuration array $db_conf = $config->get('db'); // get the db object $db = $container->get('db'); // or get from locator $db = Service::db();
Middlewares are defined in config/middleware.php
., (*30)
Console script execution path, (*31)
Single utility entry point. Load system/bootstrap.php
file
and then process command line arguments, (*32)
Common line arguments processed. And then look for controller/action pairs in the 'system/Console/' and 'app/Console/' directories for specific actions., (*33)
phossa2/framework is a configruation driven framework. Most of the objects,
utilities are defined in config files under the config/
directory. Objects are
generated automatically by the DI container and avaiable via
Service::objectId()
., (*34)
For example, the database connection is defined in config/db.php
as follows,, (*35)
use Phossa2\Db\Driver\Pdo\Driver as Pdo_Driver; // config/db.php return [ // PDO driver classname 'driver.pdo.class' => Pdo_Driver::getClassName(), // connect conf 'driver.pdo.conf' => [ 'dsn' => 'mysql:dbname=test;host=127.0.0.1;charset=utf8', ], // container section 'di' => [ // ${#db} 'db' => [ 'class' => '${db.driver.pdo.class}', 'args' => ['${db.driver.pdo.conf}'], ], ], ];
The last section di
equals to defining a $db
in the container, (*36)
$db = new Pdo_Driver(['dsn' => '...']); $container->set('db', $db);
To utilize the database connection in your code, you may either inject it in another container object configuration file., (*37)
// config/article.php return [ 'class' => MyArticle::getClassName(); // ${#article} in container 'di' => [ 'article' => [ 'class' => '${article.class}', 'args' => ['${#db}'] // inject $db ] ] ];
Or use it explicitly with the service locator,, (*38)
use Phossa2\Di\Service; // get db $db = Service::db(); $article = new MyArticle($db);
Complicated db configurations can be found in config/production/db.php
which
uses a db connection manager with a pool of a read-write connection and couple
of read-only connections., (*39)
use Phossa2\Db\Manager as Db_Manager; use Phossa2\Db\Driver\Pdo\Driver as Pdo_Driver; // config/production/db.php return [ // driver manager 'manager.class' => Db_Manager::getClassName(), // more connect confs 'driver.pdo.conf2' => [ 'dsn' => 'mysql:dbname=test;host=127.0.0.2;charset=utf8', ], 'driver.pdo.conf3' => [ 'dsn' => 'mysql:dbname=test;host=127.0.0.3;charset=utf8', ], // callback to get a db from db manager with tagname 'callable.getdriver' => function($dbm, $tag) { return $dbm->getDriver($tag); }, // container section 'di' => [ // ${#dbm} 'dbm' => [ 'class' => '${db.manager.class}', 'methods' => [ ['addDriver', ['${#db1}', 1]], ['addDriver', ['${#db2}', 5]], ['addDriver', ['${#db3}', 5]], ], ], // ${#db1} 'db1' => [ 'class' => '${db.driver.pdo.class}', 'args' => ['${db.driver.pdo.conf}'], 'methods' => [ ['addTag', ['RW']] ] ], // ${#db2} 'db2' => [ 'class' => '${db.driver.pdo.class}', 'args' => ['${db.driver.pdo.conf2}'], 'methods' => [ ['addTag', ['RO']] ] ], // ${#db3} 'db3' => [ 'class' => '${db.driver.pdo.class}', 'args' => ['${db.driver.pdo.conf3}'], 'methods' => [ ['addTag', ['RO']] ] ], // ${#dbro} read only driver (round-robin) 'dbro' => [ 'class' => '${db.callable.getdriver}', 'args' => ['${#dbm}', 'RO'], 'scope' => Container::SCOPE_SINGLE, ], // ${#dbrw} readwrite driver (round-robin if any) 'dbrw' => [ 'class' => '${db.callable.getdriver}', 'args' => ['${#dbm}', 'RW'], 'scope' => Container::SCOPE_SINGLE, ], // ${#db} either RW or RO 'db' => [ 'class' => '${db.callable.getdriver}', 'args' => ['${#dbm}', ''], 'scope' => Container::SCOPE_SINGLE, ], ], ];
The previous configruations equal to the following code,, (*40)
// different db connectors $db1 = (new Pdo_Driver($conf ))->addTag('RW'); $db2 = (new Pdo_Driver($conf2))->addTag('RO'); $db3 = (new Pdo_Driver($conf3))->addTag('RO'); // db manager $dbm = (new Db\Manager\Manager()) ->addDriver($db1, 1) // readwrite, factor 1 ->addDriver($db2, 5) // read_only, factor 5 ->addDriver($db3, 5) // read_only, factor 5 // get a readonly connection (round robin) $dbro = $dbm->getDriver('RO'); // get a readwrite connection $dbrw = $dbm->getDriver('RW'); // get a db connection (either RW or RO) $db = $dbm->getDriver('');
phossa2/framework is not a pure MVC structure but a middleware-centric framework. For middleware runner implementation, please see phossa2/middleware., (*41)
Different middleware queues are defined in config/middleware.php
., (*42)
Routes are handled by Phossa2\Middleware\Middleware\Phossa2RouteMiddleware
.
See phossa2/middleware, phossa2/route for
detail., (*43)
Route dispatcher $dispatcher
is defined in config/route.php
. It will be
injected into the main middleware queue when processing reaches the
Phossa2RouteMiddleware
., (*44)
Different routes should be defined in config/route/*.php
files. For example,, (*45)
// route/50_admin.php $ns = "App\\Controller\\"; // controller namespace return [ 'prefix' => '/admin/', 'routes' => [ // resolve to ['App\Controller\AdminController', 'defaultAction'] '/admin/{action:xd}/{id:d}' => [ 'GET,POST', // http methods, [$ns . 'Admin', 'default'], // handler, ['id' => 1] // default values ], ] ];
Note: 50_
in the route filename is for sorting purpose., (*46)
Do it a simple way, (*47)
You may just start programming in the app/
directory where
phossa2/app-skeleton is already installed during the
project creation., (*48)
Do it a nice way, (*49)
Git clone app-skeleton to your local directory., (*50)
Add your own stuff to the cloned application skeleton., (*51)
Remove the initially installed app-skeleton
from the project, (*52)
# cd PROJECT/ # composer remove phossa2/app-skeleton
PROJECT
If your app is on the git, (*53)
Add the following lines to your PROJECT/composer.json
, (*54)
"repositories": [ { "type":"package", "package": { "name": "my/app", "version": "master", "source": { "url": "https://github.com/my/app.git", "type": "git", "reference":"master" } } } ]
If your app is just a zip., (*55)
Add the following lines to your PROJECT/composer.json
, (*56)
"repositories": [ { "type": "package", "package": { "name": "my/app", "version": "master", "dist": { "type": "zip", "url": "http://mydomain.com/downloads/app-1.4.zip", "reference": "master" } } } ]
then install the app via composer require
or composer update
, (*57)
# cd PROJECT/ # composer require my/app
MIT License, (*58)
A modern PHP framework built-upon configuration, dependency injection and middlewares.
MIT
framework phossa phossa2