phossa2/framework

基于配置、依赖注入和中间件的现代PHP框架。

dev-master / 2.1.x-dev 2016-10-11 09:01 UTC

This package is not auto-updated.

Last update: 2024-09-14 19:20:17 UTC


README

phossa2/framework 是一个基于配置、依赖注入和中间件的现代PHP框架。

它需要PHP 5.4,支持PHP 7.0+ 和 HHVM。它符合 PSR-1PSR-2PSR-3PSR-4 以及其他提议的PSR标准。

创建项目

通过 composer 工具安装。

# cd installation_dir/
# composer create-project phossa2/framework PROJECT

目录结构

phossa2/framework 包含了 单服务器安装 的目录结构。它也可以通过修改 .env 文件中的目录设置来适应不同的需求。

  • 单服务器安装

    默认的框架分发适用于单服务器安装。

    |--- .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
    
  • 多服务器安装

    框架也可以跨多台服务器安装,以提供负载均衡、中央应用程序管理(NFS挂载)等功能。

    |--- .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

执行路径

  • 应用程序执行路径

    1. public/index.php

    单个应用程序入口点。加载 system/bootstrap.php 文件,然后处理 config/middleware.php 中定义的应用程序中间件队列。

    <?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()
    );
    1. system/bootstrap.php

    public/index.phpphossa2 实用脚本需要。启动所有必需的组件,包括

    • 设置基本环境。

    • 启动自动加载。

    • .env 文件加载其他环境。

    • 启动 $config$container,它们从 config/ 目录读取配置。

    1. .env

    环境文件安装在 PROJECT 目录的上一级。该文件是针对特定主机,可能在不同的服务器上有所不同。

    有关详细信息,请参阅 phossa2/envphossa2/config

    • 更改应用程序环境

      PHOSSA2_ENV 的值更改来实现不同的服务器,例如生产服务器、开发服务器或预发布服务器。

    • 重构框架

      通过修改此文件中的目录设置,用户可以重构框架。

    1. 启动 $config$container
    • configure

      配置被分组到文件中,并位于 config/ 目录。

      有关详细信息,请参阅 phossa2/config

    • container

      phossa2/di 提供了一个基于 phossa2/config 的PSR-11兼容容器实现。

      容器对象在 config/di.php 或不同文件(如 config/db.php)的 'di' 部分中进行配置。

      还提供了一个服务定位器 Phossa2\Di\Service

      容器对象可以通过 Service::container() 获取。配置对象可以通过 Service::config() 获取。

      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();
    1. 处理应用中间件队列

    中间件在 config/middleware.php 中定义。

  • 控制台脚本执行路径

    1. phossa2 工具脚本

    单个工具入口。加载 system/bootstrap.php 文件,然后处理命令行参数

    1. 常见行参数

    处理常见行参数。然后,在 'system/Console/' 和 'app/Console/' 目录中查找控制器/动作对以执行特定操作。

由配置驱动的框架

phossa2/framework 是一个由配置驱动的框架。大多数对象和工具都在 config/ 目录下的配置文件中定义。对象由 DI 容器自动生成,并通过 Service::objectId() 提供。

例如,数据库连接在 config/db.php 中定义如下,

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}'],
        ],
    ],
];

最后部分 di 等于在容器中定义一个 $db

$db = new Pdo_Driver(['dsn' => '...']);
$container->set('db', $db);

要在代码中利用数据库连接,您可以在另一个容器对象配置文件中注入它。

// config/article.php
return [
    'class' => MyArticle::getClassName();

    // ${#article} in container
    'di' => [
        'article' => [
            'class' => '${article.class}',
            'args' => ['${#db}'] // inject $db
        ]
    ]
];

或者使用服务定位器明确使用它,

use Phossa2\Di\Service;

// get db
$db = Service::db();

$article = new MyArticle($db);

复杂的数据库配置可以在 config/production/db.php 中找到,它使用一个带有读/写连接池和几个只读连接的数据库连接管理器。

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,
        ],
    ],
];

前面的配置等同于以下代码,

// 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 不是一个纯 MVC 结构,而是一个以中间件为中心的框架。有关中间件运行器实现,请参阅 phossa2/middleware

不同的中间件队列在 config/middleware.php 中定义。


路由

路由由 Phossa2\Middleware\Middleware\Phossa2RouteMiddleware 处理。有关详细信息,请参阅 phossa2/middlewarephossa2/route

路由分发器 $dispatcherconfig/route.php 中定义。当处理到达 Phossa2RouteMiddleware 时,它将被注入到主中间件队列中。

不同的路由应定义在 config/route/*.php 文件中。例如,

// 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
        ],
    ]
];

注意:路由文件名中的 50_ 用于排序。

应用程序编程

  • 简单的方式来做事

    您可以从在项目创建期间已安装 phossa2/app-skeletonapp/ 目录开始编程。

  • 以良好的方式做事

    1. app-skeleton 克隆到本地目录。

    2. 将您自己的内容添加到克隆的应用程序骨架中。

    3. 从项目中移除最初安装的 app-skeleton

    # cd PROJECT/
    # composer remove phossa2/app-skeleton
    1. 将您的应用程序安装到 PROJECT
    • 如果您的应用程序在 git 上

      将以下行添加到您的 PROJECT/composer.json 文件中

      "repositories": [
          {
              "type":"package",
              "package": {
                  "name": "my/app",
                  "version": "master",
                  "source": {
                      "url": "https://github.com/my/app.git",
                      "type": "git",
                      "reference":"master"
                  }
              }
          }
      ]
      
    • 如果您的应用程序只是一个 zip 文件。

      将以下行添加到您的 PROJECT/composer.json 文件中

      "repositories": [
          {
              "type": "package",
              "package": {
                  "name": "my/app",
                  "version": "master",
                  "dist": {
                      "type": "zip",
                      "url": "http://mydomain.com/downloads/app-1.4.zip",
                      "reference": "master"
                  }
              }
          }
      ]
      
    • 然后通过 composer requirecomposer update 安装应用程序。

      # cd PROJECT/
      # composer require my/app

许可协议

MIT 许可协议