Arsenals 开发文档

版本号: 1.0 DEV
作者: 管宜尧
2014/1/4 0:04:56

第一章 架构指南

Arsenals采用了基于MVC的架构,同时支持Service层的扩展。

系统采用了 PHP 5.3 开始支持的 命名空间 ,在开发过程中,可以实现业务代码的灵活组织,非常简单的实现 HMVC 架构,以便对业务逻辑进行分离,更加清晰的实现模块化的开发。

第二章 开发规范

命名规范

  1. 对于类,采用驼峰命名法进行命名,如SessionUtils
  2. 对于成员变量,变量,采用_分割的小写方式命名,如$cate_name
  3. 对于方法,采用首字母小写的驼峰命名, 如getUserName()
  4. 普通函数采用小写加_的命名方法,如function _exception_handler()
  5. 对于PHP常量,采用大写,如define('BASE_PATH', '\\')
  6. 在PHP类中,如果成员是private或者protected的,则在名称前加一个 _ ,如protected function _output()
  7. 文件命名,所有的类文件命名以含有的类名为准,比如类SessionUtils所在的PHP文件应该命名为 SessionUtils.php , 不要使用类似SessionUtils.class.php等格式的命名,自动加载机制无法加载此种命名方法。

第三章 快速开始

本章主要介绍如何快速开始一个Arsenals项目的开发。
为了方便快速建立一个项目,框架提供了项目构建工具,用于快速创建一个项目,该工具位于Tools目录下,使用方式如下:

php app.php -n Demo

命令具体用法参见 杂项-快速构建项目骨架 部分。

第四章 参考文档

常量定义

常量 用途
APP_PATH 项目路径
CONFIG_PATH 配置文件所在路径
VIEW_PATH 视图所在路径
VIEW_LAYER 采用的视图实现,默认是SimpleView,值为带有命名空间的试图实现名称
MODEL_NAMESPACE 模型命名空间
SERVICE_NAMESPACE 服务层命名空间
CONTROLLER_NAMESPACE 控制层命名空间
FILTER_NAMESPACE 过滤器命名空间

项目配置

基本配置config.php

配置项 默认值 作用
theme defaults 默认主题
site_url 站点访问地址
hook_enabled false 是否允许钩子调用

数据库配置database.php

配置项 默认值 作用
data_source Arsenals\\Core\\Database\\MySQL\\MySQLiDataSource 默认采用的数据源
global array('prefix') 数据库访问全局配置
mysql array('host','port','db_name','user','password','char_set','dbcollat') mysql连接配置
pdo (暂未实现) array('dsn','user','password') PDO连接配置

路由配置router.php

下面是默认的路由配置。

配置项 默认值 作用
default_controller Index 默认控制器
default_action index 默认访问的方法
route 空数组 以数组的kv形式提供路由映射,key为url(支持正则), value为控制器方法字符串标识

默认情况下访问配置文件中配置的控制其方法,一般访问方法为:控制器名称/方法名(首字母小写即可)。
如果需要自定义路由,可以在项目入口文件中定义如下:

public function run() {
    //Route::map("articles/lists", '\\Demo\\controllers\\Articles@lists');
    Route::map("articles/lists", function ($input){
        return $input->get("cat");
    });
}

如果没有自定义路由,将采用系统内置路由规则,系统对所有的控制器方法注入了$input参数,该参数为Input类的实例,方便开发。

Route::map方法支持任意数量参数,可以在第三个参数开始任意传递变量,该参数将会自动附加到回调函数或者控制器方法中,例如:

Route::map('^原创音乐$', function($media, $action){
    return "这里是原创音乐:{$media} {$action}";
}, "MP3", "play");

小提示如果方法或者回调函数 *第一个** 参数为Input类型的对象,则可以自动注入Input对象,其它参数顺序后移一位。*

钩子

Arsenals框架提供了系统运行各个阶段的钩子函数功能,使对系统的扩展成为了可能,要使用钩子功能,需要在 config.php 配置文件中配置 hook_enabledtrue

钩子的配置文件为config目录下的 hook.php 文件,配置规则如下:

return array(
    // before_system为挂载点
    // 挂载点挂载的功能通过数组进行配置
    'before_system' => array(
        // 执行的为DemoHook对象的beforeSystem1方法
        'Demo\\hooks\\DemoHook@beforeSystem1',
        
        // 执行的为DemoHook的静态方法beforeSystem2
        'Demo\\hooks\\DemoHook::beforeSystem2'
    )   
);

系统内置挂载点:

挂载点 用途
before_system 系统初始化之前
after_system 系统初始化之后
before_controller 控制器之前
after_controller 控制器之后

字段校验规则

Arsenals框架提供了字段校验功能,开发过程中,可以方便的使用框架提供的字段校验功能对来自用户的输入信息进行校验。

要使用字段校验功能,需要使用Input类的静态方法validate方法。

\Arsenals\Core\Input::validate($var, $type, $optionals = null)

系统内置校验规则:

注意: 多个规则之间用|进行分隔。
如果需要指定规则参数,使用如下规则: 规则名:参数1,参数2

如果需要使用自定义的规则也很简单,使用Input的validateRuleRegister方法,为Input类注册自定义的校验规则。

\Arsenals\Core\Input::validateRuleRegister($rule_name, $entity_name)

$rule_name 为定义的规则名称,$entity_name 为规则实现(使用系统约定的对象指定方式)。

模板引擎

默认是采用系统内置的简单模板的,该模板使用纯PHP。
在控制器中渲染模板引擎只需要执行 ViewAndModel::make() 或者 VM::make() 方法即可获取解析之后的模板内容。

可以通过在入口文件中定义常量 VIEW_LAWER 修改默认采用的模板引擎,默认值为: Arsenals\Core\Views\SimpleView ,采用纯PHP模板。 例如:

define('VIEW_LAYER', 'Arsenals\Core\Views\SimpleView');

内置模板引擎ArsenalsTemplates

如果需要使用模板引擎,可以采用系统内置模板引擎 ArsenalsTemplates , 采用该模板引擎后,视图代码中可以使用内置标签,标签语法类似于Java EE中的JSTL语法。

使用前需要先配置使用该模板引擎,在项目入口文件中定义常量:

define('VIEW_LAYER', 'Arsenals\Core\Views\ArsenalsTemplates');

该模板引擎默认是使用 .html 作为模板文件扩展名,因此,所有的模板文件均为 *.html格式。
在模板中可以使用内置标签库语法进行模板编写。

标签库

例如: 模板文件index.html中:

    <html>
        <head>
            <title>样例</title>
        </head>
        <body>
            <div>
                <c:out value="$value" escape="true" default="hello" >
            </div>
        </body>
    </html>
模板编译缓存

为了提高效率,模板文件在第一次运行时会编译成 .php 的缓存文件,以使得在程序运行过程中省略掉模板编译过程,提高运行效率。
默认编译缓存在缓存目录下的views文件夹中,并且保持了模板文件的原始文件结构以及文件名称(除扩展名之外)。

标签变量规范

模板引擎是基于文本解析的,因此,对标签项的配置比较严格,因此,需要按照标签变量规范进行标签内容录入。如下变量必须进行替换:

原始字符 替换字符
> gt
< lt
== eq
!= neq
>= gte
<= lte
\ .(这里指的是命名空间分隔符)

例如:

    <c:func func="Demo.hello()" />
    输出为:<?php echo Demo\hello(); ?>

    <c:if test="$a gt 5">
        ${var}
    </c:if>
    输出为:
        <?php if($a &gt 5) { ?>
        <?php echo $var; ?>
        <?php } ?>

第三方模板引擎

系统还提供了一个基于Twig的模板引擎,不过需要手动加入Twig的类库才可以使用。加入Twig的类库之后,需要在项目的入口文件中定义Twig的Autoloader.php文件的路径常量,如下所示:

define('TWIG_LIB', 'Twig所在目录/Autoloader.php');

接下来再配置VIEW_LAWER值为 'Arsenals\Libraries\Twig\TwigView' 即可。

自定义模板引擎

除了使用内置模板引擎之外,开发者可以使用自定义的模板引擎,使用自定义的模板引擎也很简单,只需要实现自定义的视图解析类,自定义视图解析类实现 Arsenals\Core\Views\View 接口即可。

View接口中只包含一个方法, parse($vm), $vm为Arsenals\Core\Views\ViewAndModel类型的对象,其中保存了要显示的视图名称以及传递给视图的数据模型。

parse($vm) 方法完成视图解析,并返回解析后的视图内容。

例如:

namespace Demo\DemoViews;
use Arsenals\Core\Views\View;

class DemoView implements View{  
    public function parse($vm){  
        // $vm->getDatas(); 传递给视图的数据数组
        // 例如: @extract($vm->getDatas());

        // $vm->getView(); 要显示的视图名称

        return "解析之后的视图字符串";
    }
}

配置常量VIEW_LAWE为 Demo\DemoViews\DemoView即可。

日志系统

开发过程中要进行日志记录,可以通过使用内置的 \Arsenals\Core\Log 类进行日志记录,默认情况下,系统日志功能是关闭的。
如果要启用日志功能,需要在项目入口文件中定义常量 LOGtrue
默认情况下,系统会使用内置的文件方式进行日志写入,你也可以通过自定义日志实现进行接管日志写入操作,系统日志实现由常量 LOG_IMPL 定义,默认值为 Arsenals\\Core\\Logs\\FileLogImpl , 采用基于文件的方式。

要写入日志,使用一下方法:

$log = Registry::load('Arsenals\\Core\\Log');
$log->debug("日志内容", '日志类型');

日志类型含有三种: info, debug, error, warning。
如果需要获取日志内容, 使用 getLogs(日志级别) 方法。

如果需要控制写入日志的级别,可以通过log.php配置文件进行配置:

return array(
    'log_levels' => array('info', 'error', 'warning', 'debug') // 允许的日志级别
);

自定义日志实现

要使用自定义的日志实现,需要实现 Arsenals\Core\Logs 接口, 该接口含有两个方法:

public function write($level, $message);
public function getLogs($level = null);

然后再入口文件中定义日志实现就可以了。

define('LOG_IMPL', '你的日志实现类(包含命名空间)');

杂项

快速构建项目骨架

通过使用Tools下的快速构建工具可以快速的构建一个基本项目的骨架,构建命令如下:

    php app.php -n 项目名称 [额外参数]

可选参数如下:

参数 功能 默认值
author 开发者姓名 操作系统用户
db_prefix 数据库表前缀 项目名称小写_
db_dbname 数据库名称 db_项目名称小写
db_user 数据库用户名 root
db_password 数据库密码
db_host 数据库地址 localhost
db_port 数据库端口号 3306
view_theme 默认视图主题 default
model 模型目录 models
controller 控制器目录 controllers
cache 缓存目录 caches
filter Filter目录 filters

例如:
需要构建一个示例程序Demo。

D:\xampp\htdocs>php init.php -n CMS --db_prefix demo_ --author developer --db_
dbname test

上面的命令构建了一个项目,名称为CMS, 数据表前缀为demo_, 开发者为developer, 数据库名称为test, 其它配置项使用的是默认值。

异常处理/错误处理

可以在项目入口文件index.php中通过定义常量 ERROR_HANDLEREXCEPTION_HANDLER 使用自定义的异常处理。
例如:

define('ERROR_HANDLER', 'Arsenals\\Core\\_error_handler');
define('EXCEPTION_HANDLER', 'Arsenals\\Core\\_exception_handler');

function _error_handler($errno, $errstr, $errfile, $errline){
    _D("文件{$errfile}的第{$errline}行有一个错误,错误代码为{$errno}, 错误描述:{$errstr}");
}

function _exception_handler(\Exception $exception){
    _D("文件{$exception->getFile()}的第{$exception->getLine()}行抛出异常, 错误代码为 {$exception->getCode()}, 错误描述 :{$exception->getMessage()}");
}

内置异常

框架实现中包含了一些可能会常用到的异常,在开发过程中可以直接使用内置异常类。
系统内置异常统一在命名空间 Arsenals\Core\Exceptions 下,并且都继承了 Arsenals\Core\Exceptions\ArsenalsException 异常基类。

内置异常类 用途
AccessDeniedException 拒绝访问异常,一般用于没有权限访问
ClassNotFoundException 找不到类
ClassTypeException 类不是合法的类型
FormInvalidException 表单异常,如表单校验异常
FuncParamException 函数,方法调用参数异常
NoRecoredException 没有查询到指定基类异常
PageNotFoundException 找不到要访问的页面异常
QueryException 查询异常
RedefineException 重复定义异常
TypeErrorException 错误的类型

扩展类库

图形验证码

扩展库中包含简单验证码实现,调用方式非常简单:

$captcha = Registry::load('\Arsenals\Libraries\Images\Captcha');
$code = $captcha->generageCode();
$captcha->createImage($code);

注意的是,createImage 方法可以接收两个参数,第一个参数为验证码字符串,第二个参数为可选,如果为NULL,则验证码直接输出到浏览器,或者可以为要保存验证码的文件名。

文件上传

框架扩展库中集成了一个简易的文件上传类,该类位于 \Arsenals\Libraries\Files\Uploader.php
使用该类可以简单的实现文件上传操作,使用示例如下:

$uploader = \Arsenals\Core\Registry::load('\Arsenals\Libraries\Files\Uploader');
$up_status = $uploader->upload(上传字段, 目标文件名);

需要注意的是,upload 方法再上传完成后的返回值up_status在上传成功时为文件的访问地址。

图像处理

框架扩展库中内置了一个简易的图像处理工具类\Arsenals\Libraries\Image\ImageUtils, 使用该工具类可以轻松的完成对图片的缩放,创建缩略图,添加水印等。 要创建一个图片的缩略图,使用如下方法:

use \Arsenals\Libraries\Image\ImageUtils;
ImageUtils::thumb(原文件名,最大宽度, 最大高度[, 目标文件名[,压缩率=80]])

注意的是,目标文件名如果为空的话,则会将处理后的图片文件内容发送到浏览器(直接输出)。

如果要添加水印,则使用如下方法:

use \Arsenals\Libraries\Images\ImageUtils;
ImageUtils::watermark(array(
    'source_file' => $filename, 
    'watermark'=> 'test.gif', 
    'pos_x'=>-40, 
    'pos_y'=>-40
));

可选属性为如下:

SAE(新浪云计算平台)支持

要启用SAE支持,可以通过钩子挂载系统启动前期,加入SAE支持库实现。
首先,需要在项目配置文件 config.php 中启用钩子, hook_enabledtrue
其次,在hook.php配置文件中配置系统运行前钩子实现:

'before_system' => array( 
        'Demo\\hooks\\DemoHook@beforeSystem'
)

在DemoHook类中,定义载入SAE支持类库:

public function beforeSystem(){
    $sae = new \Arsenals\Libraries\Sae\SaeInit();
    $sae->init();
}

这样,就启用了对SAE的支持了,程序开发过程中,可以通过使用常量 IS_SAE 对是否是SAE环境进行判断。
为了实现SAE与传统环境之间的兼容,开发过程中注意不要使用本地文件系统操作函数,而使用系统内置的函数代替:

\Arsenals\Core\file_put_contents
\Arsenals\Core\file_get_contents
\Arsenals\Core\file_exists
\Arsenals\Core\opendir
\Arsenals\Core\readdir
\Arsenals\Core\unlink
\Arsenals\Core\closedir
\Arsenals\Core\is_file
\Arsenals\Core\move_uploaded_file