架构及扩展

一、单入口应用程序

基于SpeedPHP框架开发的应用程序,均是“单入口应用程序”(以下简称单入口程序),这是SpeedPHP框架的默认配置。

单入口程序概述

指在同一个应用程序中,访问者仅可以通过相同的一个文件来使用整个应用程序的功能。这个文件称作“入口文件”,而这种结构的应用程序整体就称作“单入口应用程序”。

在sp框架内,入口文件就是程序顶级目录的index.php文件。

一般而言,在单入口程序中,入口文件都是通过传入的参数(arg()获取)来判断应该执行的程序,并转向到该程序来执行。

优点

单入口程序有着以下各种优点:

  • 单入口程序安全性提高。多入口程序很容易造成安全配置和管理的混乱,而单入口程序可以统一使用相同的安全配置,从管理和配置上提高了应用程序的安全性。
  • 全局配置、权限控制等更简单。
  • 有利于Url重写(伪静态)的实现。
  • 随着云平台/云主机的日益流行,web程序透明分布式已经成为了常态,单入口能更好适应这种结构。

单入口程序须知

在使用单入口程序的时候,需要注意以下问题:

  • 单入口程序是一个整体的应用程序,也就是该程序的范围,应该是入口文件能够访问(转向)的极限。
  • 单入口程序通常用在中小型规模的应用程序(百万访问级以下)中,如果是大型应用程序(千万访问级),可以通过分离多套应用程序的方式拆分。
  • 建议初学者彻底放弃多入口文件的做法。
  • 入口文件是一切程序的入口。

二、架构设计

SpeedPHP框架的架构设计遵循以下规则:MVC基础,直接驱动,autoload执行。

MVC基础架构

MVC(Model模型 - View视图 - Controller控制器)的三层架构是SpeedPHP框架的核心架构,这是一个实践证明了较为适合WEB系统开发的架构。

  • M层以Model类为父类,提供数据及业务相关操作的模型结构标准与功能。
  • V层以PHP的模板引擎为基础,提供业界通用的模板引擎功能。
  • C层以Controller类为父类,提供轻便的程序转向执行功能。

MVC架构是面向对象编程的最佳实践之一,通过对父类的继承和覆盖,将可让SpeedPHP框架的MVC各部件更强大和更适合当前的应用程序。

同时,从软件工程角度而言,MVC架构也较为适合软件建模以及团队开发。

直接驱动

在大部分的通用PHP框架中,对数据库及模板引擎的支持,都是三层结构:
底层驱动(对数据库或模板的原始操作)-> 抽象层(转换表达式)-> 应用层(通用编程接口)

使用三层结构的主要原因有二:

  1. 抽象层能够方便地支持多种数据库类型(模板引擎)。
  2. 应用层功能更多。

但在实际开发中,真正“经常”使用的数据库接口功能(模板引擎功能)都是比较少的,不外乎是CRUD(查增改删)等几个简化的操作以及复杂的SQL执行,呈现80/20的现象。

也就是“开发者80%时间使用的功能,只占全部功能的20%。而有80%的功能,只有20%机会会使用到”。

另外,经过试验也可以发现,其实在没有抽象层的情况,支持多数据库多模板引擎也并非难事。

根据实际开发情况来看,在项目开发或运作过程中,突然更换数据库类型的情况,也是极其罕见的。并且现代系统架构的做法都是通过远程接口(如thrift等)来对接另一个数据库类型而不是直接链接。

综上考虑,SpeedPHP框架去除了抽象层的设计:底层驱动 -> 应用层。在保证应用成提供了常用接口功能的前提下,底层驱动和应用层直接实现了原本抽象层才能做到的事情,当然,SpeedPHP框架的直接驱动,在一定程度上,减少了应用层的功能数量。

在新版sp框架中,更进一步,把原来多个抽象数据库驱动的模式,直接改成只有一个Model类的模式,该类包含了应用功能及数据库驱动,比原先做了极大的精简改进。

所以,一般来说,较复杂的数据库及模板引擎功能,均建议直接使用数据库句柄(SQL语句)和模板引擎对象来实现(这部分只会有20%机会出现)。

autoload执行

3.1版本及之前的sp框架,遵循的类库载入规则是“按需载入”及“扩展点”的模式,虽然在性能上面已经做到极致,但在使用上面,会有一些不尽人意的感觉。

比如说,实例化一个php类,则需要使用spClass函数;然而“最php”的方式却是new。

所以现在新版的sp框架,直接通过php内置的autoload机制,来对类文件进行实例化。

好处在于:

  • 仍然是按需载入,仍然是快速如初。因为autoload仅仅是搜索类定于文件的方式改变的,但是内里却还是类似spClass的模式——也就是仅仅根据需要来载入对应的一个类文件。
  • 可以用new语法对类进行实例化,既符合php原生语法,而且对IDE(编辑器)的支持更好。
  • 扩展类库也可以通过new的方式直接在框架类使用,如同普通的php类一样;或者换句话说普通的类库也可以是扩展类库。

当使用new语法时,php的大部分IDE会提供类名提示,类成员函数提示等便利。

三、第三方类库和扩展

autoload机制中,所有php类文件只要放到model、include、controller三个目录之一里面,并且类名和文件名相同,那么即可在程序里面用new来对其实例化,当然,并不需要require进来。

  • 只要是php类,类名和文件名相同。
  • 放在model、include、controller三个目录之一
  • 通过new语法可以对其实例化,并且按照正常php类的方式使用。
  • 不需要预先require或include类文件进来。

目录搜索优先级是:model > include > controller,故最常用的类库放置在model目录,而不经常使用的放include,

而controller主要是方便隔控制器调用某些方法,一般controller目录不建议放除控制器类文件以外的php文件。

不再需要扩展点

新版的sp框架已经不再需要扩展点,取而代之的是更为简便的方式。

原有框架共有四个扩展点,以下新的对应方式:

路由前扩展:

  • 在路由解析前进行的一系列操作。该扩展点主要用于伪静态的实现以及ACL权限认证的入口判断。
  • 新版伪静态已经是内置并且十分精简的程序,性能效率非常高,所以不再需要在路由前进行配置。
  • 而权限控制,在新版中是定位到了控制器层面进行控制(毕竟就叫控制器嘛),如BaseController的init()函数以及各控制器自身的init()函数,均是实现全局或局部权限控制的位置。比起之前的路由前控制,更为“用户级”,也更容易操作。

路由后扩展:

  • 路由后扩展在旧版中并没有自带的使用功能。一般在路由后需要做的会是记录日志、压缩输出等。
  • 新版可以直接在入口文件的最后进行此类操作。

URL扩展:

  • 实际上也是旧版伪静态的一部分。
  • 新版的伪静态已经包含了此功能,故已经不再需要。

缓存扩展:

  • 旧版上面缓存可以通过配置进行替换驱动。
  • 新版更建议直接使用缓存,而配置也是比较简单可以拿到的。