Несколько простых способов увеличить производительность PHP

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

Но, что делать если вы только начинаете? Что делать если у вас небольшое приложение? Что вы можете сделать прямо сейчас, чтобы сразу почувствовать разницу в производительности?

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

Самое первое — это обновление до PHP 5.4

Во время написания этой статьи, последняя версия PHP была 5.5.5. если у вас есть соответствующий контроль над сервером, то следует рассмотреть возможность использования этой версии. В то время как 5.5 вводит много новых концепций и обновлений безопасности, он ещё слабо протестирован и мало используется на продуктовых серверах. Если php 5.5.5 не вариант, то минимальная версия должна быть PHP 5.4. PHP 5.3 не только почти 4 года, но ещё он медленнее и использует больше памяти чем PHP 5.4.

Работаете с Drupal? PHP 5.4 на 7% быстрее и использует в два раза меньше памяти чем PHP 5.3.

Автозагрузка

Автозагрузка представляет собой подключение файлов с классами, которые используются в вашем приложении, без необходимости вручную ссылаться на пути к этим файлам. Мы можем использовать Composer для достижения этого результата. Composer предназначен для управления зависимостями и был рассмотрен в предыдущих статьях. Для автозагрузки, вы можете просто добавить расположение классов в файл composer.json. Единственная конфигурационная опция, которая позволяет делать маппинг файлов является ключом в JSON массиве.

Например, если у вас есть классы в директории src то нужно определить вот так:

{
    "autoload": {
        "psr-0": { "": "src/" }
    }
}

Если ваши классы распространились по папкам resources или library, формат немного отличается:

{
    "autoload": {
        "classmap": ["resources/", "library/", "Something.php"]
    }
}

Однако, нужно знать, что такая автозагрузка снижает необходимость использовать require или include_once, производительность может пострадать, если попытаться загрузить большое количества файлов. Но вы можете, смягчить эту ситуацию, если будете использовать акселератор или кэширование через opcode. Альтернативный подход к автозагрузке файлов, которую так же стоить изучить является компонент Classloader в Symfony2 фреймворке, техника описана в этой статье.

Уменьшение использования памяти в коде

Есть определенные техники при использовании операторов, циклов, или присваивание значение переменной, которые используют меньше памяти и возможно может сделать всё приложение более производительным. При необходимости, можно сделать свойства объекта публичными, чтобы избежать лишних методов для доступа к этой переменной (сеттеры или геттеры), так будет использоваться меньше памяти при выполнении скрипта (но делать свойства публичными — это плохая практика в плане архитектуры проекта):

~~~{.php} <?php

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 и документированы в benchmarks. Они, очевидно, зависят от размера ваших значений данных и сложностью кода, но привыкание к хорошему в начале, даёт меньше головной боли в будущем.
### Профилирование
Объективные измерения того, насколько хорошо работает ваш шедевр обеспечивает ценную информацию и уменьшает субъективные отвлекающие. Профилировать код очень просто, но требует подключения отдельного расширения в PHP. Вы можете использовать расширения **XDebug extension** или **Advanced PHP Debugger (APD)** для профилирования вашего кода. Просто обновите `php.ini` или добавьте INI файл с соответствующими параметрами конфигурации:
Например XDebug конфигурация для OSX:
~~~{.ini}
[xdebug]
zend_extension="/usr/local/Cellar/php54-xdebug/2.2.3/xdebug.so"
xdebug.profiler_enable=1
xdebug.profiler_output_dir="/tmp"

Узнайте о том сколько тратят времени процессы или функции и если нужно настройте их ссотвествующим образом.

Для более надёжного профилирования и мониторинга, вы также можете провести установку инструментов из AppDynamics, которые при установке в качестве демона сервера и php расширения, позволяют проводить углубленный анализ ваших сложных и больших приложений. Это отличный вариант для оптимизации старого кода.

OpCode кеш

Последнее, но не менее важное, является выполнение кода в памяти. Это является более производительным, потому что такой подход снижает необходимость читать код с диска и компилировать его заново. По состоянию на PHP 5.5 OpCache — система кэширования с открытым исходным кодом от компании Zend, которая включена по умолчанию (еще одна причина для обновления). Для более ранних версий, вы легко можете установить ZendOpCache через PECL.

Пример конфигурации ZendOpCache на OSX:

~~~{.ini} [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 приложений. Эти техники достаточно простые, чтобы реализовать их прямо сейчас. Не ждите!