zoukankan      html  css  js  c++  java
  • php框架之自动加载与统一入口

    现在PHP有很多的框架,基本都是以MVC为基础进行设计的。其实很多框架(像thinkphp,zf,symfont等)都有两个特性,自动加载类文件和统一入口。这里就简单实现以上两个特性。

    假设PHP使用的版本在5.3以上,5.3以上支持命名空间

    自动加载类文件:
        我们做__autoload来实现,现在PHP官方是建议使用spl_autoload去实现,具体好处自己去google吧。这里还是简单的用__autoload去实现,来学习自动加载的原理。
        目录结构:

       
        inc.php:

    <?php
    function __autoload($clsName){
        $clsInfo = explode("\", $clsName);
        $len = count($clsInfo);
        $clsName = $clsInfo[$len - 1];
        if($len == 1){
            $clsInfo[$len - 1] = '/home/wwwroot/domain.com/library';
        }else{
            $pref = substr($clsName, 0, 3);
            $clsInfo[0] = '/home/wwwroot/domain.com/module/' . $clsInfo[0];
            if($pref == 'ctl'){
                $clsInfo[$len - 1] = 'control';
            }elseif($pref = 'mdl'){
                $clsInfo[$len - 1] = 'module';
            }else{
                $clsInfo[$len - 1] = 'library';
            }
        }
        $clsFile = implode("/", $clsInfo) . "/" . $clsName . ".php";
        $clsFile = realpath($clsFile);
        if($clsFile){
            require_once($clsFile);
        }else{
            exit("{$clsFile} is not exists!!");
        }
    }

        上面这个加载函数的应用实例:

        require_once(inc.php);
        new libEntry();//加载/home/wwwroot/domain.com/libEntry.php
        new /libEntry(); //加载/home/wwwroot/domain.com/library/libEntry.php
        new /index/clsIndex(); //加载/home/wwwroot/domain.com/module/index/control/clsIndex.php
        new /index/mdlDb(); //加载/home/wwwroot/domain.com/module/index/module/mdlDb.php
        new /index/libUser(); //加载/home/wwwroot/domain.com/module/index/library/libUser.php

       
    统一入口:
        libRouter.php:

    <?php
    class libRouter{
        private $entry;
        private $control;
        private $method;
    
        function __construct(){
            $url = $_GET['_URL_'];
            $urlInfo = explode('/', trim($url, '/'));
            $this->entry = $urlInfo[0];
            $module = $urlInfo[1];
            $params = explode('-', $module);
            $len = count($params);
            $this->control = $params[0];
            if($len % 2 == 0){
                $this->method = $params[1];
                unset($params[1]);
            }else{
                $this->method = '';
            }
            unset($params[0]);
            $data = array_values($params);
            $len = count($data);
            for($i = 0; $i < $len; $i += 2){
                $GLOBAL['_params'][$data[$i]] = $data[$i + 1];
            }
        }
    
        public function route(){
            $base = '/home/wwwroot/domain.com/module/';
            $base .= $this->entry . '/';
            if(!$this->entry || !is_dir($base)){
                exit('Error entry!');
            }
            !$this->control && $this->control = 'index';
            !$this->method && $this->method = 'index';
    
            $controlName = 'ctl' . ucfirst($this->control);
            $controlFile = "{$base}control/{$controlName}.php";
            if(!is_file($controlFile)){
                exit('Error control!!');
            }
    
            require_once "{$controlFile}";
            $control = new $controlName();
    
            $methods = array($this->method, 'index');
            $method = null;
            foreach($methods as $tmp){
                $tmp = 'func' .ucfirst($tmp);
                if(method_exists($control, $tmp)){
                    $method = $tmp;
                    break;
                }
            }
            if(empty($method)){
                exit("Error method!!");
            }
    
            $control->$method();
        }
    }

    实例应用:

    index.php:

    <?php
    require_once('inc.php');
    $router = new libRouter();
    $router->route();

    module/index/control/ctlIndex.php:

    <?php
    
    class ctlIndex{
        function __construct() {
            //;
        }
    
        public function funcIndex(){
            echo 'Hello World!';
        }
    }

    module/index/control/ctlUser.php

    <?php
    
    class ctlUser{
        function __construct() {
            //;
        }
        public function funcGetName(){
            echo "My Name is Happy.";
        }
    }

    配置nginx:

      在nginx配置文件中,对应的域名配置下,加入下面的语句。

    #访问的文件不存在是,统一由index.php处理。
    if(!-f $request_filename){ rewrite ^(.*)$ /index.php?_URL_
    =$1 last; }

    实例:

    配置完上面的所有内容,我们接下来,访问看看:

    其实上面两个链接分别被nginx处理为:

    www.domain.com/index.php?_URL_=/index/user-getName

    www.domain.com/index.php?_URL_=/index/index-index

    总结

    以上就简单的完成了,统一入口和自动加载类的实现了。当然, 要应用到生产环境中,这样是远远不够的,至少还要加上对于类名的过滤,及没有提交类名和方法时的默认调用:

    比如直接访问www.domain.com时,默认调用module/index/ctlIndex.php里的funcIndex方法。

  • 相关阅读:
    Enumerable.Distinct方法去重
    datatable使用lambda
    jQuery获取单选框(复选框)选中的状态
    从 datetime2 数据类型到 datetime 数据类型的转换产生一个超出范围的值
    SQL Server 中WITH (NOLOCK)浅析
    C#将int型数字转换成3位字符串,不足的时候,前面补0
    window.locatin.href 中特殊字符串问题
    windows下git bash不显示中文问题解决
    python获取文件行数
    自定义异常以及触发异常
  • 原文地址:https://www.cnblogs.com/mengzhongshi/p/3181748.html
Copyright © 2011-2022 走看看