Существует ряд правил, которые стоит соблюдать, чтобы увеличить скорость работы приложений на PHP. Правила простые и не потребуют значительных изменений в существующих приложениях.
FastCGI — это один из вариантов подключения PHP к Web серверу. Лучше всего использовать в связке с Nginx. PHP-fpm (Fastcgi контейнер для PHP) и Nginx по умолчанию поддерживают совместную работу и очень легко настраиваются.
Как обычно выполняется PHP скрипт? PHP открывает файл с кодом, компилирует его, затем выполняет. Поскольку файлов может быть много, процесс их открытия, чтения и компиляции может отнимать кучу ресурсов. Если файлы не меняются, то постоянную компиляцию можно и не делать. Лучше сделать ее один раз и закэшировать результат.
Именно это и делает модуль opCache. Результат первой компиляции будет сохранен в кэш, с которым и будет работать PHP. Таким образом это ускорит выполнение за счет отсутствия тяжелого процесса компиляции. Когда файлы изменятся, модуль сам сбросит кэш и обеспечит перекомпиляцию. Короче, этот модуль делает очень полезную экономию ресурсов. И это без необходимости его настраивать.
В версии PHP5.5+ этот модуль поставляется в стандартной сборке. В предыдущих версиях модуль нужно устанавливать самостоятельно. Проверить наличие можно так:
php -i | grep opcache
Пустой вывод будет означать, что модуля нет
Если версия слишком ранняя, лучше использовать APC:
apt-cache search php-apc
Это альтернатива opCache, но делает то же самое
Часто код просто медленный. Например:
В этом случае, кэширование данных следует использовать как средство оптимизации.
Для PHP наиболее популярным решением для кэширования является Memcache. Очень простой в использовании и очень быстрый, т.к. поддерживает только самое необходимое.
Если Вы только установили PHP, убедитесь, что Вы настроили наиболее важные параметры под Ваш сайт. Это также может сэкономить ресурсы:
memory_limit = 32M
— не стоит устанавливать этот параметр слишком большим. Увеличивайте его только в крайних случаях.zlib.output_compression = Off
, zlib.output_compression_level = -1
— компрессию лучше использовать на стороне Web сервера.max_execution_time = 5
— максимальное время работы скрипта не должно быть больше 5 секунд. Увеличивайте только в крайних случаях.zend.enable_gc = On
— включает сборщик мусора (будет оптимизировать память на фоне).expose_php = Off — PHP
не будет отправлять свою версию вместе с ответом.report_memleaks = On
— будет отправлять в лог ошибок информацию об обнаруженных утечках памяти.post_max_size = 4M
, upload_max_filesize = 4M
— настройте максимальный размер запросов и файлов для загрузки. Защитит от обработки громадных запросов, которых не должно быть в приложении.По умолчанию, PHP хранит сессии в файлах. Это довольно эффективное решение. Но когда файлов становится очень много (десятки тысяч), работа с ними будет замедляться в рамках одной папки (особенности файловых систем). В этом случае лучше перенести сессии на Memcache (php.ini):
session.save_handler = memcache session.save_path = "tcp://localhost:11211" localhost:11211 это стандартный хост и порт Memcache
Кроме этого, такая схема хранения позволит масштабироваться на несколько серверов.
Помните! ООП — это всегда медленно. Объекты нужно создавать, где-то хранить и уничтожать. Не используйте объекты, если они не нужны. Например, тут:
<?
$post = new Post();
$post->set_title($_GET['title']);
$post->set_description($_GET['description']);
$post->save();
Создаем объект только для того, чтобы сохранить данные в БД
<? # $posts = список объектов Post, полученных каким-то образом foreach ( $posts as $post ) { echo $post->title . '<br/>'; }
Используем список объектов только для того, чтобы вывести свойство
В этих примерах использование ООП не имеет особого смысла. Зато расходует ресурсы. Старайтесь использовать массивы, когда объекты не нужны.
<? mysql::insert(['title' => $_GET['title'], 'description' => $_GET['description']]);
Избежали создания объекта, функция просто сохраняет данные из массива в базу или тут:
$posts = mysql::query('SELECT title FROM posts'); foreach ( $posts as $post ) { echo $post['title'] . '<br/>'; }
Намного лучше — сделать простую выборку и вывести нужные данные из массива
При работе с файлами используйте абсолютные пути. Тогда не будут происходить лишние операции поиска файла:
<? include 'file.php'; file_get_contents('dir/data.txt'); include '/var/www/file.php'; file_get_contents('/var/www/dir/data.txt');
Константы классов работают эффективнее, чем define:
<? define('MAX_POSTS_PER_PAGE', 10); class posts { const PER_PAGE = 10; ...
Не используем функции в условии for, т.к. они будут повторяться на каждой итерации цикла:
<? for ( $i = 0; $i < mysql::get_col('SELECT count(*) FROM posts'); $i++ ) { ... } $max = mysql::get_col('SELECT count(*) FROM posts'); for ( $i = 0; $i < $max; $i++ ) { ... }
В качестве ключей массивов всегда указывайте строки с кавычками:
<? $post[title] = 'Первый пост'; $post['title'] = 'Первый пост';
Используйте встроенные функции работы со строками вместе регулярных выражений, если это возможно.
<? preg_match('/хорошо/ui', $post['title']); strpos($post['title'], 'хорошо');
Используйте строки с одинарными кавычками:
<? $post["title"] = "Почему?"; $post['title'] = 'В этом случае нет дополнительной обработки переменных'
Когда PHP используется для разработки скрипта, который будет выполняться по крону, следует избегать использования глобальных переменных. Частый пример, это просто использование общего массива:
<?
while ( true )
{
$rss = file_get_contents('http://somesite.com/rss');
preg_match_all('/title>(.+?)<\/title/', $rss, $matches);
}
Переменная $matches
передается по ссылке. Это значит, что с каждым новым повторением, она будет расти. Другой частый пример, это просто использование общего массива:
<? while ( true ) { $rss = file_get_contents('http://somesite.com/rss'); $has_something = preg_match('/title>(.+?)<\/title/', $rss); if ( $has_something ) $updates[] = time(); $rss = file_get_contents('http://othersource.com/rss'); $has_something = preg_match('/title>(.+?)<\/title/', $rss); if ( $has_something ) $updates[] = time(); }
Теперь переменная $updates
будет расти до максимального предела. Когда будет достигнут лимит по памяти, скрипт будет остановлен. Уследить за всеми переменными довольно тяжело, поэтому лучше использовать функции. Все переменные, созданные внутри функции будут удаляться после ее завершения:
<? while ( true ) process(); function process() { $rss = file_get_contents('http://somesite.com/rss'); $has_something = preg_match('/title>(.+?)<\/title/', $rss); if ( $has_something ) $updates[] = time(); $rss = file_get_contents('http://othersource.com/rss'); $has_something = preg_match('/title>(.+?)<\/title/', $rss); if ( $has_something ) $updates[] = time(); }
Этот текст был написан несколько лет назад. С тех пор упомянутые здесь инструменты и софт могли получить обновления. Пожалуйста, проверяйте их актуальность.
Прокси (proxy), или прокси-сервер — это программа-посредник, которая обеспечивает соединение между пользователем и интернет-ресурсом. Принцип…
Согласитесь, было бы неплохо соединить в одно сайт и приложение для смартфона. Если вы еще…
Повсеместное распространение смартфонов привело к огромному спросу на мобильные игры и приложения. Миллиарды пользователей гаджетов…
В перечне популярных чат-ботов с искусственным интеллектом Google Bard (Gemini) еще не пользуется такой популярностью…
Скрипт (англ. — сценарий), — это небольшая программа, как правило, для веб-интерфейса, выполняющая определенную задачу.…
Дедлайн (от англ. deadline — «крайний срок») — это конечная дата стачи проекта или задачи…