проблемы с автозагрузкой - PullRequest
2 голосов
/ 15 марта 2012

У меня проблема с функцией автозагрузки. Вот сценарий:

Примечание: MVC framework не мой.Я просто использую его, чтобы узнать больше об ООП и 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/';
?>

в конфигурации/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_once (/home/novacl/public_html/myMVC/application/libs/lib_index.php) [function.require-Once]:Не удалось открыть поток: нет такого файла или каталога в /home/novacl/public_html/myMVC/application/config/func_main.php в строке 6 **

Строка 6 находится в функции __autoload.

Так почему это происходит?Если контроллер индекса (controller / index.php) изменяется на:

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

Я не могу использовать его, потому что load_template не является методом index, это метод Boot класс ..

Что происходит?

Ответы [ 2 ]

2 голосов
/ 15 марта 2012

__autoload будет вызываться при попытке создать экземпляр класса, который еще не определен. Сообщение об ошибке указывает, что где-то код пытается создать класс с именем «index». Если он присутствует в примере кода, он, вероятно, $controller = new $this->request;. Вам нужно включить файл, который определяет класс 'index' перед этой строкой. Строка, расположенная непосредственно перед require_once( $this->controller.$this->request.'.php' );, является одним из мест, где вы можете это сделать, как вы определили.

Что касается того, что вызов $this->load_template('index') в index.php не работает, вы ни в коем случае не должны этого делать. С одной стороны, реализация класса должна содержаться в одном файле; в противном случае ваш код не очень сплоченный. С другой стороны, $this - это свободная переменная в файле, которая почти так же плоха, как глобальная, когда речь идет о ясности кода. Вместо этого должен существовать стандартный метод контроллера, который вызовет ваш диспетчер Boot; тело load_template является хорошим кандидатом для реализации.

Если вы не можете изменить базовый класс контроллера (у вас может не быть контроля над кодом платформы, но вы можете создать свой собственный форк, в зависимости от лицензирования), вы можете создать некрасивый хак и определить индексный класс и Назовите любой другой код за пределами класса:

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

Однако это ужасно с точки зрения дизайна. В дополнение к предыдущим причинам (разбросанная реализация, свободная переменная), он выполняет код в очевидной глобальной области действия, которая фактически является областью действия функции. Код библиотеки должен только определять вещи, а не выполнять код напрямую, из-за путаницы в области видимости, которую он может вызвать.

Одна вещь, которую вы должны сделать, это добавить вызов к file_exists в __autoload, чтобы не пытаться включить несуществующий файл. Однако это может привести к фатальной ошибке «Индекс класса не найден», если только вы не примените вышеуказанные исправления. Даже это предпочтительнее текущей ситуации, так как это дает вам более значимую ошибку.

Обратите внимание, что использование spl_autoload_register рекомендуется вместо определения функции __autoload, поскольку первая допускает несколько функций автозагрузки. В документе указано, что __autoload может быть удалено в будущем.

0 голосов
/ 15 марта 2012
class index {
function - construct(){

$this->load_template('index');

}

Недействительный код PHP.Не могли бы вы внести изменения, чтобы вызвать ошибки, а затем вставить этот полный код.

...