PHP MVC框架之错误捕捉入门教程

 更新时间:2016年11月25日 15:03  点击:2060
以前有讲过关于php mvc的各种用法,本文章主要介绍PHP MVC框架之错误捕捉用法说明,各位同学可参考。

前三篇文章已经把MVC的结构原理都简单的进行了说明和演示。。。当然,不是说一个框架就只有那点东西,一个良好的框架所要求的功能还是要很全面的,例如友好的错误输出,安全处理,防止跨域攻击等

好了,我们一步一步来。这节要说的是错误捕捉,其实这个不难,只要理解2个方法就可以做好错误捕捉的程序。

 代码如下 复制代码


register_shutdown_function(‘functionname’);  
set_error_handler(‘functionname’); 

第一个方法,是注册一个shutdown的回调函数,当php脚本关闭时调用,当然这个关闭可以是正常的代码执行完毕,也可以是程序抛出致命错误关闭的脚本,那我怎么区分呢?别急,php还有一个方法叫error_get_last() 就像函数名说的那样,获取php最后一个错误信息,这样就可以判断是代码正常执行完毕还是遇到fatal error。。。

第二个方法,是注册一个error的回调函数,当脚本执行遇到错误时调用。

这2个方法最大的区别是,第一个是脚本关闭调用,也就是1次访问,只会调用一次(因为发生致命错误脚本就退出执行了),二第二个方法的触发调用是发生错误的时候,例如访问数组中不存在的index,使用未定义的变量,就是这些warning,notice错误的捕捉。。。如果你想更了解二者的区别,建议访问php官网查看文档说明。。。

这里我就不贴代码了,有兴趣的同学,可以去github那里下回来慢慢看。。。

 

 代码如下 复制代码

<?php

# 定义application路径

define('APPPATH', trim(__DIR__,'/'));

# 获得请求地址

$root = $_SERVER['SCRIPT_NAME'];

$request = $_SERVER['REQUEST_URI'];

$URI = array();

# 获得index.php 后面的地址

$url = trim(str_replace($root, '', $request), '/');


# 如果为空,则是访问根地址

if (empty($url))

{

    # 默认控制器和默认方法

    $class = 'Index';

    $func = 'welcome';

}

else

{

    $URI = explode('/', $url);

 


    # 如果function为空 则默认访问index

    if (count($URI) < 2)

    {

        $class = ucfirst($URI[0]);

        $func = 'index';

    }

    else

    {

        $class = ucfirst($URI[0]);

        $func = $URI[1];

    }

}

 

# 把class加载进来

include(APPPATH . '/' . 'application/controllers/' . $class . '.php');

 


#实例化

$obj = new $class;

 


call_user_func_array(

    # 调用内部function

    array($obj,$func),

    # 传递参数

    array_slice($URI, 2)

);

 

 

我们来看看最终的效果。。。我们来试试访问不存在的controller里的方法试试

先看看没有错误捕捉的时候:

 

再来对比下做了错误捕捉的时候

在php中访问mysql我们需要利用php的各种函数来实现的,最常用的函数是mysql_connect()函数了,用它就可以连接数据库,其它的我们后面再廛。

mysql_connect()函数

定义和用法

mysql_connect() 函数打开非持久的 MySQL 连接。

语法

mysql_connect(server,user,pwd,newlink,clientflag)

例子

 代码如下 复制代码

<?php
$con = mysql_connect("localhost","mysql_user","mysql_pwd");
if (!$con)
  {
  die('Could not connect: ' . mysql_error());
  }

// 一些代码...

mysql_close($con);
?>

下面我们来看个连接数据库实例

先建一个名为test的数据库(使用phpadmin)见下图:

然后,在该表内建一个名为 user的表,

准备工作完成,正式开始:)

 代码如下 复制代码

<?php
//connect.php
$db_server="localhost";// 数据库服务器名称
$db_user="root"; // 连接数据库用户名
$db_pwd="leaf";//连接数据库密码
$db_name="test";//数据库的名字
$db=mysql_connect($db_server,$db_user,$db_pwd,$db_name);
/*
面向对像
$db=new mysql($db_server,$db_user,$db_pwd,$db_name);
*/
 
if(!$db)echo "fail";
else echo "connect success"
?>


如果PHP是4.0以后版本,可以使用mysqli库,相应的代码这样写:

 代码如下 复制代码

<?php ......
$db=mysqli_connect($db_server,$db_user,$db_pwd,$db_name);
/*
面向对象
$db=new mysqli($db_server,$db_user,$db_pwd,$db_name);
*/
if(mysqli_connect_errno()){
  echo "Error: Could not connect to database. Please try again laer.";
  exit;
}
else echo "Success!";
?>

说明:使用了函数库mysqli,所以需要将php.ini文件中的extension=php.mysqli 打开

通常,我们将代码前面的几行单独放在一配制文件中,这里取名为 db_config.php

 代码如下 复制代码

<?php
//db_config.php
$db_server="localhost";// 数据库服务器名称
$db_user="root"; // 连接数据库用户名
$db_pwd="leaf";//连接数据库密码
$db_name="test";//数据库的名字
?>

如此一来,最初的那个连接测试代码就成了这样的:

 代码如下 复制代码

<?php
// connect.php
require_once(“db_config.php”);//包含配置文件
$db=mysql_connect($db_server,$db_user,$db_pwd,$db_name);
//同样也可以用面向对像的语法
if(!$db)echo "fail";
else echo "connect success"
?>

文章主要讲到了关于PHP MVC框架路由使用方法,有需要了解的同学可进入参考。


说到PHP开发web,自然离不开开发框架,开发框架为我们提供了灵活的开发方式,MVC层分离,业务解耦等。。。

第一篇先来简单点的,说说MVC框架的路由功能。。。

一般的单入口框架路由都是这样的结构:

domain/index.php/classname/functionname/var1/var2

这里的index.php 就被称为入口文件。。。对于服务器而言,你这里访问的就只有index.php 后面调用的controller 和里面的方法,甚至传值都是在框架内部基于PHP层面实现的。

Talk is cheap, show you the code !!


首先,先建立好下面的文件结构

 

我们来动手试试,怎么才能访问到controllers里面的文件。。。

在index.php里面输入以下内容

print_r($_SERVER);

然后访问 以下地址试试。

yourdomain/index.php/class/function/var1

这里作者我是用本地环境的,我访问的地址是localhost/MVC/index.php/class/function/var1

我贴出最重要的2个变量

[REQUEST_URI] => /MVC/index.php/class/function/var1

[SCRIPT_NAME] => /MVC/index.php

其实路由最基本的原理就在这里:

通过这2个变量来提取url地址里的class 和 function,参数等,然后把class include进来,通过PHP的回调函数  call_user_func_array 调用对应的function和传递相应的参数。

接下来上代码,读代码应该比我写的易懂。哈哈~~

index.php 的内容如下

 代码如下 复制代码

 
<?php  
 
# 定义application路径  
define(‘APPPATH’, trim(__DIR__,’/'));  
 
# 获得请求地址  
$root = $_SERVER['SCRIPT_NAME'];  
$request = $_SERVER['REQUEST_URI'];  
 
$URI = array();  
 
# 获得index.php 后面的地址  
$url = trim(str_replace($root, ”, $request), ‘/’);  
 
# 如果为空,则是访问根地址  
if (empty($url))  
{  
    # 默认控制器和默认方法  
    $class = ‘index’;  
    $func = ‘welcome’;  
}  
else 
{  
    $URI = explode(‘/’, $url);  
 
    # 如果function为空 则默认访问index  
    if (count($URI) < 2)  
    {  
        $class = $URI[0];  
        $func = ‘index’;  
    }  
    else 
    {  
        $class = $URI[0];  
        $func = $URI[1];  
    }  
}  
 
 
# 把class加载进来  
include(APPPATH . ‘/’ . ‘application/controllers/’ . $class . ‘.php’);  
 
#实例化  
$obj = new ucfirst($class);  
 
call_user_func_array(  
    # 调用内部function  
    array($obj,$func),   
    # 传递参数  
    array_slice($URI, 2)  
);  
 

在application/controllers 里面添加下面2个文件

index.php   用于作为默认控制器

 

 代码如下 复制代码


<?php  
 
class Index  
{  
 
    function welcome()  
    {  
        echo ‘I am default controller’;  
    }  
 
}  
 
 
?> 
 

hello.php

 
<?php  
class Hello  
{  
    public function index()  
    {  
        echo ‘hello world’;  
    }  
 
    public function name($name)  
    {  
        echo ‘hello ‘ . $name;  
    }  
}  
 
?> 
 

测试一下看看,能不能访问了。根据上面的路由结构。我们来试试

 

这个访问正常,正确调用了hello这个class内部的name方法,然后把参数barbery传递过去了。。。

再试试不输入function name,看看能不能默认调用index。。

 

答案也是可以的。。。

最后一个,访问root地址看看

 

也正确的映射到了默认控制器上。。。

ok,一个简单的MVC路由功能就完成了。。。

本文章来给各位介绍PHP MVC框架之加载器学习笔记,有需要了解的朋友可进入参考。

上节说了MVC的路由原理,这节我们来说说MVC框架的loader,也称为加载器。

虽然不同的框架,加载器的用法不同,但是其原理都是相通的。。。都是通过单例模式加载文件,而且把已加载的文件cache起来,避免重复加载。。。因为在开发业务的过程中,常常需要加载不同的模块,不同的类库等,MVC的loader可以帮助我们实现单例模式,更加符合开发需求。

下面我们开始动手,利用其原理,做一个简单的loader。


首先,我们设计的加载器,要满足可以全局使用,无论在controller里还是在model、library里都可以使用。

其次,加载器要有缓存能力,即相同的文件只加载一次,相同的类只实例化一次。

最后,要能加载多种文件,model、library、helper。

先解决第一步,怎么全局使用,最简单的办法就是定义一个全局的function,这样,在后面的不同类库,不同function里都可以调用这个全局function,进行加载文件。

第二步和第三步,要一起解决,定义一个单例模式的loader类,因为是单例模式,可以保证全局只有一份内容,这样的话,就可以利用数组把这些已加载的内容和对象cache起来,这样就可以避免了重复加载的问题。。。

 代码如下 复制代码
if ( ! function_exists(‘load’))  
{  
    function load($name, $type=’model’, $data=array())  
    {  
        static $loader = NULL;  
        if (is_null($loader))  
        {  
            include (ROOT.’/system/core/loader.php’);  
            $loader = Loader::get_instance();  
        }  
 
        return $loader->$type($name, $data);  
    }  

上面这个,就是我写的一个简单的全局函数 load,这个函数的作用就是为了可以全局调用,然后通过这个load函数,去调用loader类,由loader类负责加载文件,实例化,和缓存对象。。。下面我把loader的代码放出来给大家看看。

 代码如下 复制代码
<?php  
 
class Loader  
{  
    private $_loaded_models = array();  
    private $_loaded_librarys = array();  
    private static $OBJ;  
 
    # 单例模式,不允许new对象  
    private function __construct()  
    {  
 
    }  
 
 
    public static function get_instance()  
    {  
        if (is_null(self::$OBJ))  
        {  
            $class = __CLASS__;  
            self::$OBJ = new $class;  
        }  
          
        return self::$OBJ;  
    }  
 
    public function model($model, $data=array())  
    {  
        $model = strtolower($model);  
 
        # 如果已经加载,则返回对象,避免重复加载  
        if (isset($this->_loaded_models[$model]))  
        {  
            return $this->_loaded_models[$model];  
        }  
 
        # 否则加载文件  
        include ROOT.“/application/models/{$model}.php”;  
 
        $class = ucfirst($model);  
        # 实例化对象  
        if (emptyempty($data))  
        {  
            $instance = new $class;  
        }  
        else 
        {  
            $instance = new $class($data);  
        }  
        # 把对象cache起来  
        $this->_loaded_models[$model] = $instance;  
 
        return $instance;  
    }  
 
 
    public function library($library, $data=array())  
    {  
        $library = strtolower($library);  
 
        # 如果已经加载,则返回对象,避免重复加载  
        if (isset($this->_loaded_librarys[$library]))  
        {  
            return $this->_loaded_librarys[$library];  
        }  
 
        # 否则加载文件  
        include ROOT.“/application/librarys/{$library}.php”;  
 
        $class = ucfirst($library);  
        # 实例化对象  
        if (emptyempty($data))  
        {  
            $instance = new $class;  
        }  
        else 
        {  
            $instance = new $class($data);  
        }  
          
        # 把对象cache起来  
        $this->_loaded_librarys[$library] = $instance;  
 
        return $instance;  
    }  
 
 
}  
 
 
 
?> 

大家看到了没有,这个loader采用的是单例模式,虽然前面的function的设计已经可以保证不会重复实例化loader这个对象,但是为了真正可以保证全局只有一份loader对象,设计成单例模式是最保险的。。。

具体的测试例子请看代码。。。我把代码打包上传上来,有需要的就下载回去看看吧。。。下载后,解压,把lesson2文件夹放到你的www目录下,然后访问yourdomain/MVC/lesson2/index.php/index/test  试试看吧。。。

本文章来给大家介绍PHP MVC框架视图学习笔记,以方便以后需要参考。

今天来讲讲view,视图。。。没了解之前,你可能觉得模板引擎很神奇,了解了之后你会觉得,原来是如此简单。。。

对于模板引擎而言,它的原理一般是这样,把模板引擎的语言替换成可执行的语言,然后把变量输出。。。

因为PHP本身就是一个良好了模板引擎,所以用原生的模板引擎是灰常方便和容易做到的。。。


index.html

 代码如下 复制代码
 
<html>  
<head>  
    <title><?php echo $title ?></title>  
</head>  
<body>  
<h1><?php echo $content ?></h1>  
 
<?php if( ! empty($arr)) { ?>  
<ul>  
    <?php foreach($arr as $value) { ?>  
    <li><?php echo $value ?></li>  
    <?php } ?>  
</ul>  
<?php } ?>  
 
</body>  
</html> 

想上面这样一个html页面,采用的就是原生的php模板引擎,服务器在你include这个页面时,会处理html中的PHP代码。

你也许会问,要是我想定制模板语言可以吗?答案当然是可以的,像我上面说的,用模板引擎的语言,只需要多做一步,就是把模板引擎的语言替换成标准的PHP语言。。。

 index_2.html

 

 代码如下 复制代码
<html> 
<head> 
    <title><?php echo $title ?></title> 
</head> 
<body> 
<h1><?php echo $content ?></h1> 
 
<ifexist arr> 
<ul> 
    <for value = arr> 
    <li><echo value></li> 
    <endfor> 
</ul> 
<endexist> 
 
</body> 
</html> 

看看这个页面,发现和index.html 有什么不同吗,没错,就是在循环那里,我们用的不是标准的php语言,而是,按照自己的喜好,定义了几个模板语言,一个是<ifexist xxx>这个是判断xxx变量是否存在,而且不为空,后面那个<for xx1=xx2>是循环迭代xx2变量,中间的<echo xx> 是输出xx变量

怎么替换成标准语言呢?这个可以使用正则替换,因为字符串替换无法满足我们需求了。

 代码如下 复制代码
 
$pattern = array(  
    ‘/<ifexists+(w+)>/i’,  
    ‘/<fors+(w+)s=s(w+)>/’,  
    ‘/<echos+(w+)>/’  
);  
 
$replacement = array(  
    ‘<?php if( ! empty($\1)){ ?>’,  
    ‘<?php foreach($\2 as $\1){ ?>’,  
    ‘<?php echo $\1 ?>’  
);  
 
$content = preg_replace($pattern, $replacement, $content);  
 
$search = array(‘<endexist>’, ‘<endfor>’);  
 
 
$content = str_replace($search, ‘<?php } ?>’, $content); 

 

上面的正则就可以帮我们把刚刚定义的标签,转换成标准p hp语言。。。

转换之后是这样,请看图。

 

转换之后可以输出了吗?答案是不行的,因为你获取到html文件的内容的时候,php就已经解释了,那时候你还没替换成标准的php语言,所以,你现在输出的话,其中的php代码就没有执行。。。不过我们可以利用 php eval 这个函数,来强制要求执行其中的代码。

 代码如下 复制代码

$content = eval(‘ ?>’.$content);

注意哦,要 ?>.$content 要不,php会把其中的html当成是php代码的执行,这样就会出错了。。。

刷新一下,ok,已经可以执行了~~~

[!--infotagslink--]

相关文章

  • Ecshop提示Only variables should be passed by reference in错误

    在安装好ecshop软件之后我们打开首页时提示Only variables should be passed by reference in错误了,碰到这个问题是什么原因呢?下面我们就一起来看看解决办法吧。...2016-11-25
  • 409错误是什么 http 409错误怎么解决

    409错误是什么?http 409错误怎么解决呢?不少站长在遇到这个错误代码之后都一筹莫展,本次一聚教程网为大家带来了详细的说明,快来看看吧。 409错误是什么: HTTP 40...2017-01-22
  • 414错误是什么 414错误怎么解决

    414错误是HTTP协议状态码中的一种,很多都还不知道414错误是什么,以及不知道怎么解决414错误,那么就来看看小编带来的介绍吧。 414错误是什么: HTTP 414错误,(Requ...2017-01-22
  • http 405错误是什么 http 405错误怎么解决

    http 405错误是什么?http 405错误怎么解决?相信很多站长都在找这两个问题的答案,本次小编为大家带来了详细的教程,快来看看吧。 405错误是什么: HTTP 405错误是H...2017-01-22
  • 401错误码代表什么 401错误解决办法

    401是HTTP状态码的一种,属于“请示错误”,表示请求可能出错,已妨碍了服务器对请求的处理。具体的401错误是指:未授权,请求要求进行身份验证。登录后,服务器可能会返回对页面...2017-01-22
  • http 402错误是什么 http 402简介

    http 402错误是什么?402错误较为少见,一般不轻易出现,下面小编就来告诉大家402错误是什么吧。 HTTP 402错误是HTTP状态码的一种,表示“要求付费”; 所求的...2017-01-22
  • 411错误是什么 411错误怎么解决

    411错误是HTTP协议状态码的一种,很多人都还不知道411错误是什么,本次一聚教程网将为大家进行解答,并且告诉大家411错误怎么解决。 411错误是什么: HTTP 411错误,(Lengt...2017-01-22
  • 404错误是什么 404错误怎么解决

    403错误是网站访问过程中,常见的错误提示。资源不可用,服务器理解客户的请求,但拒绝处理它。通常由于服务器上文件或目录的权限设置导致,比如IIS或者apache设置了访问权限...2017-01-22
  • apache网站提示503错误解决办法

    Apache status 503 的原因大致有如下几种情况 : 1、 CPU 负载过高,服务器响应不过来,返回503 2、 系统连接数超限,超过MaxVhostClients的上限,返回503 3、 单IP连接数超限,超过M...2016-01-28
  • 403错误是什么 403错误怎么解决

    403错误是HTTP状态码的一种,属于“请示错误”,表示服务器拒绝请求。如果在搜索引擎尝试抓取您网站上的有效网页时显示此状态代码,那么,这可能是您的服务器或主机拒绝搜索...2017-01-22
  • 412错误是什么 412错误怎么解决

    412错误是什么?412错误怎么解决?本次一聚教程网将为大家带来详细的介绍,帮助大家全面了解412错误的意思以及解决412错误的方法。 412错误是什么: HTTP 412错误,(Precond...2017-01-22
  • HTTP 408错误是什么 HTTP 408错误解决方法

    相信很多站长都遇到过这样一个问题,访问页面时出现408错误,下面一聚教程网将为大家介绍408错误出现的原因以及408错误的解决办法。 HTTP 408错误出现原因: HTT...2017-01-22
  • 406错误是什么 406错误怎么解决

    HTTP 406错误是HTTP协议状态码的一种,表示无法使用请求的内容特性来响应请求的网页。一般是指客户端浏览器不接受所请求页面的 MIME 类型。 而MIME类型是在把输出...2017-01-22
  • 407错误是什么 407错误怎么解决

    407错误是什么?407错误怎么解决?不少站长都遇到过407错误,下面小编将告诉大家如何处理407错误。 407错误是什么: HTTP 407错误是HTTP协议状态码的一种,表示需要代...2017-01-22
  • 410错误是什么 http 410错误怎么解决

    410错误是HTTP协议状态码的一种,本次一聚教程网将为大家详细介绍HTTP 410错误是什么,以及410错误的解决办法。 410错误是什么: HTTP 410错误是HTTP协议状态码的...2017-01-22
  • HTTP 400错误是什么 HTTP 400错误怎么解决

    每当遇到http错误代码为400,代表客户端发起的请求不符合服务器对请求的某些限制,或者请求本身存在一定的错误,那么HTTP 400错误怎么解决呢?请看下文介绍。 目前400错...2017-01-22
  • PHP Fatal error: Cannot use object of type stdClass as array in错误

    下面一起来看看在php开发中碰到PHP Fatal error: Cannot use object of type stdClass as array in错误问题的解决办法吧。 普通的数组出现如下错误 代码...2016-11-25
  • 基于BootStrap Metronic开发框架经验小结【八】框架功能总体界面介绍

    这篇文章主要介绍了基于BootStrap Metronic开发框架经验小结【八】框架功能总体界面介绍 的相关资料,需要的朋友可以参考下...2016-05-14
  • PHP Curl出现403错误的解决办法

    自己用的小PHP应用,使用curl抓网页下来处理,为了穿墙方便,使用Privoxy作为代理,便于选择哪些网站使用proxy、哪些不用。但今天却遇到了奇怪的问题,访问google baidu这些网站居然都返回403错误,而访问其他的一些网站没事,如果...2014-05-31
  • Lua语言新手简单入门教程

    这篇文章主要给大家介绍的是关于Lua语言新手入门的简单教程,文中通过示例代码一步步介绍的非常详细,对各位新手们的入门提供了一个很方便的教程,需要的朋友可以参考借鉴,下面随着小编来一起学习学习吧。...2020-06-30