我对autoload函数有问题,这里是场景:
注: 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.php:
<?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.php:
<?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';
}
}控制器/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;
}这样我就可以在控制器/index.php中写到:
<?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)更改为:
class index {
function __construct(){
$this->load_template('index');
}
}我不能使用它,因为load_template不是index的方法,它是Boot类的方法。
这是怎么回事?
发布于 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的主体是实现的一个很好的候选对象。
如果您无法更改控制器基类(您可能无法控制框架代码,但您可以创建自己的叉子,这取决于许可),您可以创建一个丑陋的黑客,定义一个索引类,并调用类之外您想要的任何其他代码:
<?php
class index {
}
$this->load_template('index');然而,从设计的角度来看,这是很糟糕的。除了前面的原因(零散的实现,空闲变量)之外,它在一个明显的全局范围(实际上是函数范围)中执行代码。库代码应该只定义事物,而不是直接执行代码,因为它可能造成范围混乱。
您应该做的一件事是在file_exists中添加一个__autoload调用,以防止试图包含一个不存在的文件。但是,这可能会导致一个“类‘索引’找不到”致命错误,除非您也应用上述修复。即使这样也比目前的情况更好,因为它会给您带来一个更相关的错误。
请注意,建议使用spl_autoload_register而不是定义__autoload函数,因为前者允许多个自动加载函数。docs声明__autoload可能在将来被删除。
发布于 2012-03-14 21:11:03
class index {
function - construct(){
$this->load_template('index');
}无效的PHP代码。您是否可以更改触发错误,然后粘贴完整的代码。
https://stackoverflow.com/questions/9709974
复制相似问题