Лучшее решение для __ автозагрузка

Вот что происходит, когда вы используете style-loader. Это добавляет CSS к голове.

Вы должны использовать mini-css-extract-plugin для генерации внешнего CSS-файла.

10
задан hakre 1 July 2012 в 15:44
поделиться

10 ответов

Я также играл с автозагрузкой в течение достаточно долгого времени, и я закончил тем, что реализовал своего рода namespaced автопогрузчик (да, Это работает также на PHP5.2).

Стратегия довольно проста: Сначала у меня есть singleton-класс (загрузчик), который имеет вызов, который моделирует import. Этот вызов берет один параметр (полное имя класса для загрузки) и внутренне вычисляет имя файла, от которого это назвали (использование debug_backtrace()). Вызов хранит эту информацию в ассоциативном массиве для использования его позже (использующий файл вызова в качестве ключа и списка импортированных классов для каждого ключа).

Типичный код похож на это:

<?php

    loader::import('foo::bar::SomeClass');
    loader::import('foo::bar::OtherClass');

    $sc = new SomeClass();

?>

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

Я знаю, что Это не точно, что Вы просили, но это может решить проблему обхода каталога, поскольку загрузчик непосредственно знает, где файл точно (с дополнительной функцией, что Вам можно было организовать Ваши классы в каталогах без очевидной потери производительности).

Я мог предоставить Вам некоторые рабочие примеры, но я слишком застенчив, чтобы показать мой дрянной код общественности. Надежда вышеупомянутое объяснение была полезна...

2
ответ дан 4 December 2019 в 04:53
поделиться

Существует 2 общих подхода та работа хорошо.
Сначала использует ГРУШЕВУЮ структуру именования стандартного класса, таким образом, просто необходимо заменить '_' / для нахождения класса.

http://pear.php.net/manual/en/pear2cs.rules.php

Или можно искать каталоги php классы и имя класса сопоставления к файлу. Можно сохранить карту класса для кэширования для сохранения ищущих каталогов каждая загрузка страницы.
Платформа Symfony использует, они приближаются.

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

1
ответ дан 4 December 2019 в 04:53
поделиться

CodeIgniter делает что-то похожее с функцией load_class. Если я вспоминаю правильно, это - статическая функция, которая содержит массив объектов. Вызов к функции:


 load_class($class_name, $instansiate);

таким образом в Вашем случае


 load_class('Customer', TRUE);

и это загрузило бы экземпляр Клиентского класса в массив объектов.

Функция была довольно прямой. Извините я не могу помнить название класса, в котором это было. Но я действительно вспоминаю там быть несколькими классами, которые загружаются, такие как, я думаю класс Маршрутизации, класс Сравнительного теста и класс URI.

0
ответ дан 4 December 2019 в 04:53
поделиться

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

1
ответ дан 4 December 2019 в 04:53
поделиться

Вы исследовали использование Zend_LoaderregisterAutoload ()) вместо просто собственного компонента __autoload()? Я использовал Zend_Loader и был доволен им, но не посмотрел на него с точки зрения производительности. Однако это сообщение в блоге, кажется, сделало некоторый анализ производительности его; Вы могли сравнить те результаты со своим внутренним тестированием производительности на Вашем текущем автопогрузчике, чтобы видеть, может ли это оправдать Ваши надежды.

-1
ответ дан 4 December 2019 в 04:53
поделиться
function __autoload( $class )
{
    $patterns = array( '%s.class.php', '%s.interface.php' );

    foreach( explode( ';', ini_get( 'include_path' ) ) as $dir )
    {
        foreach( $patterns as $pattern )
        {
            $file    = sprintf( $pattern, $class );
            $command = sprintf( 'find -L %s -name "%s" -print', $dir, $file );
            $output  = array();
            $result  = -1;

            exec( $command, $output, $result );

            if ( count( $output ) == 1 )
            {
                require_once( $output[ 0 ] );
                return;
            }
        }
    }

    if ( is_integer( strpos( $class, 'Exception' ) ) )
    {
        eval( sprintf( 'class %s extends Exception {}', $class ) );
        return;
    }

    if ( ! class_exists( $class, false ) )
    {
        // no exceptions in autoload :(
        die( sprintf( 'Failure to autoload class: "%s"', $class ) );
        // or perhaps: die ( '<pre>'.var_export( debug_backtrace(), true ).'</pre>' );        
    }
}

Вы могли также найти некоторого другого, меньше posix зависимого способа выполнить итерации каталогов, но это - то, что я использовал.

Это пересекает все каталоги в include_path (набор в php.ini или .htaccess) для нахождения класса или интерфейса.

-3
ответ дан 4 December 2019 в 04:53
поделиться

При использовании APC необходимо включить кэширование кода операции. Я полагаю, что это обладало бы большим преимуществом для производительности и было бы более прозрачным решением, чем какая-либо стратегия класса/файла, которую Вы используете.

Второе предложение состоит в том, чтобы использовать любую стратегию класса/файла, является самым легким разработать против, но на Вашем месте производства, необходимо связать классы, используемые наиболее часто в один файл, и удостовериться, что это загружается во время каждого запроса (или кэшируется с APC).

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

0
ответ дан 4 December 2019 в 04:53
поделиться

Я использовал это решение в прошлом, я писал об этом в блоге для справки и может быть интересен некоторым из вас ...

Вот оно

1
ответ дан 4 December 2019 в 04:53
поделиться

I have specific naming conventions for each 'type' of class (controllers, models, library files, and so on...), so currently I do something similar to:

function __autoload($class){
    if($class matches pattern_1 and file_exists($class.pattern_1)){
        //include the file somehow
    } elseif($class matches pattern_2 and file_exists($class.pattern_2)){
        //include the file somehow
    } elseif(file_exists($class.pattern_3)){
        //include the file somehow
    } else {
       //throw an error because that class does not exist?
    }
}
0
ответ дан 4 December 2019 в 04:53
поделиться

Старая ветка, но я подумал, что все равно могу раскрыть здесь свой метод, может быть, это кому-то поможет. Так я определяю __ autoload () в точке входа на мой веб-сайт /path/to/root/www/index.php , например:

function __autoload($call) {
    require('../php/'.implode('/', explode('___', $call)).'.php');
}

Все файлы PHP организованы в дереве

/path/to/root/php
  /Applications
    /Website
      Server.php
  /Model
    User.php
  /Libraries
    /HTTP
      Client.php
    Socket.php

И имена классов:

Applications___Website___Server
Model___User
Libraries___HTTP___Client
Libraries___Socket

Это быстро, и если файл отсутствует, произойдет сбой, и в вашем журнале ошибок будет указано, какой файл отсутствует. Это может показаться немного резким, но если вы попытаетесь использовать неправильный класс, это ваша проблема.

NB: это было для PHP 5 <5.3, поэтому для PHP 5.3 вы можете использовать пространства имен, причина, по которой я использовал 3 _ в качестве разделителя, заключается в том, что это простая замена для использования пространства имен 5.3

0
ответ дан 4 December 2019 в 04:53
поделиться
Другие вопросы по тегам:

Похожие вопросы: