首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >_autoload问题

_autoload问题
EN

Stack Overflow用户
提问于 2012-03-14 20:41:48
回答 2查看 368关注 0票数 2

我对autoload函数有问题,这里是场景:

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

首先是相关档案。

.htaccess:

代码语言:javascript
复制
<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:

代码语言:javascript
复制
<?php require_once('./application/LOADER.php'); ?>

application/LOADER.php:

代码语言:javascript
复制
<?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:

代码语言:javascript
复制
<?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.php:

代码语言:javascript
复制
<?php
// Site Address Here:
$S->DOMAIN      = 'site.com';
$S->SITE_URL    = 'http://site.com/myMVC/';
?>

在config/func_main.php中:

代码语言:javascript
复制
function __autoload($class_name) {
    global $C;
    require_once( $C->INCPATH.'libs/lib_'.$class_name.'.php' );
}

libs/libs_Boot.php:

代码语言:javascript
复制
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';
    }
}

控制器/index.php:

代码语言:javascript
复制
<?php $this->load_template('index');?>

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

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

代码语言:javascript
复制
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;
}

这样我就可以在控制器/index.php中写到:

代码语言:javascript
复制
<?php
if (/* the user is not logged in */) {
    $this->redirect('signin');
} 
$this->load_template('index');
?>

在某种程度上,所有的东西都可以在е上工作。我可以看到视图,但有一个错误:

**警告: require_once(/home/novacl/public_html/myMVC/application/libs/lib_index.php)函数.要求-一次:未能打开流:在第6行的/home/novacl/public_html/myMVC/application/config/func_main.php中没有这样的文件或目录

第6行位于__autoload函数中。

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

代码语言:javascript
复制
class index {
    function __construct(){
        $this->load_template('index');
    }
}

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

这是怎么回事?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-03-14 20:51:41

当尝试创建一个尚未定义的类的实例时,将调用__autoload。错误消息表示代码试图创建一个名为"index“的类。如果它存在于示例代码中,则可能是$controller = new $this->request;。您需要在这一行之前包含一个定义类“index”的文件。正如您已经确定的那样,前面的行require_once( $this->controller.$this->request.'.php' );就是这样做的地方之一。

至于这使得index.php中的调用index.php不起作用,在任何情况下都不应该这样做。首先,类的实现应该包含在一个文件中;否则,代码就不会很有凝聚力。另一方面,$this是文件中的一个空闲变量,在代码清晰度方面几乎与全局变量一样糟糕。相反,应该有一个Boot调度程序将调用的标准控制器方法;load_template的主体是实现的一个很好的候选对象。

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

代码语言:javascript
复制
<?php
class index {
}
$this->load_template('index');

然而,从设计的角度来看,这是很糟糕的。除了前面的原因(零散的实现,空闲变量)之外,它在一个明显的全局范围(实际上是函数范围)中执行代码。库代码应该只定义事物,而不是直接执行代码,因为它可能造成范围混乱。

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

请注意,建议使用spl_autoload_register而不是定义__autoload函数,因为前者允许多个自动加载函数。docs声明__autoload可能在将来被删除。

票数 2
EN

Stack Overflow用户

发布于 2012-03-14 21:11:03

代码语言:javascript
复制
class index {
function - construct(){

$this->load_template('index');

}

无效的PHP代码。您是否可以更改触发错误,然后粘贴完整的代码。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9709974

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档