Простые советы по увеличению производительности PHP
Введение
Повышение производительности вашего сайта может потребовать очень многих действий: от настройки кэша обратного прокси-сервера с помощью Varnish до конфигурирования группы балансировщиков нагрузки.
Как быть, если вы не знаете с чего начать? Что делать, если у вас небольшое приложение? Что можно сделать, чтобы получить результат сразу?
В этой статье мы рассмотрим типовые способы увеличения производительности PHP, которые вы можете внедрить в свой процесс разработки.
Как минимум, обновитесь до PHP 5.4
На момент написания данной статьи, последней являлась PHP версии 5.5.5. Если у вас есть доступ к управлению программным обеспечением сервера, то следует использовать именно указанную версию PHP.
В PHP 5.5 реализовано много новых концепций, сделано немалое количество обновлений безопасности, и не следует этими нововведениями пренебрегать.
Если же PHP 5.5.5 не подходит, то, как минимум обновитесь до PHP 5.4. Версия PHP 5.3 была выпущена почти 4 года назад, она медленнее и потребляет больше памяти, чем версия 5.4.
Например, загрузка Drupal происходит на 7% быстрее именно при использовании PHP 5.4 и при этом требует практически на 50% меньше памяти.
Автозагрузка
Автозагрузка позволяет включать классы в файлы вашего приложения без необходимости их ручного подключения. Таким образом, достигается более высокая производительность, ведь подключение происходит лишь тогда, когда действительно создается экземпляр класса.
Для достижения поставленных целей, мы можем установить Composer – менеджер зависимостей.
Для автоматической загрузки, вы можете просто указать путь к классам в файле composer.json. Единственной настройкой здесь является расположение файлов, задаваемое ключами JSON-массива.
Предположим, что у вас есть классы, расположенные в папке src в формате PSR-0:
{
"autoload": {
"psr-0": { "": "src/" }
}
}
Если классы расположены в папках resources и library, то формат будет немного другой:
{
"autoload": {
"classmap": ["resources/", "library/", "Something.php"]
}
}
Однако, будьте осторожны: несмотря на то, что такой способ устраняет необходимость использования команд require и include_once, производительность может снизиться при попытке загрузки большого количества файлов.
Этот эффект может быть смягчен, если вы используете акселераторы или средства opcode-кэширования.
Альтернативой автозагрузчикам является компонент Symfony2 Classloader.
Уменьшение использования памяти в коде
Есть определенные техники с использованием операторов, циклов или переменных, которые могут повысить производительность вашего приложения.
По возможности, делайте свойства объектов публичными (public), чтобы избежать вызова лишних методов, которые к тому же еще и медленнее выполняются, чем обращение к переменной класса напрямую:
class A {
public $foo;
public function setFoo($bar) { $this->foo = $bar; }
public function getFoo() { return $this->foo; }
}
$bat = new A();
// Медленнее
$bat->setFoo('baz');
$baz = $bat->getFoo();
// Быстрее
$bat->foo = 'baz';
$baz = $bat->foo;
Указывайте размер циклов до начала итераций:
// Медленнее
for ($i = 0; $i < count($j); $i++)
// Быстрее
$count = count($j);
for ($i = 0; $i < $count; $i++)
Используйте функцию isset() перед началом любой операции:
// Проверяйте существование и тип переменной
if (isset($foo) && is_array($foo)) { return $bar; }
Все перечисленные техники являются частью рекомендаций Google и доказаны тестами.
Разумеется, они зависят от размера используемых вами значений и сложности кода, но привитие хороших привычек сейчас, избавит вас от головной боли в будущем.
Профилирование кода
Объективные измерения скорости работы вашего творения дают ценную информацию для анализа и уменьшают влияние субъективных суждений. Профилирование кода сделать очень просто, но это потребует компиляции расширений в среде PHP.
Вы можете использовать инструмент XDebug или Advanced PHP Debugger (APD) для выполнения профилирования кода.
Вам нужно всего лишь изменить файл php.ini или добавить INI-файл для вашего расширения со следующими настройками (приведен пример настройки ini-файла для XDebug под OSX):
[xdebug]
zend_extension="/usr/local/Cellar/php54-xdebug/2.2.3/xdebug.so"
xdebug.profiler_enable=1
xdebug.profiler_output_dir="/tmp"
Исследуйте, какие функции или процессы занимают больше всего времени и произведите соответствующие настройки.
OpCode-кэширование
Наконец, очень действенной является методика запуска скомпилированного кода из памяти. Это чрезвычайно эффективно, поскольку снижает необходимость считывания кода с диска и его компиляции при каждом запросе.
В PHP 5.5 (еще одна веская причина обновиться), OpCache, проект с открытым кодом, разрабатываемый Zend, включен по умолчанию.
Для боле ранних версий, вам нужно будет установить ZendOpCache через PECL.
Пример ini-конфигурации ZendOpCache под OSX:
[opcache]
zend_extension="/usr/local/Cellar/php54-opcache/7.0.2/opcache.so"
zend_optimizerplus.memory_consumption=128
zend_optimizerplus.interned_strings_buffer=8
zend_optimizerplus.max_accelerated_files=4000
zend_optimizerplus.revalidate_freq=60
zend_optimizerplus.fast_shutdown=1
zend_optimizerplus.enable_cli=1
zend_optimizerplus.enable_file_override=1
apc.cache_by_default = false
Итоги
Надеюсь, приведенные выше техники дадут вам хороший старт в деле оптимизации и ускорения PHP-приложений.
Будете ли вы делать полный рефакторинг вашего кода для совместимости с PHP 5.5 или просто оптимизируете циклы для меньшего потребления памяти, есть много способов, которыми вы можете повысить производительность прямо сейчас.
Не ждите! Делайте это прямо сейчас!