Yaf一个基于C语言实现的MVC框架,其性能不言而喻非常的强悍,Yaf提供的基本的MVC、路由、视图、插件等功能,如果要想很好利用Yaf进行开发的话需要做很多方面的扩充,由于要用到这个框架分享一下自己的一部分扩展剩下还会慢慢的补充扩展。
1:整个Yaf的目录结构如下:
[root@lmlq yaf_expand_01]# tree -d
├── application
│ ├── actions
│ ├── cache
│ │ └── templates_c
│ ├── controllers
│ ├── library
│ │ ├── Db
│ │ ├── Smarty
│ │ │ ├── plugins
│ │ │ └── sysplugins
│ │ └── Sys
│ ├── models
│ │ └── Gongchanginfo
│ ├── modules
│ │ ├── Index
│ │ └── User
│ │ ├── controllers
│ │ └── views
│ ├── plugins
│ └── views
└── conf
└── index.php
目录结构中的代码如下:
2:入口文件:index.php
<?php
/**定义项目中用到的常量**/
define('APPLICATION_PATH', dirname(__FILE__));//index.php文件所在的路径
define('MODELS_PATH', APPLICATION_PATH . '/application/Models/');//models所在目录
define('SMARTY_PATH', APPLICATION_PATH . '/application/library/Smarty');//smarty.class.php所在目录
define('SMARTY_TEMPLATE_PATH', APPLICATION_PATH . '/application/views/');//smarty模板文件路径
/**初始化及路由**/
$application = new Yaf_Application( APPLICATION_PATH . "/conf/application.ini",'development');//development 为开发环境 product为生存环境
$application->bootstrap()->run();
3:/application/BootStrap.php
<?php
/**
* @name Bootstrap 引导程序 只是引导的一部分是可以选择
* @author root
* @desc 所有在Bootstrap类中, 以_init开头的方法, 都会被Yaf调用,
* 这些方法, 都接受一个参数:Yaf_Dispatcher $dispatcher
* 调用的次序, 和申明的次序相同
*/
class Bootstrap extends Yaf_Bootstrap_Abstract{
/**
初始化配置文件
**/
public function _initConfig() {
$arrConfig = Yaf_Application::app()->getConfig();//把配置保存起来
Yaf_Registry::set('config', $arrConfig);
}
/**路由设置
路由协议事实上主要负责我们预先定义好的路由协议,只有一个路由器,可有有许多路由协议。
路由器主要负责管理和运行路由连,它根据协议栈顺序依次调用各个路由协议,一直到某一个路由协议返回成功就匹配成功。
**/
public function _initRoute(Yaf_Dispatcher $dispatcher) {
//在这里注册自己的路由协议,默认使用简单路由 通过派遣器获取默认的路由器
$router = Yaf_Dispatcher::getInstance()->getRouter();//获取路由器
$router->addConfig(Yaf_Registry::get("config")->routes);//加载路由协议
}
//初始化视图 如果有要添加自己的视图工具 关闭其自动渲染
public function _initView(Yaf_Dispatcher $dispatcher){
//在这里注册自己的view控制器,例如smarty,firekylin
Yaf_Dispatcher::getInstance()->disableView();//关闭其自动渲染
}
/**
初始化插件
**/
public function _initPlugin(Yaf_Dispatcher $dispatcher) {
$samplePlugin = new SamplePlugin ();
$dispatcher->registerPlugin($samplePlugin);
}
}
4:配置文件 /conf/application.ini
[common]
application.directory = APPLICATION_PATH"/application/"
application.dispatcher.catchException = True ;出错的时候是否抛出异常
application.dispatcher.catchException = True ;是否使用默认的异常捕捉
application.cache_config = 1
application.view.ext = "html"
application.modules = Index,User;声明存在的模块名
;application.library = local
;默认的module controller action
;application.dispatcher.defaultModule = Index
;application.dispatcher.defaultController = Index
;application.dispatcher.defaultAction = test
application.showErrors = 0
;;生产环境
[product : common]
;memcache配置信息
memcache.host.1 = 192.168.0.8
memcache.port = 11211
memcache.expire = 0
memcache.type = 'memcache'
memcache.isopen = 1 ;1:打开 0:关闭
;mongodb配置信息
mongodb.server = "mongodb://192.168.0.8:27017"
;mongodb.option.connect = True
;mongodb.option.timeout = 10
;mongodb.option.replicaset = ''
;mongodb.option.username = ''
;mongodb.option.password = ''
;mongodb.option.db = 'gcproduct'
;msyql读配置
mysql.read.host = 192.168.0.8
mysql.read.username = root
mysql.read.password = ******
mysql.read.dbname = ******
mysql.read.port = 3306
mysql.read.charset = UTF8
;msyql写库配置
mysql.write.host = 192.168.0.8
mysql.write.username = root
mysql.write.password = ******
mysql.write.dbname = ******
mysql.write.port = 3306
mysql.write.charset = UTF8
;开发环境 覆盖生产环境的配置
[development : product]
application.dispatcher.catchException = 1
application.cache_config = 0
application.view.ext = "html"
application.modules = Index,User
application.showErrors = 1
;正则路由
routes.regex_index.type = "regex"
routes.regex_index.match = "#^/$#"
routes.regex_index.route.module = User
routes.regex_index.route.controller = Index
routes.regex_index.route.action = index
routes.regex_index.map.1 = name
;关于企业
routes.regex_about.type = "regex"
routes.regex_about.match = "#^/about.html$#"
routes.regex_about.route.module = User
routes.regex_about.route.controller = Index
routes.regex_about.route.action = about
routes.regex_about.map.1 = name
routes.regex_about_d.type = "regex"
routes.regex_about_d.match = "#^/about/(\d*).html$#"
routes.regex_about_d.route.module = User
routes.regex_about_d.route.controller = Index
routes.regex_about_d.route.action = about
routes.regex_about_d.map.1 = id
5:/application/library/Db/Base.php 数据库的基础操作类
<?php
/**
数据库操作基础类
**/
class Db_Base
{
private static $_instance = null;//唯一实例.
private $_db; //数据库连接
private $_read_db = null; //读数据库连接
private $_write_db = null ; //写数据库连接
private $_read_config; //读库的配置
private $_write_config; //写库的配置
///////下面的函数主要是主从分离和获取数据库的链接操作
public function __construct(){
$config = Yaf_Registry::get('config')->mysql;//获取配置文件
$this->_read_config = $config->read; //读配置文件
$this->_write_config = $config->write; //写配置文件
$this->readConntection();//默认的为读库链接
}
//获取数据库的读写配置
public static function factory(){
if(self::$_instance === null){
self::$_instance = new self();
}
return self::$_instance;
}
//读库时的数据库链接
public function readConntection(){
if($this->_read_db != null){
$this->_db = $this->_read_db;
return;
}
$this->_read_db = $this->getConnection($this->_read_config);
$this->_db = $this->_read_db;
$this->_read_db->query("SET NAMES '{$this->_read_config['charset']}'");
}
//写库时的数据库链接
public function witeConntection(){
if($this->_write_db != null){
$this->_db = $this->_write_db;
return;
}
$this->_write_db = $this->getConnection($this->_write_config);
$this->_db = $this->_write_db;
$this->_write_db->query("SET NAMES '{$this->_read_config['charset']}'");
}
//创建数据库链接
public function getConnection($DbconfigArr = array()){
if(is_array($DbconfigArr)) {
throw new Exception("The DbcofigArr is not a array");
}
$db = new mysqli($DbconfigArr['host'],$DbconfigArr['username'],$DbconfigArr['password'],$DbconfigArr['dbname'],$DbconfigArr['port']);
if(mysqli_connect_errno()){
throw new Exception('Connect Error('.mysqli_connect_errno().')'.mysqli_connect_error());
}
return $db;
}
public function query($sqlUrl){
//读写分离
if(preg_match('/^\s*select/i',$sqlUrl)){
$this->readConntection();
}else{
$this->witeConntection();
}
$result = $this->_db->query($sqlUrl);
//最后一次调用产生的错误代码 返回0代表没有错误发生
if($this->_db->errno){
throw new Exception('Query Error('.mysqli_connect_errno().')'.mysqli_connect_error());
}
return $result;
}
//////下面的函数主要是根据需求获取不同查询需求:
////// 1.获取信息(单条、多条) 2.insert操作 3.update操作 4.delete操作 (批量操作) 5.获取相关信息的总数
///// 函数参数说明:1.数据库字段以array('field1','field2'...)获取,2:sql语句完善where部分
//获取结果中所有的行
public function fetchAssoc($sql){
$returnArr = array();
$result = $this->query($sql);
while($row = $result->fetch_assoc()){
$returnArr[] = $row;
}
$result ->free();
return $returnArr;
}
//获取结果中的第一行的值
public function fetchRow($sql){
$row = array();
$returnArr = array();
$result = $this->query($sql);
$row = $result->fetch_array(MYSQL_ASSOC);//获取第一条数据
if(empty($row)){
return array();
}
return $row;
}
//插入操作
public function insert($sql){
$this->witeConntection();
$result = $this->_db->query($sql);
return $this->_db->insert_id;
}
//更新删除操作
public function modify($sql){
$this->witeConntection();
$this->_db->query($sql);
return $this->_db->affected_rows;
}
///////对提供的参数进行主装成不同的sql语句
//把查询的字段数组主装成字符串
public function getFieldStr($arrayField = array()){
$newArr = array();
foreach($arrayField as $v){
$newArr[] ="`$v`";
}
return join(',',$newArr);
}
//获取对应数组的key对应的value并对其进行处理
private function _getValue($value){
if(empty($value)){
return "''";
}else if (is_string($value)){
return "'".self::$_instance->_db->real_escape_string($value)."'";
}else{
return "''";
}
}
//获取更新的字符串
public function getModifyStr($arrayFieldKeyValue = array()){
$returnArr = array();
foreach($arrayFieldKeyValue as $key=>$value){
$returnArr[] = "`".$key."`" . '=' . $this->_getValue($value);
}
return join(',',$returnArr);
}
public function getInsertStr($fieldArr = array()){
$field = array();
$value = array();
foreach($fieldArr as $f=>$v){
$field[] = "`".$f."`";
$value[] = "'".self::$_instance->_db->real_escape_string($v)."'";
}
return array(join(',',$field),join(',',$value));
}
}
6:/application/library/Db/Table.php 表的操作类继承Db_Base
<?php
/**
model类要继承的类
**/
class Db_Table extends Db_Base{
protected $_dataBaseName;//数据库名称
protected $_tableName;//表名
protected $_primaryKey;//主键
protected $_db;//数据库链接
//构造函数
public function __construct(){
$this->_db = Db_Base::factory();
}
//获取数据库名称和对应的表名
protected function _getDataBaseTableName(){
//有一个为空就是错误的
if(!(empty($this->_dataBaseName) || empty($this->_tableName))){
return $this->_dataBaseName.'.'.$this->_tableName;
}else{
throw new Exception("'The dataBaseName or tableName isn't empty!");
}
}
//获取对应的记录数
public function getCount($where = ''){
$count = array();
$sql = '';
if(empty($where)){
$sql = 'select count(*) as count from '.$this->_getDataBaseTableName();
}else{
$sql = 'select count(*) as count from '.$this->_getDataBaseTableName() .' where '.$where;
}
$count = $this->_db->fetchRow($sql);
return $count['count'];
}
/**
功能 :获取多条记录获取
参数说明:$field = array('field1','field2',...);//如果是全部的字段 $field = array();空数组
$whereArr = array('where'=>'','order'=->'','limit');//条件数组
**/
public function getAll($fieldArr = array(),$whereArr = array()){
//不是数组就报错
if(!is_array($whereArr) || !is_array($fieldArr)){
throw new Exception("'The whereArr or fieldArr isn't array!");
}
if(!empty($fieldArr)){
$fieldStr = $this->getFieldStr($fieldArr);
}else{
$fieldStr = '*';
}
//where 条件
isset($whereArr['where']) ? $whereStr = ' where '.$whereArr['where']:$whereStr = ' where 1=1 ';
//order条件
isset($whereArr['order']) ? $orderStr = ' order by '.$whereArr['order']:$orderStr = ' ';
//limit条件
isset($whereArr['limit']) ? $limitStr = ' limit '.$whereArr['limit']:$limitStr = ' limit 10 ';
$sql = 'SELECT '.$fieldStr.' from ' .$this->_getDataBaseTableName().$whereStr.$orderStr.$limitStr;
return $this->_db->fetchAssoc($sql);
}
/**
功能 ://获取单条记录
参数说明:$field = array('field1','field2',...);//如果是全部的字段 $field = array();空数组
$whereArr = array('where'=>'','order'=->'','limit');//条件数组
**/
public function getOne($fieldArr = array(),$whereArr = array()){
$resultArr = $this->getAll($fieldArr,$whereArr);
if(!empty($resultArr)){
return $resultArr['0'];
}
return array();
}
/**
功能 :删除操作
参数说明:$whereArr = array('where'=>'where');//条件数组 不能为空
**/
public function delete($whereArr = array()){
if(!empty($whereArr) && isset($whereArr['where'])){
$sql = "delete from ".$this->_getDataBaseTableName().' where '. $whereArr['where'];
}else{
throw new Exception("'The delete where is error!");
}
return $this->_db->modify($sql);
}
/**
功能 :更新操作
参数说明:$fieldArr = array('filed1'=>'value'....)
$whereArr = array('where'=>'where');//条件数组 不能为空
**/
public function update($fieldArr = array(),$whereArr = array()){
//不是数组就报错
if(!is_array($whereArr) || !is_array($fieldArr) || !isset($whereArr['where'])){
throw new Exception("'The whereArr or fieldArr isn't array!");
}
$sql = 'UPDATE '.$this->_getDataBaseTableName().' set '. $this->getModifyStr($fieldArr).' where '.$whereArr['where'];
return $this->_db->modify($sql);
}
/**
功能 :插入操作
参数说明:$fieldArr = array('filed1'=>'value'....)
**/
public function insert($fieldArr = array()){
list($field,$value) = $this->getInsertStr($fieldArr);
$sql = 'INSERT INTO '. $this->_getDataBaseTableName().'('.$field.') values ('.$value.')';
return $this->_db->insert($sql);
}
}
7:Smarty的适配器类:/application/library/Smarty/Adapter.php
<?php
Yaf_Loader::import( SMARTY_PATH."/Smarty.class.php");
Yaf_Loader::import( SMARTY_SYSPLUGINS_DIR ."smarty_internal_templatecompilerbase.php");
Yaf_Loader::import( SMARTY_SYSPLUGINS_DIR . "smarty_internal_templatelexer.php");
Yaf_Loader::import( SMARTY_SYSPLUGINS_DIR . "smarty_internal_templateparser.php");
Yaf_Loader::import( SMARTY_SYSPLUGINS_DIR . "smarty_internal_compilebase.php");
Yaf_Loader::import( SMARTY_SYSPLUGINS_DIR . "smarty_internal_write_file.php");
class Smarty_Adapter extends Smarty
{
public function __construct(){
parent::__construct();
}
}
8:Sys_Box :/application/library/Sys/Box.php 该类的作为暗箱可以根据类、方法名获取该类的方法并且方法的参数是以数组的形式方便处理,并相同类只用创建一次,然后由Box类管理。
<?php
/**
利用php的变量传导特性,建立一个资源调度类,来统一加载和调度需要的类并声明
同时利用反射类调用类中的方法
需要传递的方法为:
$_className:类的名字
$methodName:方法的名字
$avgArr = array("arvName"=>'value'....)
**/
class Sys_Box{
//声明一个进程内资源对象
public static $_modelObjArr = array();
//获取资源对象 默认$_typeStr = 'class'
public static function invoke($_className,$methodName,$avgArr = array()){
//检测变量是否合法
if(empty($_className) || empty($methodName) || !is_string($_className) || !is_string($methodName)){
echo "Argument is error";exit;
}
//资源已经存在不再创建
if(!isset(self::$_modelObjArr[$_className])){
//都是用本地类
if(!Yaf_Loader::getInstance()->isLocalName($_className)){
self::$_modelObjArr[$_className] = new $_className();
}else{
echo $_className." is not exists";exit;
}
}
//检测$_className是否存在$methodName方法
if(!method_exists(self::$_modelObjArr[$_className],$methodName)){
echo $_className." don't has the method:".$methodName;exit;
}
if(empty($avgArr)){
return self::$_modelObjArr[$_className]->$methodName();
}else{
return self::$_modelObjArr[$_className]->$methodName($avgArr);
}
}
//另外加载数据对象到静态数据组中去
public static function setObjArr($obj){
//检测是否存存在已经创建的好的对象
!isset(self::$_modelObjArr[$obj]) && self::$_modelObjArr[$obj] = $obj;
}
}
9:Memcache:/application/library/Sys/Memcache.php
<?php
/**
memcache的初始化及操作
public function get($avgArr)
public function set($avgArr)
public function delete($key)
**/
class Sys_Memcache{
private $_instance;//memcache对象
//初始化memcache
public function __construct(){
$this->_instance = new memcache();
$config = Yaf_Registry::get('config');//获取配置文件
$hostConfig = $config->memcache->host;//获取memcache配置信息
$port = $config->memcache->port;//端口
foreach($hostConfig as $key=>$value){
$this->_instance->addServer($value,$port);//添加memcache服务器
}
}
//$avgArr = {'key'} 获取memcache中缓存中的值 返回的数组仅仅包含从服务端找到的key-value对
public function get($avgArr){
return $this->_instance->get($avgArr);
}
//$avgArr = {'key','value','expire','flag'} 设置memcache中缓存的值 key value expire 为必选项
public function set($avgArr){
//对set的参数进行处理
if(isset($argArr['flag'])){//使用memcache_compressed指定的值进行压缩
return $this->_instance->set($avgArr['key'],$avgArr['value'],MEMCACHE_COMPRESSED,$avgArr['expire']);
}
return $this->_instance->set($avgArr['key'],$avgArr['value'],0,$avgArr['expire']);
}
//删除一个key对应的元素或者批量删除一个元素
public function delete($key){
$keyArr = array();
if(!is_array($key)){//单个key值
$keyArr[] = $key;
}else{
$keyArr = $key;
}
//删除缓存
foreach($keyArr as $k=>$v){
$this->_instance->delete($v);
}
}
}
10:Mongodb:
/application/library/Sys/Mongodb.php
<?php
/**
mongodb的扩展
**/
class Sys_mongodb{
private $_instance;
//初始化mongodb
public function __construct(){
$config = Yaf_Registry::get('config');//获取配置文件
$mongodbConfig = $config->mongodb;//mongodb全部配置对象
$server = $mongodbConfig->server;//获取mongodb的server信息
$option = $config->mongodb->option;//额外的参数
if(empty($option)){
$option = array();
}
$this->_instance = new Mongo($server,$option);
}
}
未完待续,接下来会优化并加入更多的功能。欢迎吐槽!!!
来源:oschina
链接:https://my.oschina.net/u/582440/blog/119198