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方法。

原文地址:https://www.cnblogs.com/mengzhongshi/p/3181748.html