InitPHP初探

引言:今天又认识了一种国产框架,InitPHP,它是一种小型框架。也是采用MVC三层架构。

用InitPHP开发,目录结构可以自由设置,只需要在配置文件中设置一下即可。

下载了initPHP的文件,解压后的文件夹是这样的:

这里主要的核心文件夹是initphp。demo是一些使用案例。manual是一些帮助文档,至于license.txt和README就更不用说了。所以只要留住一个initphp就可以了,其他的都可以删除。

点评:知道原理之后,就能抓住核心文件,敢于取舍。

其实initphp无所谓安装不安装,只需要把相应的文件夹建好之后,然后把配置文件修改一下,就可以了。

参考一下demo或者参考一下帮助文档,我建的目录如下:

其中conf是存放配置文件的,data存放缓存文件,initphp是核心文件目录,library存放一些扩展,这里把数据库辅助文件放于其中。static存放的是一些静态文件,比如js、css等等。web是主要的内容,控制器,视图界面存放其中。

.htaccess文件是Apache服务器中的一个配置文件,它负责相关目录下的网页配置。通过htaccess文件,可以帮我们实现:网页301重定向、自定义404错误页面、改变文件扩展名、允许/阻止特定的用户或者目录的访问、禁止目录列表、配置默认文档等功能。

蛮好玩的,index.php是入口文件,进入的时候,加载一些配置信息和基础目录。

下面是重定向文件中的代码内容,很有趣,主要用的是正则表达式的一些语法。

RewriteEngine on
#RewriteRule !uploadfile index.php
RewriteRule !\.(js|ico|gif|jpg|png|css|swf|htm|php|txt|zip|html|xml|ur|pptx|ppt|pdf|mp3|mp4|db3|doc|docx|xls|xlsx)$|uploadfile/*|phpmyadmin/*$ ./index.php

只要路径中包含一些乱七八糟的内容,都可以将其重定向到index.php入口文件中。

下面我们来走一走流程,

index.php内容:

<?php
define("APP_PATH", "./"); 
header("Content-Type:text/html; charset=utf-8");   
require_once('./initphp/initphp.php'); //导入配置文件-必须载入
require_once(APP_PATH . 'conf/comm.conf.php'); //公用配置
InitPHP::init(); //框架初始化 

主要是引入主文件,和配置文件。

配置文件很重要,它就像一把钥匙,正确的在这些目录结构中行走,以及在数据库中行走。

<?php
/*********************************************************************************
 * InitPHP 3.2.2 国产PHP开发框架  
 *-------------------------------------------------------------------------------
 * 版权所有: CopyRight By initphp.com
 * 您可以自由使用该源码,但是在使用过程中,请保留作者信息。尊重他人劳动成果就是尊重自己
 *-------------------------------------------------------------------------------
 * $Author:zhuli
 * $Dtime:2012-11-27
***********************************************************************************/
/* 框架全局配置常量 */ 
define('INITPHP_PATH', dirname(__FILE__)); 
define('IS_INITPHP', 1);
error_reporting(E_ERROR | E_PARSE); 
/* 框架全局配置变量 */
$InitPHP_conf = array();
/*********************************基础配置*****************************************/
/**
 * 站点URL配置
 * 必选参数
 */
$InitPHP_conf['url'] = 'http://localhost/initphp_demo/';  
/**
 * 是否开启调试
 */
$InitPHP_conf['is_debug'] = true; //开启-正式上线请关闭
/**
 * 路由访问方式
 * 1. 如果为true 则开启path访问方式,否则关闭
 * 2. default:index.php?m=user&c=index&a=run
 * 3. rewrite:/user/index/run/?id=100
 * 4. path: /user/index/run/id/100
 * 5. html: user-index-run.htm?uid=100
 * 6. 开启PATH需要开启APACHE的rewrite模块,详细使用会在文档中体现
 */
$InitPHP_conf['isuri'] = 'default'; 
/**
 * 是否开启输出自动过滤
 * 1. 对多人合作,安全性可控比较差的项目建议开启
 * 2. 对HTML进行转义,可以放置XSS攻击
 * 3. 如果不开启,则提供InitPHP::output()函数来过滤
 */
$InitPHP_conf['isviewfilter'] = false; 

/*********************************DAO数据库配置*****************************************/
/**
 * Dao配置参数
 * 1. 你可以配置Dao的路径和文件(类名称)的后缀名
 * 2. 一般情况下您不需要改动此配置
 */
$InitPHP_conf['dao']['dao_postfix']  = 'Dao'; //后缀
$InitPHP_conf['dao']['path']  = 'library/dao/'; //后缀
/**
 * 数据库配置
 * 1. 根据项目的数据库情况配置
 * 2. 支持单数据库服务器,读写分离,随机分布的方式
 * 3. 可以根据$InitPHP_conf['db']['default']['db_type'] 选择mysql mysqli(暂时支持这两种)
 * 4. 支持多库配置 $InitPHP_conf['db']['default']
 * 5. 详细见文档
 */
$InitPHP_conf['db']['driver']   = 'mysqli'; //选择不同的数据库DB 引擎,一般默认mysqli,或者mysqls 
//default数据库配置 一般使用中 $this->init_db('default')-> 或者 $this->init_db()-> 为默认的模型
$InitPHP_conf['db']['default']['db_type']                   = 0; //0-单个服务器,1-读写分离,2-随机
$InitPHP_conf['db']['default'][0]['host']                   = '127.0.0.1'; //主机
$InitPHP_conf['db']['default'][0]['username']               = 'root'; //数据库用户名
$InitPHP_conf['db']['default'][0]['password']               = ''; //数据库密码
$InitPHP_conf['db']['default'][0]['database']               = 'test'; //数据库
$InitPHP_conf['db']['default'][0]['charset']                = 'utf8'; //数据库编码   
$InitPHP_conf['db']['default'][0]['pconnect']               = 0; //是否持久链接


//test数据库配置 使用:$this->init_db('test')->  支持读写分离,随机选择(有两个数据库)
$InitPHP_conf['db']['test']['db_type']                      = 2; //0-单个服务器,1-读写分离,2-随机
$InitPHP_conf['db']['test'][0]['host']                      = '127.0.0.1'; //主机
$InitPHP_conf['db']['test'][0]['username']                  = 'root'; //数据库用户名
$InitPHP_conf['db']['test'][0]['password']                  = ''; //数据库密码
$InitPHP_conf['db']['test'][0]['database']                  = 't1'; //数据库
$InitPHP_conf['db']['test'][0]['charset']                   = 'utf8'; //数据库编码   
$InitPHP_conf['db']['test'][0]['pconnect']                  = 0; //是否持久链接

$InitPHP_conf['db']['test'][1]['host']                      = '127.0.0.1'; //主机
$InitPHP_conf['db']['test'][1]['username']                  = 'root'; //数据库用户名
$InitPHP_conf['db']['test'][1]['password']                  = ''; //数据库密码
$InitPHP_conf['db']['test'][1]['database']                  = 't1'; //数据库
$InitPHP_conf['db']['test'][1]['charset']                   = 'utf8'; //数据库编码   
$InitPHP_conf['db']['test'][1]['pconnect']                  = 0; //是否持久链接

/*********************************Service配置*****************************************/
/**
 * Service配置参数
 * 1. 你可以配置service的路径和文件(类名称)的后缀名
 * 2. 一般情况下您不需要改动此配置
 */
$InitPHP_conf['service']['service_postfix']  = 'Service'; //后缀
$InitPHP_conf['service']['path'] = 'library/service/'; //service路径

/*********************************Controller配置*****************************************/
/**
 * Controller控制器配置参数
 * 1. 你可以配置控制器默认的文件夹,默认的后缀,Action默认后缀,默认执行的Action和Controller
 * 2. 一般情况下,你可以不需要修改该配置参数
 * 3. $InitPHP_conf['ismodule']参数,当你的项目比较大的时候,可以选用module方式,
 * 开启module后,你的URL种需要带m的参数,原始:index.php?c=index&a=run, 加module:
 * index.php?m=user&c=index&a=run , module就是$InitPHP_conf['controller']['path']目录下的
 * 一个文件夹名称,请用小写文件夹名称
 */
$InitPHP_conf['ismodule'] = false; //开启module方式
$InitPHP_conf['controller']['path']                  = 'web/controller/'; 
$InitPHP_conf['controller']['controller_postfix']    = 'Controller'; //控制器文件后缀名
$InitPHP_conf['controller']['action_postfix']        = ''; //Action函数名称后缀
$InitPHP_conf['controller']['default_controller']    = 'index'; //默认执行的控制器名称
$InitPHP_conf['controller']['default_action']        = 'index'; //默认执行的Action函数
$InitPHP_conf['controller']['module_list']           = array('test', 'index'); //module白名单
$InitPHP_conf['controller']['default_module']        = 'index'; //默认执行module
$InitPHP_conf['controller']['default_before_action'] = 'before'; //默认前置的ACTION名称
$InitPHP_conf['controller']['default_after_action']  = 'after'; //默认后置ACTION名称

/*********************************View配置*****************************************/
/**
 * 模板配置
 * 1. 可以自定义模板的文件夹,编译模板路径,模板文件后缀名称,编译模板后缀名称
 * 是否编译,模板的驱动和模板的主题
 * 2. 一般情况下,默认配置是最优的配置方案,你可以不选择修改模板文件参数
 */
$InitPHP_conf['template']['template_path']      = 'web/template'; //模板路径
$InitPHP_conf['template']['template_c_path']    = 'data/template_c'; //模板编译路径 
$InitPHP_conf['template']['template_type']      = 'htm'; //模板文件类型  
$InitPHP_conf['template']['template_c_type']    = 'tpl.php';//模板编译文件类型 
$InitPHP_conf['template']['template_tag_left']  = '<!--{';//模板左标签
$InitPHP_conf['template']['template_tag_right'] = '}-->';//模板右标签
$InitPHP_conf['template']['is_compile']         = true;//模板每次编译-系统上线后可以关闭此功能
$InitPHP_conf['template']['driver']             = 'simple'; //不同的模板驱动编译
$InitPHP_conf['template']['theme']              = ''; //模板主题

/*********************************Hook配置*****************************************/
/**
 * 插件Hook配置
 * 1. 如果你需要使用InitPHP::hook() 钩子函数来实现插件功能
 * 2. 详细查看钩子的使用方法
 */
$InitPHP_conf['hook']['path']          = 'hook'; //插件文件夹目录, 不需要加'/'
$InitPHP_conf['hook']['class_postfix'] = 'Hook'; //默认插件类名后缀
$InitPHP_conf['hook']['file_postfix']  = '.hook.php'; //默认插件文件名称
$InitPHP_conf['hook']['config']        = 'hook.conf.php'; //配置文件

/*********************************单元测试*****************************************/
/**
 * 单元测试
 * 1. 使用工具库中的单元测试需要配置
 */
$InitPHP_conf['unittesting']['test_postfix'] = $InitPHP_conf['service']['service_postfix'] . 'Test';
$InitPHP_conf['unittesting']['path'] = 'library/test/'; 

/*********************************Error*****************************************/
/**
 * Error模板
 * 如果使用工具库中的error,需要配置
 */
$InitPHP_conf['error']['template'] = 'library/helper/error.tpl.php';

/*********************************缓存,Nosql配置*****************************************/
/**
 * 缓存配置参数
 * 1. 您如果使用缓存 需要配置memcache的服务器和文件缓存的缓存路径
 * 2. memcache可以配置分布式服务器,根据$InitPHP_conf['memcache'][0]的KEY值去进行添加
 * 3. 根据您的实际情况配置
 */
$InitPHP_conf['memcache'][0]   = array('127.0.0.1', '11211');  
$InitPHP_conf['cache']['filepath'] = 'data/filecache';   //文件缓存目录
/**
 * MongoDB配置,如果您使用了mongo,则需要配置
 */
$InitPHP_conf['mongo']['default']['server']     = '127.0.0.1';
$InitPHP_conf['mongo']['default']['port']       = '27017';
$InitPHP_conf['mongo']['default']['option']     = array('connect' => true);
$InitPHP_conf['mongo']['default']['db_name']    = 'test';
$InitPHP_conf['mongo']['default']['username']   = '';
$InitPHP_conf['mongo']['default']['password']   = '';
/**
 * Redis配置,如果您使用了redis,则需要配置
 */
$InitPHP_conf['redis']['default']['server']     = '127.0.0.1';
$InitPHP_conf['redis']['default']['port']       = '6379';

设置了一些默认信息,比如dao的目录

controller的目录

template的目录

默认的数据库

用户名、及密码

是否开启调试等等。

点评:

学习框架,就要进入底层,扒掉它的衣服,甚至进行各种改造。

我想这个时候,入口文件,就会到达默认的控制器下面了,也就是index控制器,并且进入其中的默认的方法,以前是run,现在被我改成了index了。

<?php
/**
 * DEMO
 * @author zhuli 
 */
class indexController extends Controller {
    
    public $initphp_list = array('post'); //Action白名单

    public function index() {    
        $this->view->display("index/index"); //展示模板页面
    }
    
    public function post() {
        $user = $this->controller->get_gp(array('username', 'password'));
        $result = $this->_getUserDao()->addUser($user);
        if ($result > 0) {
            echo '新增用户成功 ID:' . $result;
        } else {
            echo '新增失败';
        }
        
    }
    
    /**
     * @return userDao
     */
    private function _getUserDao() {
        return InitPHP::getDao("user");
    }
} 

index方法直接进入到视图界面中,视图界面存在template目录下的index目录下的index.htm

其内容如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Form POST提交数据例子</title>
</head>

<body>
表单提交:<br/><br/>
<form action="?c=index&a=post" method="post">
用户名:<input value="" name="username"><br/><br/>
密码:<input value="" name="password"><br/><br/>
<input type="submit"/>
</form>
</body>
</html>

它就是一个表单信息

用户输入用户名,密码

然后提交表单,到index中的post方法下

post对数据进行处理并保存。

这里的路由机制很简单?c=index&a=post  c表示控制器,a表示方法。

public function post() {
        $user = $this->controller->get_gp(array('username', 'password'));
        $result = $this->_getUserDao()->addUser($user);
        if ($result > 0) {
            echo '新增用户成功 ID:' . $result;
        } else {
            echo '新增失败';
        }
        
    }

调用私有方法,_getUserDao()

 private function _getUserDao() {
        return InitPHP::getDao("user");
    }

返回一个dao对象,执行其中的addUser方法。

<?php 
class userDao extends Dao {
    
    public $table_name = 'user';
    private $fields = "username,password";
    
    /**
     * 新增用户
     * @param $user
     */
    public function addUser($user) {
        $user = $this->dao->db->build_key($user, $this->fields);
        return $this->dao->db->insert($user, $this->table_name);
    }
}

完成对数据的添加动作。

整个流程就结束了。一气呵成。结构清晰。

此时,我还想看看源码,核心源码如下,有兴趣的可以研读一下。。。

<?php
/*********************************************************************************
 * InitPHP 3.2.2 国产PHP开发框架  框架入口文件 核心框架文件
 *-------------------------------------------------------------------------------
 * 版权所有: CopyRight By initphp.com
 * 您可以自由使用该源码,但是在使用过程中,请保留作者信息。尊重他人劳动成果就是尊重自己
 *-------------------------------------------------------------------------------
 * $Author:zhuli
 * $Dtime:2012-11-27
***********************************************************************************/
require_once('initphp.conf.php'); //导入框架配置类
require_once('init/core.init.php'); //导入核心类文件
require_once('init/exception.init.php'); //导入核心类文件
class InitPHP extends coreInit {

    public static $time;

    /**
     * 【静态】运行InitPHP开发框架 - 框架运行核心函数
     * 1. 在index.php中实例化InitPHP启动类 InitPHP::init();
     * 2. 初始化网站路由,运行框架
     * 3. 全局使用方法:InitPHP::init(); 
     * @return object
     */
    public static function init() { 
        try {
            require(INITPHP_PATH . '/init/dispatcher.init.php');
            require(INITPHP_PATH . '/init/run.init.php'); 
            $dispacher = InitPHP::loadclass('dispatcherInit');
            $dispacher->dispatcher();
            $run = InitPHP::loadclass('runInit');
            $run->run();
        } catch (exceptionInit $e) {
            $e->errorMessage();
        }
    }
    
    /**
     * 【静态】命令行模式运行php
     * 1. 例如:/usr/lib/php /usr/local/web/www/index.php index test sql
     * 2. index 控制器名称 test Action名称 sql controller/文件夹下的文件名称
     * 3. 全局使用方法:InitPHP::cli_init(); 
     * @return object
     */
    public static function cli_init($argv) {
        try {
            $InitPHP_conf = InitPHP::getConfig();
            $argv[1] = ($argv[1] == '') ? '' : trim($argv[1]) . $InitPHP_conf['controller']['controller_postfix'];
            $argv[2] = ($argv[2] == '') ? '' : trim($argv[2]) . $InitPHP_conf['controller']['action_postfix'];
            $argv[3] = ($argv[3] == '') ? '' : trim($argv[3]);
            InitPHP::getController($argv[1], $argv[2], $params = array(), $argv[3]);
        } catch (exceptionInit $e) {
            $e->errorMessage();
        }
    }

    /**
     * 【静态】框架加载文件函数 - 核心加载文件
     * 1. 自定义文件路径,加载文件
     * 2. 自定义文件路径数组,自动查询,找到文件返回TRUE,找不到返回false
     * 全局使用方法:InitPHP::import($filename, $pathArr);
     * @param $filename 文件名称
     * @param $pathArr  文件路径
     * @return file
     */
    public static function import($filename_old, array $pathArr = array()) {
        $filename = InitPHP::getAppPath($filename_old);
        $temp_name = md5($filename);
        if (isset(parent::$instance['importfile'][$temp_name])) return true; //已经加载该文件,则不重复加载
        if (@is_readable($filename) == true && empty($pathArr)) {
            require($filename);
            parent::$instance['importfile'][$temp_name] = true; //设置已加载
            return true;
        } else {
            /* 自动搜索文件夹 */
            foreach ($pathArr as $val) {
                $new_filename = rtrim($val, '/') . '/' . $filename_old;
                $new_filename = InitPHP::getAppPath($new_filename);
                if (isset(parent::$instance['importfile'][$temp_name])) return true;
                if (@is_readable($new_filename)) {
                    require($new_filename);// 载入文件
                    parent::$instance['importfile'][$temp_name] = true;
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 【静态】框架实例化php类函数,单例模式
     * 1. 单例模式-单例 实例化一个类
     * 2. 可强制重新实例化
     * 全局使用方法:InitPHP::loadclass($classname, $force = false);
     * @param string $classname
     * @return object
     */
    public static function loadclass($classname, $force = false) {
        if (preg_match('/[^a-z0-9\-_.]/i', $classname)) InitPHP::initError('invalid classname');
        if ($force == true) unset(parent::$instance['loadclass'][$classname]);
        if (!isset(parent::$instance['loadclass'][$classname])) {
            if (!class_exists($classname)) InitPHP::initError($classname . ' is not exist!');
            $Init_class = new $classname;
            parent::$instance['loadclass'][$classname] = $Init_class;
        }
        return parent::$instance['loadclass'][$classname];
    }

    /**
     * 【静态】框架hook插件机制
     * 1. 采用钩子挂载机制,一个钩子上可以挂载多个执行
     * 2. hook机制需要配置框架配置文件运行
     * 全局使用方法:InitPHP::hook($hookname, $data = '');
     * @param string $hookname 挂钩名称
     * @param string $data   传递的参数
     * @return
     */
    public static function hook($hookname, $data = '') {
        $InitPHP_conf = InitPHP::getConfig();
        $hookconfig = $InitPHP_conf['hook']['path'] . '/' . $InitPHP_conf['hook']['config']; //配置文件
        $hookconfig = InitPHP::getAppPath($hookconfig);
        if (!isset(parent::$instance['inithookconfig']) && file_exists($hookconfig)) {
            parent::$instance['inithookconfig'] = require_once($hookconfig);
        }
        if (!isset(parent::$instance['inithookconfig'][$hookname])) return false;
        if (!is_array(parent::$instance['inithookconfig'][$hookname])) {
            self::_hook(parent::$instance['inithookconfig'][$hookname][0], parent::$instance['inithookconfig'][$hookname][1], $data);
        } else {
            foreach (parent::$instance['inithookconfig'][$hookname] as $v) {
                self::_hook($v[0], $v[1], $data);
            }
        }
    }

    /**
     *    【静态】框架hook插件机制-私有
     *  @param  string $class  钩子的类名
     *  @param  array  $function  钩子方法名称
     *  @param  string $data 传递的参数
     *  @return object
     */
    private static function _hook($class, $function, $data = '') {
        $InitPHP_conf = InitPHP::getConfig();
        if (preg_match('/[^a-z0-9\-_.]/i', $class)) return false;
        $file_name  = $InitPHP_conf['hook']['path'] . '/' . $class . $InitPHP_conf['hook']['file_postfix'];
        $file_name  = InitPHP::getAppPath($file_name);
        $class_name = $class . $InitPHP_conf['hook']['class_postfix']; //类名
        if (!file_exists($file_name)) return false;
        if (!isset(parent::$instance['inithook'][$class_name])) {
            require_once($file_name);
            if (!class_exists($class_name)) return false;
            $init_class = new $class_name;
            parent::$instance['inithook'][$class_name] = $init_class;
        }
        if (!method_exists($class_name, $function)) return false;
        return parent::$instance['inithook'][$class_name]->$function($data);
    }

    /**
     * 【静态】XSS过滤,输出内容过滤
     * 1. 框架支持全局XSS过滤机制-全局开启将消耗PHP运行
     * 2. 手动添加XSS过滤函数,在模板页面中直接调用
     * 全局使用方法:InitPHP::output($string, $type = 'encode');
     * @param string $string  需要过滤的字符串
     * @param string $type    encode HTML处理 | decode 反处理
     * @return string
     */
    public static function output($string, $type = 'encode') {
        $html = array("&", '"', "'", "<", ">", "%3C", "%3E");
        $html_code = array("&amp;", "&quot;", "&#039;", "&lt;", "&gt;", "&lt;", "&gt;");
        if ($type == 'encode') {
            if (function_exists('htmlspecialchars')) return htmlspecialchars($string);
            $str = str_replace($html, $html_code, $string);
        } else {
            if (function_exists('htmlspecialchars_decode')) return htmlspecialchars_decode($string);
            $str = str_replace($html_code, $html, $string);
        }
        return $str;
    }

    /**
     * 【静态】获取Service-实例并且单例模式获取Service
     * 1.单例模式获取
     * 2.可以选定对应Service路径path
     * 3. service需要在配置文件中配置参数,$path对应service目录中的子目录
     * 全局使用方法:InitPHP::getService($servicename, $path = '')
     * @param string $servicename 服务名称
     * @param string $path 路径
     * @return object
     */
    public static function getService($servicename, $path = '') {
        $InitPHP_conf = InitPHP::getConfig();
        $path  = ($path == '') ? '' : $path . '/';
        $class = $servicename . $InitPHP_conf['service']['service_postfix'];
        $file  = rtrim($InitPHP_conf['service']['path'], '/') . '/' . $path . $class . '.php';
        if (!InitPHP::import($file)) return false;
        return InitPHP::loadclass($class);
    }

    /**
     * 【静态】获取Dao-实例并且单例模式获取Dao
     * 1.单例模式获取
     * 2.可以选定Dao路径path
     * 3. dao需要在配置文件中配置参数,$path对应dao目录中的子目录
     * 全局使用方法:InitPHP::getDao($daoname, $path = '')
     * @param string $daoname 服务名称
     * @param string $path 路径
     * @return object
     */
    public static function getDao($daoname, $path = '') {
        $InitPHP_conf = InitPHP::getConfig();
        $path  = ($path == '') ? '' : $path . '/';
        $class = $daoname . $InitPHP_conf['dao']['dao_postfix'];
        $file  = rtrim($InitPHP_conf['dao']['path'], '/') . '/' . $path . $class . '.php';
        if (!InitPHP::import($file)) return false;
        $obj = InitPHP::loadclass($class);
        return $obj;
    }

    /**
     * 【静态】组装URL
     * default:index.php?m=user&c=index&a=run
      * rewrite:/user/index/run/?id=100
      * path: /user/index/run/id/100
     * html: user-index-run.htm?uid=100
      * 全局使用方法:InitPHP::url('user|delete', array('id' => 100))
     * @param String $action  m,c,a参数,一般写成 cms|user|add 这样的m|c|a结构
     * @param array  $params  URL中其它参数
     * @param String $baseUrl 是否有默认URL,如果有,则
     */
    public static function url($action, $params = array(), $baseUrl = '') {
        $InitPHP_conf = InitPHP::getConfig();
        $action = explode("|", $action);
        $baseUrl = ($baseUrl == '') ? $InitPHP_conf['url'] : $baseUrl;
        $baseUrl = rtrim($baseUrl, '/') . '/';
        $ismodule = $InitPHP_conf['ismodule'];
        switch ($InitPHP_conf['isuri']) {

            case 'rewrite' :
                $actionStr = implode('/', $action);
                $paramsStr = '';
                if ($params) {
                    $paramsStr = '?' . http_build_query($params);
                }
                return $baseUrl . $actionStr . $paramsStr;
                break;
            
            case 'path' :
                $actionStr = implode('/', $action);
                $paramsStr = '';
                if ($params) {
                    foreach ($params as $k => $v) {
                        $paramsStr .= $k . '/' . $v . '/';
                    }
                    $paramsStr = '/' . $paramsStr;
                }
                return $baseUrl . $actionStr . $paramsStr;
                break;
                
            case 'html' :
                $actionStr = implode('-', $action);
                $actionStr = $actionStr . '.htm';
                $paramsStr = '';
                if ($params) {
                    $paramsStr = '?' . http_build_query($params);
                }
                return $baseUrl . $actionStr . $paramsStr;
                break;
            
            default:
                $actionStr = '';
                if ($ismodule === true) {
                    $actionStr .= 'm=' . $action[0];
                    $actionStr .= '&c=' . $action[1];
                    $actionStr .= '&a=' . $action[2] . '&';
                } else {
                    $actionStr .= 'c=' . $action[0];
                    $actionStr .= '&a=' . $action[1] . '&';
                } 
                $actionStr = '?' . $actionStr;
                $paramsStr = '';
                if ($params) {
                    $paramsStr = http_build_query($params);
                }
                return $baseUrl . $actionStr . $paramsStr;
                break;
        }
    }

    /**
     * 【静态】获取时间戳
     * 1. 静态时间戳函数
     * 全局使用方法:InitPHP::getTime();
     * @param $msg
     * @return html
     */
    public static function getTime() {
        if (self::$time > 0) return self::$time;
        self::$time = time();
        return self::$time;
    }

    /**
     * 框架控制访问器,主要用来控制是否有权限访问该模块
     * 1. InitPHP 页面访问主要通过3个参数来实现,m=模型,c=控制器,a=Action。m模型需要在应用开启模型的情况下执行
     * 2. $config是用户具体业务逻辑中,包含的用户访问权限白名单,我们根据白名单列表去判断用户是否具备权限
     * 3. 具备访问权限,返回true,否则false
     * 4. 返回false之后的具体业务逻辑需要用户自己做相应处理
     * 5. 开启$InitPHP_conf['ismodule']配置结构
     * array(
     *     '模型名称' => array(
     *       '控制器名称' => array('run', 'test', 'Action名称')
     *     )
     * )
     * 6. 关闭$InitPHP_conf['ismodule']配置结构
     * array(
     *    '控制器名称' => array('run', 'test', 'Action名称')
     * )
     * 7. 默认为空,则全部有权限
     * @param array $config
     */
    public static function acl($config = array()) {
        $InitPHP_conf = InitPHP::getConfig();
        if (!is_array($config) || empty($config)) return true;
        $c = ($_GET['c']) ? $_GET['c'] : $InitPHP_conf['controller']['default_controller'];
        $a = ($_GET['a']) ? $_GET['a'] : $InitPHP_conf['controller']['default_action'];
        if ($InitPHP_conf['ismodule']) {
            $m = $_GET['m'];
            if (isset($config[$m]) && isset($config[$m][$c]) && in_array($a, $config[$c]))
                return true;
            return false;
        } else {
            if (isset($config[$c]) && in_array($a, $config[$c]))
                return true;
            return false;
        }
    }

    /**
     * 【静态】获取全局配置文件
     * 全局使用方法:InitPHP::getConfig()
     * @param $msg
     * @return Array
     */
    public static function getConfig() {
        global $InitPHP_conf;
        return $InitPHP_conf;
    }
    
    /**
     * 设置配置文件,框架意外慎用!
     * @param $key
     * @param $value
     */
    public static function setConfig($key, $value) {
        global $InitPHP_conf;
        $InitPHP_conf[$key] = $value;
        return $InitPHP_conf;
    }
    
    /**
     * 【静态】获取项目路径
     * 全局使用方法:InitPHP::getAppPath('data/file.php')
     * @param $path
     * @return String
     */
    public static function getAppPath($path = '') {
        if (!defined('APP_PATH')) return $path;
        return rtrim(APP_PATH, '/') . '/' . $path;
    }

    /**
     * 【静态】框架错误机制
     * 1. 框架的错误信息输出函数,尽量不要使用在项目中
     * 全局使用方法:InitPHP::initError($msg)
     * @param $msg
     * @return html
     */
    public static function initError($msg, $code = 10000) {
        throw new exceptionInit($msg, $code);
    }
    
    /**
     * 【静态】调用其它Controller中的方法
     * 1. 一般不建议采用Controller调用另外一个Controller中的方法
     * 2. 该函数可以用于接口聚集,将各种接口聚集到一个接口中使用
     * 全局使用方法:InitPHP::getController($controllerName, $functionName)
     * @param $controllerName 控制器名称
     * @param $functionName   方法名称
     * @param $params         方法参数
     * @param $controllerPath 控制器文件夹名称,例如在控制器文件夹目录中,还有一层目录,user/则,该参数需要填写
     * @return 
     */
    public function getController($controllerName, $functionName, $params = array(), $controllerPath = '') {
        $InitPHP_conf = InitPHP::getConfig();
        $controllerPath = ($controllerPath == '') ? '' : rtrim($controllerPath, '/') . '/';
        $path = rtrim($InitPHP_conf['controller']['path'], '/') . '/' . $controllerPath . $controllerName . '.php';
        InitPHP::import($path);
        $controller = InitPHP::loadclass($controllerName);
        if (!$controller) 
            return InitPHP::initError('can not loadclass : ' . $controllerName);
        if (!method_exists($controller, $functionName)) 
            return InitPHP::initError('function is not exists : ' . $controllerName);
        if (!$params) {
            $controller->$functionName();
        } else {
            call_user_func_array(array($controller, $functionName), $params); 
        }
    }

}

/**
 * 控制器Controller基类
 * 1. 每个控制器都需要继承这个基类
 * 2. 通过继承这个基类,就可以直接调用框架中的方法
 * 3. 控制器中可以直接调用$this->contorller 和 $this->view
 * @author zhuli
 */
class Controller extends coreInit {

    /**
     * @var controllerInit
     */
    protected $controller;

    /**
     * @var viewInit
     */
    protected $view;

    /**
     * 初始化 
     */
    public function __construct() {
        parent::__construct();
        $InitPHP_conf = InitPHP::getConfig();
        $this->controller = $this->load('controller', 'c'); //导入Controller
        $this->view       = $this->load('view', 'v'); //导入View
        $this->view->set_template_config($InitPHP_conf['template']); //设置模板
        $this->view->assign('init_token', $this->controller->get_token()); //全局输出init_token标记
        //注册全局变量,这样在Service和Dao中通过$this->common也能调用Controller中的类
        $this->register_global('common', $this->controller); 
    }
}

/**
 * 服务Service基类
 * 1. 每个Service都需要继承这个基类
 * 2. 通过继承这个基类,就可以直接调用框架中的方法
 * 3. Service中可以直接调用$this->service
 * @author zhuli
 */
class Service extends coreInit {

    /**
     * @var serviceInit
     */
    protected $service;

    /**
     * 初始化
     */
    public function __construct() {
        parent::__construct();
        $this->service = $this->load('service', 's'); //导入Service
    }
}

/**
 * 数据层Dao基类
 * 1. 每个Dao都需要继承这个基类
 * 2. 通过继承这个基类,就可以直接调用框架中的方法
 * 3. Dao中可以直接调用$this->dao
 * 4. $this->dao->db DB方法库
 * 5. $this->dao->cache Cache方法库
 * @author zhuli
 */
class Dao extends coreInit {

    /**
     * @var daoInit
     */
    protected $dao;

    /**
     * 初始化
     */
    public function __construct() {
        $this->dao = $this->load('dao', 'd'); //导入D
        $this->dao->run_db(); //初始化db
        $this->dao->run_cache(); //初始化cahce
    }

    /**
     * 分库初始化DB
     * 如果有多数据库链接的情况下,会调用该函数来自动切换DB link
     * @param string $db
     * @return dbInit
     */
    public function init_db($db = 'default') {
        $this->dao->db->init_db($db);
        return $this->dao->db;
    }
}
原文地址:https://www.cnblogs.com/jiqing9006/p/3044904.html