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
Wallogit.com
2017 © Pedro Peláez
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