我的自动加载功能有问题,这就是场景:
注意: MVC framework不是我自己的。我只是用它来了解有关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'); ?>
应用/ 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_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;
}
所以在controller / 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)[function.require-once]:无法打开流:/ home / novacl / public_html / myMVC中没有此类文件或目录第6行的/application/config/func_main.php **
第6行位于__autoload
函数中。
为什么会发生这种情况?如果索引控制器(controller / index.php)更改为:
class index {
function __construct(){
$this->load_template('index');
}
}
我无法使用它,因为load_template
不是index
的方法,它是Boot
类的方法..
发生了什么事?
答案 0 :(得分:2)
__autoload
。错误消息表明代码正在尝试创建名为“index”的类。如果它出现在示例代码中,则可能是$controller = new $this->request;
。您需要在此行之前包含一个定义类'index'的文件。正如您所确定的那样,紧接在之前的行require_once( $this->controller.$this->request.'.php' );
是一个执行此操作的地方。
至于这使得index.php中的调用$this->load_template('index')
不起作用,在任何情况下都不应该这样做。首先,类的实现应该包含在一个文件中;否则,你的代码不是很有凝聚力。另一方面,$this
是文件中的自由变量,在代码清晰度方面几乎与全局变量一样糟糕。相反,应该有Boot
调度员调用的标准控制器方法; load_template
的主体是实施的良好候选人。
如果您无法更改控制器基类(您可能无法控制框架代码,但您可以创建自己的分支,具体取决于许可),您可以创建一个丑陋的黑客并定义索引类和在课堂外调用你想要的任何其他代码:
<?php
class index {
}
$this->load_template('index');
然而,从设计角度来看,这很糟糕。除了之前的原因(分散实现,自由变量),它还在一个明显的全局范围内执行代码,该范围实际上是函数范围。库代码应该只定义事物,而不是直接执行代码,因为它可能导致范围混乱。
您应该做的一件事是在file_exists
中添加对__autoload
的调用,以防止尝试包含不存在的文件。但是,除非您也应用上述修复,否则这可能会导致“未找到”类“索引”致命错误。即使这样做也比目前的情况更好,因为它会给你一个更相关的错误。
请注意,建议使用spl_autoload_register
而不是定义__autoload
函数,因为前者允许多个自动加载功能。文档声明将来可能会删除__autoload
。
答案 1 :(得分:0)
class index {
function - construct(){
$this->load_template('index');
}
不是有效的PHP代码。你可以更改错误的触发器,然后粘贴完整的代码。