Soli 是一個輕量級的PHP 框架,參考了Phalcon, Laravel 框架的設計,意在松耦合、可擴展、簡潔易用。
MVC、依賴注入、事件管理、閃存消息、模版引擎(Twig、Smarty) 路由、命令行應用等功能
從上圖我們可以看到Soli 請求的處理流程為:
Application 將接收到的HTTP 請求交給路由處理,並將路由結果交給控制器調度器; 控制器處理應用程序的業務邏輯,調用相應的模型和視圖,並將處理結果通過調度器返給Application 做最終的HTTP 響應封裝。
另外,Soli 通過依賴注入容器提供的組件機制,可以供開發者在開發組件時方便的使用容器中的各種服務。
Soli 的事件管理器允許開發者通過創建"鉤子"攔截框架或應用中的部分組件操作。 以便獲得狀態信息、操縱數據或者改變某個組件進程中的執行流向。
$ 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/.
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 2.4
< VirtualHost *:80>
ServerAdmin [email protected]
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 函数对应的视图文件
目錄結構並非固定不變,可以依據實際項目需要和團隊開發習慣,約定目錄結構,定義和表達每個目錄的含義。
bootstrap.php中定義了兩個基本的常量:
APP_PATH 对应 app 目录
BASE_PATH 项目根目录
基本配置信息默認存放在config/config.php文件:
<?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 作自動加載和依賴管理。
在composer.json 中配置了app 目錄作為App 開頭的命名空間:
"autoload": {
"psr-4": {
"App\": "app/"
}
}
所以在app 目錄下按PSR-4 規則定義的類,在調用時都可以被自動加載, 像Controllers 和Console 目錄那樣。
依賴注入容器的目的為了降低代碼的耦合度,提高應用的可維護性。 把組件之間的依賴,轉換為對容器的依賴,通過容器進行服務管理(創建、配置和定位)。
容器服務的配置默認存放在config/services.php文件:
<?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 ;
});另外SoliWebApp 默認註冊了以下常用服務,供控制器和自定義組件直接使用:
| 服務名稱 | 介紹 | 預設 | 是否是共享服務 |
|---|---|---|---|
| router | 路由服務 | SoliWebRouter | 是 |
| dispatcher | 控制器調度服務 | SoliDispatcher | 是 |
| request | HTTP請求環境服務 | SoliWebRequest | 是 |
| response | HTTP響應環境服務 | SoliWebResponse | 是 |
| session | Session服務 | SoliWebSession | 是 |
| flash | 閃存消息服務 | SoliWebFlash | 是 |
允許開發者自定義同名的服務覆蓋以上默認的服務。
Web 應用程序的入口文件默認存放在public/index.php ,看起來像下面這樣:
<?php
require dirname ( __DIR__ ) . ' /app/bootstrap.php ' ;
$ app = new Soli Web App ();
// 处理请求,输出响应内容
$ app -> handle ()-> send ();
$ app -> terminate ();控制器類默認以"Controller" 為後綴,action 無後綴。
控制器可以通過訪問屬性的方式訪問所有註冊到容器中的服務。
<?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 尊重開發者在不同應用場景下的選擇和使用習慣,提供了易於擴展的方法, 讓你去實現適用於團隊和實際需求的數據層。
使用模型:
<?php
use Soli Model ;
class User extends Model
{
}這里外部在調用User 模型時默認會調用容器中以"db"命名的服務,且操作的表名為"user"。
如果需要指定其它數據庫連接服務,通過Model 的protected $connection屬性來設置:
/**
* 当前模型访问的数据库连接服务名称
*/
protected $ connection = ' user_db ' ;由於數據庫連接服務可以被指定,所以自然而然的支持多數據庫操作。
模型會自動將類名的駝峰格式轉換為對應表名的下劃線格式, 如RememberToken 模型默認轉換後操作的表名為remember_token。
我們也可以通過Model 的protected $table屬性手動指定表名:
/**
* 当前模型操作的表名
*/
protected $ table = ' xxx_user ' ;同樣可以通過Model 的protected $primaryKey屬性指定主鍵,默認主鍵為id :
/**
* 当前模型所操作表的主键
*/
protected $ primaryKey = ' xxx_id ' ;主鍵主要用於findById和findByIds函數。
Soli 模型支持的方法請移步soliphp/db。
視圖文件存放在views 目錄下,控制器與視圖對應關係的目錄結構為:
├── app 应用程序目录
│ └── Controllers WEB应用控制器目录
│ └── UserController.php
└── views 视图文件目录
└── user UserController 对应的视图目录
└── view.twig view 函数对应的视图文件
控制器app/Controllers/UserController.php:
<?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 模版引擎為例:
用户姓名:{{ user . name }}
用户邮箱:{{ user . email }}
{{ flash. output () }}更多視圖的使用方法,請移步soliphp/view。
感謝您的閱讀。