• 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;
        }
    }
  • 相关阅读:
    装箱、拆箱操作发生在
    @Data的注解使用以及在IDEA上安装
    Mysql中 BLOB字段转String的方法
    不属于java语言鲁棒性特点的是
    java object默认的基本方法
    哪个类可用于处理 Unicode?
    类和接口的继承
    抽象类的叙述:
    Hashtable 和 HashMap 的区别是:
    编程之美初赛第一场--焦距
  • 原文地址:https://www.cnblogs.com/jiqing9006/p/3044904.html
Copyright © 2020-2023  润新知