PHP несколько функций __autoload * без * использования spl_register_autoload?

Я являюсь автором растущей библиотеки кода, связанного с PHP + QuickBooks. Я хотел бы использовать функцию PHP __autoload (), однако мой код - это библиотека, которую другие люди могут включать () в свои собственные приложения, поэтому я не могу полагаться на то, что __autoload () еще не определенный.

Есть ли способ иметь несколько функций __autoload ()?

Я видел spl_autoload_register () в руководстве по PHP, но не у всех моих пользователей установлено расширение SPL, поэтому я не могу полагаться на это. Если бы был способ вернуться к использованию этого и по умолчанию использовать обычные операторы require / include, я бы подумал об этом.

Есть ли у кого-нибудь еще какие-нибудь умные решения этой проблемы? Похоже на вопиющую оплошность иметь возможность иметь только одну функцию __autoload () ...


person Keith Palmer Jr.    schedule 18.03.2010    source источник
comment
Что ж, я думаю, что ответ на проблему (один __autoload) был spl_autoload_register. Сейчас это довольно стандартно   -  person Tomasz Struczyński    schedule 18.03.2010


Ответы (3)


Я видел spl_autoload_register () в руководстве по PHP, но не у всех моих пользователей установлено расширение SPL, поэтому я не могу полагаться на это.

Игнорируйте их, он скомпилирован по умолчанию и даже не может быть отключен в 5.3.0. Не жертвуйте своей структурой в угоду меньшинству.

person The Pixel Developer    schedule 18.03.2010
comment
Это не вариант и не ответ. Вероятно, у 50% моих пользователей не включен SPL, и они не имеют возможности самостоятельно обновлять PHP (общий хостинг). Совместимость имеет первостепенное значение для библиотек классов, особенно тех, за которые мне платят. - person Keith Palmer Jr.; 18.03.2010
comment
Руководствуясь здравым смыслом, направьте их к хостинг-провайдеру. Я хотел бы услышать их причины отключения SPL. А еще лучше пожаловаться хостинг-провайдеру и попросить об этом. - person The Pixel Developer; 18.03.2010
comment
Поверьте, я уже жаловался и почти не получил полезного ответа. У некоторых из этих людей установлены приложения, использующие имена классов, с которыми конфликтует SPL, у некоторых из них есть глупые хостинг-провайдеры, некоторые хостинг-провайдеры просто слишком ленивы для обновления и т. Д. И т. Д. И т. Д. все будут на 5.3.0, и мне бы не о чем беспокоиться. Однако это решение, которое я не могу заставить их принять, не потеряв кучу денег и не расстроив многих людей. Уууууу ... Мне нужно решение, не зависящее от SPL. - person Keith Palmer Jr.; 18.03.2010

Я решил, что способ сделать это, а также сохранить обратную совместимость, - это написать свой собственный класс «Загрузчик».

Вместо использования require_once 'TheFile.php' теперь я использую Loader :: load ('TheFile.php') ;. Метод Loader :: load () выполняет следующие действия:

if ( the function spl_autoload_register exists )
   register an autoloader
   return true
else 
   check if the file has already been included (static array var with a list of files)
   if not included yet
      require $file
   return true

Это дает мне возможность использовать автозагрузчик, если его установка PHP поддерживает его, и в противном случае вернуться к обычному использованию require $ file; типа вещи.

person Keith Palmer Jr.    schedule 19.03.2010
comment
В чем преимущество Loader::load('TheFile.php'); перед require_once 'TheFile.php';? Суть автозагрузчиков в том, что они не позволяют явно загружать файлы PHP. - person niutech; 21.04.2015
comment
Если их установка PHP поддерживает автозагрузчики, она будет использовать автозагрузчик (например, в этом случае Loader :: load (..) ничего не делает). Если он не поддерживает автозагрузчики, значит, он требует_once. Вы получите значительный прирост производительности, если можно будет использовать автозагрузчик, но при этом поддерживать обратную совместимость. - person Keith Palmer Jr.; 21.04.2015

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

function loader1 ($className)
{
    if (is_file ('foo/' . $clasName))
    {
        include ('foo/' . $className);
        return (true);
    }
}

function loader2 ($className)
{
    if (is_file ('bar/' . $clasName))
    {
        include ('bar/' . $className);
        return (true);
    }
}

function loader3 ($className)
{
    if (is_file ('baz/' . $clasName))
    {
        include ('baz/' . $className);
        return (true);
    }
}

function __autoload ($className)
{
    $autoloaders = array (
        'loader1', 
        'loader2', 
        'loader3'
    );
    foreach ($autoloaders as $loader)
    {
        if ($loader ($className))
        return (true);
    }
    throw new Exception ('Failed to find class ' . $className);
}

ПРИМЕЧАНИЕ: Это "без манжеты", я не тестировал.

person GordonM    schedule 16.01.2012