_自动加载问题


_autoload problems

我对自动加载功能有问题,这是一个场景:

注意:MVC框架不是我自己的。我只是用它来学习更多关于OOP和MVC的知识。

第一,相关档案。

.htaccess:

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /phoenix/
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^(.*)$ index.php?%{QUERY_STRING} [NE,L]
    RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]
</IfModule>

index.php:

<?php require_once('./application/LOADER.php'); ?>

application/LOADER.hp:

<?php
chdir(dirname(__FILE__));
require_once('./config/func_main.php');
require_once('./conf_system.php');
session_start();
ob_start('ob_gzhandler', 6);
$load = new Boot();
$load->LOAD();
?>

conf_system.php:

<?php
$C = new stdClass;
$C->INCPATH = dirname(__FILE__) . '/';
if( ! file_exists($C->INCPATH.'conf_main.php') ) {
    exit;
}
require_once($C->INCPATH.'conf_main.php');
chdir( $C->INCPATH );
?>

conf_main.hp:

<?php
// Site Address Here:
$S->DOMAIN      = 'site.com';
$S->SITE_URL    = 'http://site.com/myMVC/';
?>

在config/func_main.php中:

function __autoload($class_name) {
    global $C;
    require_once( $C->INCPATH.'libs/lib_'.$class_name.'.php' );
}

libs/libs_Boot.php:

class Boot {
    public function __construct() {
        $this->controller = $GLOBALS['C']->INCPATH . 'controllers/';
        $this->request = array();
    }
    public function LOAD() {
        $this->_parse_input();
        $this->_load_controller();
        $this->load_template();
    }
    private function _parse_input() {
        /* Here is the logic to get the controller name. */
        $request = explode('/', ...);
        $this->request = $request[2];
    }

    private function _load_controller() {
        require_once( $this->controller.$this->request.'.php' );
        $controller = new $this->request;
    }
    public function load_template($name) {
        global $C, $D;
        require 'view/header.php';
        require 'view/' . $name . '.php';
        require 'view/footer.php';
    }
}

controllers/index.php:

<?php $this->load_template('index');?>

在视图文件夹中,只有HTML文件。

我知道应该有一个index类,但我想使用Boot类中的函数。例如:

public function redirect($loc, $abs=FALSE) {
    global $C;
    if( ! $abs && preg_match('/^http(s)?':'/'//', $loc) ) {
        $abs = TRUE;
    }
    if( ! $abs ) {
        if( $loc{0} != '/' ) {
            $loc = $C->SITE_URL.$loc;
        }
    }
    if( ! headers_sent() ) {
        header('Location: '.$loc);
    }
    echo '<meta http-equiv="refresh" content="0;url='.$loc.'" />';
    echo '<script type="text/javascript"> self.location = "'.$loc.'"; </script>';
    exit;
}

因此,在controller/index.php中,我可以写:

<?php
if (/* the user is not logged in */) {
    $this->redirect('signin');
} 
$this->load_template('index');
?>

一切都在一定程度上起作用。我看到了视图,但有一个错误:

**警告:require_sonce(/home/novacl/public_html/myMMVC/application/libs/lib_index.php)[function.requestonce]:无法打开流:在第6行/home/novicl/public_html/myMMVC/config/func_main.php中没有这样的文件或目录**

第6行在__autoload函数中。

那么为什么会发生这种情况呢?如果索引控制器(controller/index.php)更改为:

class index {
    function __construct(){
        $this->load_template('index');
    }
}

我不能使用它,因为load_template不是index的方法,它是Boot类的方法。。

发生了什么?

当尝试创建尚未定义的类的实例时,将调用

__autoload。错误消息指示代码正试图在某个地方创建名为"index"的类。如果它存在于示例代码中,那么它可能是$controller = new $this->request;。您需要在此行之前包含一个定义类"index"的文件。前面的行require_once( $this->controller.$this->request.'.php' );就是这样做的一个地方,正如您所确定的那样。

至于这使得index.php中的调用$this->load_template('index')不起作用,在任何情况下都不应该这样做。首先,类的实现应该包含在一个文件中;否则,您的代码就不是很有凝聚力。另一方面,$this是文件中的一个自由变量,在代码清晰度方面,它几乎和全局变量一样糟糕。相反,应该有一个Boot调度器将调用的标准控制器方法;CCD_ 12的主体是实现的良好候选者。

如果你不能更改控制器基类(你可能无法控制框架代码,但你可以创建自己的fork,这取决于许可),你可以创建一个丑陋的破解,定义一个索引类,并调用类之外的任何其他代码:

<?php
class index {
}
$this->load_template('index');

然而,从设计的角度来看,这是非常可怕的。除了前面的原因(分散的实现、自由变量)之外,它在一个明显的全局范围内执行代码,而这个范围实际上是函数范围。库代码应该只定义事物,而不是直接执行代码,因为这可能会导致范围混乱。

您应该做的一件事是在__autoload中添加对file_exists的调用,以防止试图包含不存在的文件。但是,除非您也应用上述修复程序,否则这可能会导致"未找到类索引"的致命错误。即使这样也比目前的情况更可取,因为它会给你一个更相关的错误。

请注意,建议使用spl_autoload_register而不是定义__autoload函数,因为前者允许多个自动加载函数。文档中指出__autoload将来可能会被删除。

class index {
function - construct(){
$this->load_template('index');
}

不是有效的PHP代码。你能更改触发错误的代码,然后粘贴完整的代码吗。