2017 © Pedro Peláez
 

project soliphp

The Soli PHP Framework.

image

soliphp/soliphp

The Soli PHP Framework.

  • Tuesday, April 10, 2018
  • by ueaner
  • Repository
  • 1 Watchers
  • 5 Stars
  • 14 Installations
  • PHP
  • 0 Dependents
  • 0 Suggesters
  • 1 Forks
  • 0 Open issues
  • 6 Versions
  • 0 % Grown

The README.md

Soli PHP Framework

Soli 是一个轻量级的 PHP 框架,参考了 Phalcon, Laravel 框架的设计,意在松耦合、可扩展、简洁易用。, (*1)

环境需求

提供的功能

MVC、依赖注入事件管理闪存消息模版引擎TwigSmarty路由命令行应用等功能, (*2)

请求的生命周期

Soli请求的生命周期, (*3)

从上图我们可以看到 Soli 请求的处理流程为:, (*4)

Application 将接收到的 HTTP 请求交给路由处理,并将路由结果交给控制器调度器控制器处理应用程序的业务逻辑,调用相应的模型视图,并将处理结果通过调度器返给 Application 做最终的 HTTP 响应封装。, (*5)

另外,Soli 通过依赖注入容器提供的组件机制,可以供开发者在开发组件时方便的使用容器中的各种服务。, (*6)

Soli 的事件管理器允许开发者通过创建"钩子"拦截框架或应用中的部分组件操作。 以便获得状态信息、操纵数据或者改变某个组件进程中的执行流向。, (*7)

快速运行当前项目

$ composer create-project soliphp/soliphp my-project
$ cp my-project/.env.example my-project/.env
$ php -S localhost:8000 -t my-project/public

浏览器访问 http://localhost:8000/., (*8)

NGiNX 配置

upstream php-fpm
{
    server unix:/tmp/php-fpm.sock;
}

server
{
    listen 80;
    server_name www.soliphp.com;
    index index.html index.php;
    root  /path/to/soliphp/public;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        include        fastcgi.conf;
        fastcgi_pass   php-fpm;
    }
}

Apache 配置

# Apache 2.4

<VirtualHost *:80>

    ServerAdmin admin@example.host
    DocumentRoot "/path/to/soliphp/public"
    DirectoryIndex index.php
    ServerName www.soliphp.com

    <Directory "/path/to/soliphp/public">
        Options All
        AllowOverride All
        Allow from all
        Require all granted

        RewriteEngine on
        RedirectMatch 403 /\..*$
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteCond %{REQUEST_FILENAME} !-d
        RewriteRule . /index.php
    </Directory>

</VirtualHost>

应用程序结构

├── app                            应用程序目录
│   ├── Console                    终端命令应用控制器目录
│   │   ├── Command.php            终端命令应用基类
│   │   └── Demo.php               Demo命令
│   ├── Controllers                WEB应用控制器目录
│   │   ├── Controller.php         控制器基类
│   │   ├── IndexController.php    默认控制器
│   │   └── UserController.php     和用户相关的控制器
│   ├── Events                     事件目录
│   │   ├── AppEvents.php          WEB应用事件
│   │   └── UserEvents.php         用户相关的事件
│   ├── Models                     模型目录
│   │   ├── Model.php              模型基类
│   │   └── UserModel.php          用户模型
│   ├── Services                   服务层目录
│   │   ├── Service.php            服务基类
│   │   └── UserService.php        用户相关的服务
│   └── bootstrap.php
├── bin
│   └── console                    终端命令应用入口文件
├── composer.json                  composer配置文件
├── config                         配置文件目录
│   ├── config.php                 基础配置文件
│   ├── console.php                针对终端命令应用的配置文件
│   ├── routes.php                 路由配置文件
│   └── services.php               容器服务配置文件
├── phpcs.xml
├── public                         WEB服务公共可被访问的文件目录
│   ├── css
│   ├── img
│   ├── index.php                  WEB程序入口文件
│   └── js
├── var                            生成的文件目录
│   ├── cache                      缓存文件目录
│   └── log                        日志文件目录
└── views                          视图文件目录
    └── index                      IndexController 对应的视图目录
        └── index.twig             index 函数对应的视图文件

目录结构并非固定不变,可以依据实际项目需要和团队开发习惯,约定目录结构,定义和表达每个目录的含义。, (*9)

使用

bootstrap.php 中定义了两个基本的常量:, (*10)

APP_PATH   对应 app 目录
BASE_PATH  项目根目录

基本配置信息

基本配置信息默认存放在 config/config.php 文件:, (*11)

<?php
// 基本配置信息
$config = array(
    // 应用
    'app' => array(
        'viewsDir' => BASE_PATH . '/views/',
        'logDir'   => BASE_PATH . '/var/log/',
        'cacheDir' => BASE_PATH . '/var/cache/',
    ),
    // 数据库
    'db' => array(
        'dsn'      => 'mysql:host=localhost;port=3306;dbname=test;charset=utf8',
        'username' => 'root',
        'password' => 'root',
    ),
    // 更多...
);

自动加载配置

composer 是一个优秀的包管理工具,也是一种趋势,所以 Soli 使用 composer 作自动加载和依赖管理。, (*12)

在 composer.json 中配置了 app 目录作为 App 开头的命名空间:, (*13)

"autoload": {
    "psr-4": {
        "App\\": "app/"
    }
}

所以在 app 目录下按 PSR-4 规则定义的类,在调用时都可以被自动加载, 像 Controllers 和 Console 目录那样。, (*14)

容器服务配置

依赖注入容器的目的为了降低代码的耦合度,提高应用的可维护性。 把组件之间的依赖,转换为对容器的依赖,通过容器进行服务管理(创建、配置和定位)。, (*15)

容器服务的配置默认存放在 config/services.php 文件:, (*16)

<?php
use Soli\Di\Container;
use Soli\Db\Connection as DbConnection;
use Soli\Logger;
use Soli\View;
use Soli\View\Engine\Twig as TwigEngine;
use Soli\View\Engine\Smarty as SmartyEngine;

$container = new Container();

// 将配置信息扔进容器
$container->set('config', require BASE_PATH . '/config/config.php');

// 配置数据库信息, Model中默认获取的数据库连接标志为"db"
// 可使用不同的服务名称设置不同的数据库连接信息,供 Model 中做多库的选择
$container->set('db', function () {
    return new DbConnection($this->config->db);
});

// 路由
$container->set('router', function () {
    $routesConfig = require BASE_PATH . '/config/routes.php';

    $router = new \Soli\Router();

    $router->setDefaults([
        // 控制器的命名空间
        'namespace' => "App\\Controllers\\"
    ]);

    foreach ($routesConfig as $route) {
        list($methods, $pattern, $handler) = $route;
        $router->map($methods, $pattern, $handler);
    }
    return $router;
});

// TwigEngine
$container->set('view', function () {
    $config = $this->config;

    $view = new View();
    $view->setViewsDir($config->app->viewsDir);
    $view->setViewExtension('.twig');

    // 通过匿名函数来设置模版引擎,延迟对模版引擎的实例化
    $view->setEngine(function () use ($config, $view) {
        $engine = new TwigEngine($view);
        // 开启 debug 不进行缓存
        //$engine->setDebug(true);
        $engine->setCacheDir($config->app->cacheDir . 'twig');
        return $engine;
    });

    return $view;
});

// 如果使用 Smarty 的话,可进行如下设置:

// SmartyEngine
$container->set('view', function () {
    $config = $this->config;

    $view = new View();
    $view->setViewsDir($config->app->viewsDir);
    $view->setViewExtension('.tpl');

    // 通过匿名函数来设置模版引擎,延迟对模版引擎的实例化
    $view->setEngine(function () use ($config, $view) {
        $engine = new SmartyEngine($view);
        // 开启 debug 不进行缓存
        $engine->setDebug(true);
        $engine->setOptions(array(
            'compile_dir'    => $config->app->cacheDir . 'templates_c',
            'cache_dir'      => $config->app->cacheDir . 'templates',
            'caching'        => true,
            'caching_type'   => 'file',
            'cache_lifetime' => 86400,
        ));
        return $engine;
    });

    return $view;
});

另外 Soli\Web\App 默认注册了以下常用服务,供控制器和自定义组件直接使用:, (*17)

服务名称 介绍 默认 是否是共享服务
router 路由服务 Soli\Web\Router
dispatcher 控制器调度服务 Soli\Dispatcher
request HTTP请求环境服务 Soli\Web\Request
response HTTP响应环境服务 Soli\Web\Response
session Session服务 Soli\Web\Session
flash 闪存消息服务 Soli\Web\Flash

允许开发者自定义同名的服务覆盖以上默认的服务。, (*18)

入口文件

Web 应用程序的入口文件默认存放在 public/index.php,看起来像下面这样:, (*19)

<?php
require dirname(__DIR__) . '/app/bootstrap.php';

$app = new \Soli\Web\App();

// 处理请求,输出响应内容
$app->handle()->send();

$app->terminate();

控制器

控制器类默认以 "Controller" 为后缀,action 无后缀。, (*20)

控制器可以通过访问属性的方式访问所有注册到容器中的服务。, (*21)

<?php
use Soli\Controller;
use App\Models\User;

class UserController extends Controller
{
    /**
     * 用户详情
     *
     * 自动渲染 views/user/view.twig 视图
     */
    public function view($id)
    {
        // 这里调用了容器中的 view 服务,设置一个模版变量
        $this->view->setVar('user', User::findById($id));
    }
}

模型

Soli 模型仅仅提供了操作数据库的一些常用方法,并没有去实现 ORM, 这是由我们的数据来源和项目架构决定的,有可能数据是来自远程接口, 也有可能团队更习惯使用 Doctrine。 Soli 尊重开发者在不同应用场景下的选择和使用习惯,提供了易于扩展的方法, 让你去实现适用于团队和实际需求的数据层。, (*22)

使用模型:, (*23)

<?php
use Soli\Model;

class User extends Model
{
}

这里外部在调用 User 模型时默认会调用容器中以"db"命名的服务,且操作的表名为"user"。, (*24)

如果需要指定其它数据库连接服务,通过 Model 的 protected $connection 属性来设置:, (*25)

/**
 * 当前模型访问的数据库连接服务名称
 */
protected $connection = 'user_db';

由于数据库连接服务可以被指定,所以自然而然的支持多数据库操作。, (*26)

模型会自动将类名的驼峰格式转换为对应表名的下划线格式, 如 RememberToken 模型默认转换后操作的表名为 remember_token。, (*27)

我们也可以通过 Model 的 protected $table 属性手动指定表名:, (*28)

/**
 * 当前模型操作的表名
 */
protected $table = 'xxx_user';

同样可以通过 Model 的 protected $primaryKey 属性指定主键,默认主键为 id:, (*29)

/**
 * 当前模型所操作表的主键
 */
protected $primaryKey = 'xxx_id';

主键主要用于 findByIdfindByIds 函数。, (*30)

Soli 模型支持的方法请移步 soliphp/db。, (*31)

视图

视图文件存放在 views 目录下,控制器与视图对应关系的目录结构为:, (*32)

├── app                          应用程序目录
│   └── Controllers              WEB应用控制器目录
│       └── UserController.php
└── views                        视图文件目录
    └── user                     UserController 对应的视图目录
        └── view.twig            view 函数对应的视图文件

控制器 app/Controllers/UserController.php:, (*33)

<?php
use Soli\Controller;
use App\Models\User;

class UserController extends Controller
{
    public function view($id)
    {
        $this->view->setVar('user', User::findById($id));
        $this->flash->notice('user info');
    }
}

视图文件 views/user/view.twig,这里以 twig 模版引擎为例:, (*34)

用户姓名:{{ user.name }}
用户邮箱:{{ user.email }}

{{ flash.output() }}

更多视图的使用方法,请移步 soliphp/view。, (*35)

感谢您的阅读。, (*36)

The Versions

10/04 2018

dev-master

9999999-dev

The Soli PHP Framework.

  Sources   Download

MIT

The Requires

 

The Development Requires

framework soliphp soli

30/03 2018

v0.8.1

0.8.1.0

The Soli PHP Framework.

  Sources   Download

MIT

The Requires

 

The Development Requires

framework soliphp soli

28/02 2018

v0.8

0.8.0.0

The Soli PHP Framework.

  Sources   Download

MIT

The Requires

 

The Development Requires

framework soliphp soli

27/02 2018

v0.7.2

0.7.2.0

The Soli PHP Framework.

  Sources   Download

MIT

The Requires

 

The Development Requires

framework soliphp soli

27/02 2018

v0.7.1

0.7.1.0

The Soli PHP Framework.

  Sources   Download

MIT

The Requires

 

The Development Requires

framework soliphp soli

26/02 2018

v0.7

0.7.0.0

The Soli PHP Framework.

  Sources   Download

MIT

The Requires

 

The Development Requires

framework soliphp soli