>백엔드 개발 >PHP 튜토리얼 >写一个属于自己的PHP的MVC框架(二)

写一个属于自己的PHP的MVC框架(二)

WBOY
WBOY원래의
2016-06-23 13:46:55971검색

第一篇文章已经把所需的目录搭建好了,接下来的工作就是写一些代码了


用编辑器打开public/index.php文件,写上下面的代码


<?php define(DS, DIRECTORY_SEPARATOR);    define(ROOT, dirname(dirname(__FILE__)));        $url = $_GET['url'];        // 加载引导    require_once( ROOT . DS . 'core' . DS . 'bootstrap.php' );            

入口文件的代码很简洁,其中$url是个全局变量,用来获取当做请求的参数

现在先把加载引导的那句注释掉,然后在下面echo $url,即

//require_once( ROOT . DS . 'core' . DS . 'bootstrap.php' );echo $url;

然后在浏览器地址栏输入http://localhost/wudicsmvc/

注:D:\AppServ\www\wudicsmvc

然后,你会发现,啥也没显示。


接着输入http://localhost/wudicsmvc/wudics

就会发现网页打出wudics这几个字


说明可以正常获取url参数了,这个作为一个全局变量存在,主要用来获取客户端的请求

如访问哪个控制器的哪个方法

http://localhost/wudicsmvc/home/index

可以这样规定,访问home控制器的index方法,当然你也可以有不同的规定,也就是路由规则,据说是mvc一个很重要的概念


index.php文件没有啥内容,加载了一个bootstrap.php文件,打开core目录下的bootstrap.php文件:

<?php // 加载配置    require_once(ROOT . DS . 'cfg' . DS . 'config.php');        // 路由请求    require_once(ROOT . DS . 'core' . DS . 'route.php');

同样加载了两个文件,一个是cfg目录下的config.php,一个是core目录下的route.php


看下config.php

<?php // mysql连接参数    define('DB_HOST', 'localhost');    define('DB_USER', 'root');    define('DB_PASS', '123456');    define('DB_NAME', 'transdb');        // smarty的一些常量    define('DIR_TPL', ROOT . DS . 'app' . DS . 'view' . DS . 'template_dir' . DS . 'default' . DS);    define('DIR_CPL', ROOT . DS . 'app' . DS . 'view' . DS . 'compile_dir' . DS);    define('DIR_CFG', ROOT . DS . 'app' . DS . 'view' . DS . 'config_dir' . DS);    define('DIR_CAC', ROOT . DS . 'app' . DS . 'view' . DS . 'cache_dir' . DS);        // 默认控制类方法    $default['controller'] = 'home';    $default['action'] = 'index';        // pulibc文件夹的路径,方便模板设计    define('WEBSITE', 'http://localhost');    define('WEBIMG', WEBSITE . dirname(dirname($_SERVER['PHP_SELF'])) . '/public/img/');

一些常量和全局变量,这个很有用,因为常量和全局变量在单一入口php程序里都是共享的资源


然后是route.php文件

<?php function callHook()    {        global $url;        global $default;                // Get the $controller $action $param        $param = array();                $urlArr = explode("/", rtrim($url, "/"));        $controller = array_shift($urlArr);        $action = array_shift($urlArr);        $param = $urlArr;                if ($controller == "")        {            $controller = $default['controller'];            $action = $default['action'];        }                if ($action == "")        {            $action = $default['action'];        }                        // 控制类书写规则 HomeController->Index         $controllerName = ucfirst($controller).'Controller';        $dispatch = new $controllerName($controller, $action);                if (method_exists($dispatch, ucfirst($action)))        {            call_user_func_array(array($dispatch, ucfirst($action)), $param);        }        else        {            /* Error Code for Method is not exists */            die('method not exitsts.<br>');        }    }     // 自动加载类    function __autoload($classname)    {        if (file_exists(ROOT . DS . 'core' . DS . strtolower($classname) . '.class.php'))        {            require_once(ROOT . DS . 'core' . DS . strtolower($classname) . '.class.php');        }        else if (file_exists(ROOT . DS . 'app' . DS . 'controller' . DS . strtolower($classname) . '.php'))        {            require_once(ROOT . DS . 'app' . DS . 'controller' . DS . strtolower($classname) . '.php');        }        else if (file_exists(ROOT . DS . 'app' . DS . 'model' . DS . strtolower($classname) . '.php'))        {            require_once(ROOT . DS . 'app' . DS . 'model' . DS . strtolower($classname) . '.php');        }        else        {            /* Error Code for can not find the files */            die('class not found.<br>');        }    }        callHook();

这个页面,首先定义了两个函数callHook和__autoload,然后页面底部有一句callHook();到此,程序就开始执行了。


callHook函数:

其作用就是定位上面所说的控制器,方法,参数

当代码执行这里时

// 控制类书写规则 HomeController->Index         $controllerName = ucfirst($controller).'Controller';        $dispatch = new $controllerName($controller, $action);

程序就会执行__autoload方法,这个方法可以在你使用类的时候可以自动加载所需的文件

不需要手动require,这样可以方便的时候各种类库,方便省事,不需要每次调用类之前都手动加载.php类文件


method_exists方法判断这个类中是不是存在该方法,若存在,就call_user_func_array调用该方法


注:__autoload方法是一些加载类库文件的规则,这个要根据你的习惯来定义的。


至此,程序就跳到某某控制器的某某方法执行了。比如说HomeController类中的Index方法,该文件就在你的__autoload规则里定义着。

我这里的就是app/controller/homecontroller.php文件了

<?phpclass HomeController extends Controller{    public function Index()    {        $user = new user();        $tpl = new tpl();        $tpl->set('name', $user->name);        $tpl->render('index.html');    }}

这个方法里加载了user类(Model)和tpl类(view)

user类负责从数据库读数据

tpl类负责把显示数据


所以也可以这样说,controller类起到了一个连接的作用,控制着数据和显示,使两者可以很好的绑定在一起,model和view就分开了

这样做就可以实现了当初的想法,把php代码和html布局分离开来


我期待我能够整合出一个属于自己的方便使用的php框架,希望大家来QQ群给点意见,QQ群号:667110936671109366711093

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.