2016-02-12 3 views
1

Есть ли способ предварительно загружать (в отличие от автозагрузки) все классы/функции для проекта PHP?PHP - предварительная загрузка всех классов/функций

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

Вот некоторый контекст:

«Regular» PHP приложение обрабатывает один запрос, а затем они убили. Предварительная загрузка всех классов/функций означает большую загрузку, автозагрузка только классов, используемых для запроса, - это умная оптимизация, но она может быть дополнительно улучшена (требуется много операций «read filesystem», которые медленны), обычно путем группировки в один файл классы, которые, вероятно, будут использоваться для всех запросов (это то, что решает ClassPreloader).

Однако при загрузке приложения обрабатывать только один запрос, а затем убить его не единственный вариант: с PHP FastCGI можно поддерживать приложение между запросами. Это позволяет нам сэкономить время загрузки с момента запроса/ответа (например, создать экземпляр всех служб из DIC один раз).

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

Для получения дополнительной информации об этом "экзотическом" способе запуска PHP-приложениях, см:

+1

Проблема X/Y: почему вы хотите это сделать? – Andrea

+0

@ Аndrea классы автозагрузки для каждого запроса с FastCGI кажутся пустой тратой, когда все они могут быть предварительно загружены один раз и повторно использованы между запросами. –

+1

Пусть opcache обрабатывает его. – Andrea

ответ

1

Если вы используете композитор, возвращаемое значение вашего композитора включать заявление будет экземпляром Composer\Autoload\ClassLoader. Вызов метода loadClass() для этого объекта будет включать файл класса. Таким образом, когда вам действительно нужен класс, PHP уже будет знать свое определение и не нужно будет вызывать обратный вызов, который композитор регистрирует с помощью «spl_autoload_register».

<?php 

/** @var Composer\Autoload\ClassLoader **/ 
$classLoader = include 'vendor/autoload.php'; 

$classLoader->loadClass('Path\\To\\MyClass'); 
$classLoader->loadClass('Path\\To\\OtherClass'); 
// ... 

Редактировать: Обратите внимание, что, вероятно, более полезным в вашем сценарии является предварительная загрузка сервисов. Фактически создавая экземпляры классов, которые требуется вашему приложению, вероятно, более дорогостоящим, чем чтение PHP. Как предварительно загружать службы будут зависеть от вашего контейнера инъекций зависимостей, но просто «получение» службы заставит контейнер создать экземпляр и запомнить его.

+0

Спасибо, это на самом деле много думать, поэтому я вернусь к вам, когда я проведу несколько экспериментов –

4

Не использовать. Если opcache включен, а также может потерять память (не всегда нужно загружать все классы), выигрыш в производительности отсутствует.

Вот тест: https://phpixie.com/blog/benchmarking-autoloading-vs-combining-classes-into-a-single-file.html

+1

Я не думаю, что это то же самое, что он спрашивает. В его случае классы будут загружены до того, как процесс ответит на запрос, поэтому время, необходимое для загрузки всех классов, не повлияет на время ответа. @LoicFaugeron это правильно? –

+0

@MatthieuNapoli да, вы правы. С FastCGI классы будут предварительно загружены один раз, а затем повторно использованы для каждого запроса. –

+0

В этом случае нет смысла не использовать normala utoloading. Потому что после нескольких запросов все классы будут загружаться в любом случае. – Dracony

0

Получается, что у композитора есть возможность предварительно включить файлы. См. doc. Скопирован из дока:

{ 
    "autoload": { 
    "files": ["src/preload.php"] 
    } 
} 

Вы можете запустить необходимую загрузочный код/​​преднагрузку, а в вашем случае использовании:

class_exists(SomeClass1::class, TRUE); 
class_exists(SomeClass2::class, TRUE); 

Какого трюк, чтобы заставить автозагрузку класса.

Смежные вопросы