_美国著名棒球运动员约格.贝拉说过:“通过仔细地观察,你可以了解很多事情。”_
##1.29.1 绝对的开放,还是绝对的固化?
框架应该都会考虑这样一个问题:到底是应该给应用项目提供统一固定的入口和初始化流程呢,还是应该给他们完全自由的空间?
但我发现,很多PHP的框架都提供了一个绝对的固化流程。也就是你能作出改动的地方很少,虽然这样应用不需要过多地去考虑。
然而我觉得,这样做,弊大于利。特别在现在项目需求背景各有各的不同时。所以,我为PhalApi框架选择了开放式的初始化做法。考虑到若开放的度太大,项目可能会迷茫,所以又结合了统一的初始化。
下面分别说明这两点:开放式入口和封闭式的初始化。
##1.29.2 开放式的入口
作为一个接口系统,是需要为不同的终端、不同的开放人群,甚至不同的版本提供不同的服务的。
如:
+ 按不同的终端:iOS设备、Android设备、PC版、网页版
+ 按不同的开放人群:手机客户端、内部管理后台、内部其他系统、公共开放平台
+ 按不同的版本:版本从V1、V2到VN
+ 按不同的项目:同一个应用下可能会存在多个项目,当然更推荐每个项目单独一个系统
基于此,为不同的维度提供不同的入口就很有现实实用场景了。
更为重要的是,这些不同的入口都应该尽可能简单,并能统一共享公共的组件资源、数据库、日志系统这些。一个可能的入口示例如下:
```javascript
<?php
/**
* Demo 统一入口
*/
require_once dirname(__FILE__) . '/../init.php';
//装载你的接口
DI()->loader->addDirs('Demo');
/** ---------------- 响应接口请求 ---------------- **/
$api = new PhalApi();
$rs = $api->response();
$rs->output();
```
简单解读一下上面的代码,首先要加载统一初始化文件,其实装载挂靠的接口项目(对应你的项目目录的名称),最后创建一个PhalApi接口实例进行响应、输出结果。
下面来看下统一初始化文件需要做的事情。
##1.29.3 封闭式的初始化
不言而喻,尽管我们有按不同维度划分入口的需要,但统一初始化的过程更是必不可少的。
不同的入口提供了各维度定制的机会,统一的初始化则为应用提供了统一定制的机会。
###(1)常规入口代码
常规的入口,需要以下初始化操作:
```javascript
<?php
/**
* 统一初始化
*/
/** ---------------- 根目录定义,自动加载 ---------------- **/
date_default_timezone_set('Asia/Shanghai');
defined('API_ROOT') || define('API_ROOT', dirname(__FILE__) . '/..');
require_once API_ROOT . '/PhalApi/PhalApi.php';
$loader = new PhalApi_Loader(API_ROOT);
/** ---------------- 注册&初始化服务组件 ---------------- **/
//自动加载
DI()->loader = $loader;
//配置
DI()->config = new PhalApi_Config_File(API_ROOT . '/Config');
//日志纪录
DI()->logger = new PhalApi_Logger_File(API_ROOT . '/Runtime',
PhalApi_Logger::LOG_LEVEL_DEBUG | PhalApi_Logger::LOG_LEVEL_INFO | PhalApi_Logger::LOG_LEVEL_ERROR);
//数据操作 - 基于NotORM,$_GET['__sql__']可自行改名
DI()->notorm = function() {
$debug = !empty($_GET['__sql__']) ? true : false;
return new PhalApi_DB_NotORM(DI()->config->get('dbs'), $debug);
};
//调试模式,$_GET['__debug__']可自行改名
DI()->debug = !empty($_GET['__debug__']) ? true : DI()->config->get('sys.debug');
//翻译语言包设定
SL('zh_cn');
```
###(2)常规代码解读
上面是框架执行所需的基础服务注册和配置,一般直接可用,但也可以根据需要作些细微的调整。如日志的级别设定、调试的参数修改(改成一个只有自己知道的参数名字,别让外界知道!)等。
出于让大家对初始化过程有一个更理性的认识,这里补充一下各代码的作用。
最开始是利用了PHP原生态的时区设置和宏定义:
```javascript
date_default_timezone_set('Asia/Shanghai');
defined('API_ROOT') || define('API_ROOT', dirname(__FILE__) . '/..');
```
接着,便开始引入PhalApi框架的类自动加载器:
```javascript
require_once API_ROOT . '/PhalApi/PhalApi.php';
$loader = new PhalApi_Loader(API_ROOT);
```
这样,我们就可以从原生态的PHP开发,切入到了PhalApi接口开发模式。但在捲起袖口准备大干一场前,我们还需要注册一些必备的服务:
```javascript
//自动加载
DI()->loader = $loader;
//配置
DI()->config = new PhalApi_Config_File(API_ROOT . '/Config');
//日志纪录
DI()->logger = new PhalApi_Logger_File(API_ROOT . '/Runtime',
PhalApi_Logger::LOG_LEVEL_DEBUG | PhalApi_Logger::LOG_LEVEL_INFO | PhalApi_Logger::LOG_LEVEL_ERROR);
//数据操作 - 基于NotORM,$_GET['__sql__']可自行改名
DI()->notorm = function() {
$debug = !empty($_GET['__sql__']) ? true : false;
return new PhalApi_DB_NotORM(DI()->config->get('dbs'), $debug);
};
```
上面的自动加载、配置、日志和数据库操作通常而言,对于一个项目都是必须的。
但配置文件的路径可自行指定,日志的存储类型也可以自由组合(多个类型采用或运算),还可以选择你合适的数据库配置。
注意到,PhalApi_DB_NotORM初始化时,除了配置文件外,还有一个debug参数,此参数的作用是用于控制是否打印显示执行的SQL语句及对应消耗的时间。
至此,我们已经为项目完成了绝大部分的基础服务注册,且上面的初始化顺序建议保留不变。因为,前后有依赖关系。
但为了让我们的项目更有活力、更具生气、更国际化,我们还可以多加这么两行代码:
```javascript
//调试模式,$_GET['__debug__']可自行改名
DI()->debug = !empty($_GET['__debug__']) ? true : DI()->config->get('sys.debug');
//翻译语言包设定
SL('zh_cn');
```
这里,也有一个debug参数,之所以和数据库的分开,是因为如果混在一起会导致返回结果解析失败(如不再是JSON格式)。
此debug的来源,默认来自环境的系统配置文件(如区分生产环境和测试环境);也可以来自某个请求的手动设置,这样,开发同学便可以快速进行在线调试了。
而这个参数,则是框架代码、项目代码以及扩展类库所共用的调试开关,至于各个场景使用的效果,视各环节而定。
SL()是一个快速函数,作用是设定翻译语言包。如果觉得中文下的UTF-8查看不直观,可以自行加个参数修改,如:
```javascript
SL(isset($_GET['__lan__']) ? $_GET['__lan__'] : 'zh_cn');
```
###(3)更多定制注册代码
上面的操作,涵盖了大部分项目的需要。除此之外,还有一些额外的服务,可根据自身的情况,定制处理:
```javascript
/** ---------------- 以下服务组件就根据需要定制注册 ---------------- **/
//缓存 - MC
/**
DI()->cache = function() {
$mc = new PhalApi_Cache_Memcached(DI()->config->get('sys.mc'));
return $mc;
};
*/
//签名验证服务
//DI()->filter = 'Common_SignFilter';
//支持JsonP的返回
if (!empty($_GET['callback'])) {
DI()->response = new PhalApi_Response_JsonP($_GET['callback']);
}
```
###(4)更多定制解读
此部分的注册,非项目必须部分。可根据需要,自行定制。
如上面出现的第一个,即缓存服务,使用的是Memcached:
```javascript
DI()->cache = function() {
$mc = new PhalApi_Cache_Memcached(DI()->config->get('sys.mc'));
return $mc;
};
```
接下来的,是重要的接口签名验证服务。之所以没有提供这个服务的实现,是出于更高安全性考虑而建议项目各自制定签名规则并实现。然后这样简单注册即可被框架自动调用:
```javascript
//签名验证服务
//DI()->filter = 'Common_SignFilter';
```
在有些需要支持JsonP返回的场景,可以使用PhalApi_Response_JsonP返回格式开放callback操作:
```javascript
//支持JsonP的返回
if (!empty($_GET['callback'])) {
DI()->response = new PhalApi_Response_JsonP($_GET['callback']);
}
```
##1.29.4 用一张图来表示
![多级缓存静态结构图-多入口](http://webtools.qiniudn.com/%E5%A4%9A%E7%BA%A7%E7%BC%93%E5%AD%98%E9%9D%99%E6%80%81%E7%BB%93%E6%9E%84%E5%9B%BE-%E5%A4%9A%E5%85%A5%E5%8F%A3.jpg)
- 欢迎使用PhalApi!
- 接口,从简单开始!
- [1.1]-下载与安装
- [1.2]-创建一个自己的项目
- [1.3]-在线体验
- [1.4]-文档、帮助和官网
- [1.10]-对PhalApi框架的抉择
- [1.11]-快速入门(backup)
- [1.12]-参数规则:接口参数规则配置
- [1.13]-统一的接口请求方式:_sevice=XXX.XXX
- [1.14]-统一的返回格式和结构:ret-data-msg
- [1.15]-数据库操作:基于NotORM的使用及优化
- [1.16]-配置读取:内外网环境配置的完美切换
- [1.17]-日记纪录:简化版的日记接口
- [1.18]-快速函数:人性化的关怀
- [1.19]-DI服务速查:各资源服务一览表
- [1.20]-DB操作:数据库基本操作速查
- [1.21]-类的自动加载:遵循PEAR包的命名规范
- [1.22]-签名验证:自定义签名规则
- [1.23]-请求和响应:GET和POST两者皆可得及超越JSON格式返回
- [1.24]-缓存策略:更灵活地可配置化的多级缓存
- [1.25]-国际化翻译:为走向国际化提前做好翻译准备
- [1.26]-数据安全:数据对称加密方案
- [1.27]-精益开发:更富表现力的Model层和重量级数据获取的应对方案
- [1.28]-COOKIE:对COOKIE原生态的支持及记忆加密升级版
- [1.29]-开放与封闭:多入口和统一初始化
- [1.30]-保持的力量:接口开发最佳实践
- [1.31]-新型计划任务:以接口形式实现的计划任务
- [2.11]-核心思想:DI依赖注入-让资源更可控
- [2.12]-海量数据:可配置的分库分表
- [2.13]-接口调试:在线SQL语句查看与性能优化
- [2.14]-测试驱动开发:意图导向编程下的接口开发
- [2.15]-演进:新型计划任务续篇
- [2.16]-领域驱动设计:应对复杂领域业务的Domain层
- [2.17]-微服务:Api接口服务层
- [2.18]-定制化:资源服务的再实现
- [2.19]-扩展库:可重用的扩展类库
- [2.20]-约定编程:架构明显的编程风格
- [2.21]-服务器统一部署方案简明版:CentOs---Nginx---php-fpm---MySql-[--Memcached]
- [2.22]-更多工具:精益项目和团队建设
- [3.1]-扩展类库:微信开发
- [3.2]-扩展类库:代理模式下phprpc协议的轻松支持
- [3.3]-扩展类库:基于PHPMailer的邮件发送
- [3.4]-扩展类库:优酷开放平台接口调用
- [3.5]-扩展类库:七牛云存储接口调用
- [3.6]-扩展类库:新型计划任务
- [3.8]-扩展类库:用户、会话和第三方登录集成
- [3.9]-扩展类库:swoole支持下的长链接和异步任务实现
- [3.11]-扩展类库:基于FastRoute的快速路由
- [4.2]-开发实战2:模拟优酷开放平台接口项目开发
- [4.3]-开发实战3:一个简单的小型项目开发(奔跑吧兄弟投票活动)
- [5.1]-架构与思想:PhalApi核心设计和思想解读
- [5.2]-杂谈:扯一些PhalApi的前世和今生
- [5.3]-框架总结:术语表和PHP开发建议
- [5.4]-许可
- [5.5]-联系和加入我们
- [5.6]-更新日记
- [5.8]-致框架贡献者:加入PhalApi开源指南
- [6.1]-基于接口查询语言的SDK包
- [6.2]-SDK包(JAVA版)
- [6.3]-SDK包(PHP版)
- [6.4]-SDK包(Objective-C版)
- [6.5]-SDK包(javascript版)
- [6.6]-SDK包(Ruby版)
- [8.1]-PhalApi视频教程
- 附录1:接口文档参考模板