Обустройство локального и удаленного веб-сервера для PHP разработчиков. Переход на Nginx.

Изображение пользователя MacLeod.

Данное руководство предназначено для разработчиков на PHP, переходящих на повседневное использование (K)Ubuntu Linux и организующих на ней рабочее место; желающих перейти на nginx; а также всех тех, кто хочет разобраться, как гибко управлять (вручную, но быстро) компонентами своего локального / удаленного веб-сервера.
Следуя современному подходу, я не буду рассматривать использование, установку и настройку Apache. Консерваторам, противникам всего нового, ленивым и задающим вопрос «зачем это все надо?» я предлагаю рассмотреть очевидные преимущества Nginx.

  • Легковесный и быстрый. К примеру, 10 000 неактивных keep-alive соединений занимают примерно 2.5Мб памяти.
  • Является лучшим средством в качестве фронт-энда, т.е. для обработки клиентских запросов.
  • Предлагает очень гибкую настройку.
  • Без nginx уже не обходится практически ни один highload (высоконагруженный) проект на открытых технологиях. Опыт работы с ним и настройки может оказаться очень полезным.
  • В подавляющем большинстве случаев позволяет вообще отказаться от использования Apache.
  • Как следствие роста популярности, многие современные стеки приложений уже опираются на него, нежели Apache.

Но зачем это все лично вам, если у вас пока нет highload проектов?
Наверняка, через какое-то время, вам захочется арендовать VPS/VDS - виртуальный выделенный сервер (возможно, он у вас уже есть) и размещать на нем свой сайт, блог, созданные вами сайты (проекты) для ваших клиентов или какие-либо демонстрационные работы. Как правило, ресурсы на виртуальных серверах ограничены и использование nginx дает очевидные преимущества. Вы сможете получить лучшую скорость/отзывчивость на менее мощных и дешевых VPS.
От себя добавлю, что мне не удалось добиться на самой честной виртуализации KVM и тарифе 2x1000 Мгц / 2 Гб RAM, даже со всеми ухищрениями и использованием mpm_event апача, тех же результатов, которые дает nginx из коробки.
Поэтому, единообразие настроек и подобный опыт сможет помочь вам в любой момент поднять быстрый и эффективный сервер на любом железе / VPS. Также, в некоторых случаях, вы сможете сэкономить на панели ISPManager, арендовав пустой VPS и затратить не более 15-30 минут на его обустройство. Хозяин - барин, и выбор, использовать или нет, конечно же, делать вам.

Итак, при построении нашего сервера будут три основных независимых компонента:

  1. nginx — фронт-энд, обработка клиентских (браузерных) подключений;
  2. php-fpm — бэк-энд, менеджер процессов FastCGI для PHP;
  3. mysql — сервер баз данных.

Для новичков: вопреки тому, что традиционно их используют в связке, как и LAMP, они могут работать и совершенно независимо. Вы можете установить MySQL и использовать его из С++, Perl, Python и даже делать запросы и парсить результаты с помощью bash. Nginx вы можете использовать как веб-сервер для раздачи статики (html), как прокси-сервер, а можете с его помощью расшарить свои фильмы с компьютера для просмотра на мобильных устройствах (кстати, один из самых быстрых способов, например, на Nexus 7 смотреть FullHD фильмы без задержек в отличие от использования SMB). PHP же может быть установлен в систему как CLI и вы можете вызывать его из командной строки или писать shell скрипты на PHP.

Установка Nginx.

Под (K)Ubuntu есть три пакета, отличающиеся по количеству включенных модулей:
nginx-light — базовый набор;
nginx-full — стандартный набор;
nginx-extras — полный набор.

Если вы не знаете точно, какой вам нужен, я рекомендую в общем случае ставить nginx-full.
apt-get install nginx-full
Да, всего 400 килобайт скачалось и чуть больше мегабайта установилось =)
Кстати, для получения самой свежей стабильной версии для всех актуальных версий дистрибутива есть репозиторий ppa:nginx/stable, поддерживаемый разработчиками, а с версии 14.04 nginx добавлен в main и поддержкой вплотную обещали заняться Canonical.

Установка PHP

Не устанавливайте пакет php5, он потянет за собой апач.
apt-get install php5-fpm
В дополнение рекомендую поставить пакет php5-cli, для возможности вызова php-скриптов из командной строки. Расширения PHP устанавливать также очень просто, поставим базовый набор (допишите нужные вам):
apt-get install php5-cli php5-curl php5-gd php5-mcrypt php5-mysql

Установка MySQL.

Тут все просто:
apt-get install mysql-server
Установщик спросит у вас два раза пароль на пользователя root для MySQL.
Сразу, не отходя от кассы, внесем настройки в /etc/mysql/my.cnf в любое место секции [mysqld], например, после skip-external-locking
character-set-server = utf8
для дефолтного использования кодировки UTF-8 в таблицах.
Обратите внимание, что начиная с версии 5.5 тип таблиц, создаваемых по умолчанию, являются innodb. Если вам нужен тип myisam по умолчанию, допишите строку default-storage-engine = myisam, хотя лучше всегда писать точные запросы при создании таблиц.

Если вы переходите на использование nginx с апача, то вам нужно либо остановить и отключить автозапуск последнего, либо удалить пакеты с ним, nginx установить как показано выше, php переустанавливать не обязательно, достаточно доустановить пакет php5-fpm.

Конфигурация PHP.

Конфиги находятся в каталоге /etc/php5. Важно: для каждой конфигурации, будь то модуль апача, CLI или FPM существуют отдельные конфиги и, соответственно, отдельный php.ini.
Если у вас был апач, то конфиги под него находятся в /etc/php5/apache2 и больше использоваться не будут.
Для скриптов, вызываемых из консоли, будут использоваться конфиги из каталога /etc/php5/cli.
FPM же имеет некоторые отличия. Помимо отдельной конфигурации, он представляет собой менеджер процессов, работающий как демон. Nginx сам не запускает интерпретатор PHP и не «скармливает» ему конкретные скрипты, он только обрабатывает запросы, быстро отдает статику, но когда требуется выполнить скрипт — он передает эту задачу бэк-энду FPM, который намного лучше решает эту задачу, после чего результат идет по цепочке обратно (на самом деле, раньше это решалось через FastCGI, но этот метод устарел и в нынешних реалиях неэффективен).
Настройка FPM сводится к конфигурированию пулов, что дает большую гибкость. Если вам нужно выполнять скрипты от другого пользователя или с другими конфигурационными настройками — это можно сделать, создав новый пул.
По умолчанию создается пул www, конфиг которого находится в /etc/php5/fpm/pool.d/www.conf. Чтобы создать дополнительный, нужно просто скопировать файл в этот же каталог под новым именем, дать пулу другое имя в квадратных скобках и настроить под себя. На начальном этапе этого делать не требуется, важен лишь параметр listen.
Он может принимать значение listen = /var/run/php5-fpm.sock в случае использования unix-сокета и listen = 127.0.0.1:9000 в случае tcp-сокета (в различных дистрибутивах дефолтные параметры могут разниться). Через этот сокет происходит общение nginx и php-fpm.
На рабочем сервере / VPS параметры пула нужно будет настроить в соответствие нагрузке.
Внесем пару изменений в /etc/php5/fpm/php.ini, поскольку настраиваем сервер под разработку и нам нужно будет видеть все ошибки:
display_errors = On
error_reporting = E_ALL | E_STRICT

Для вступления изменений в силу, не нужно по привычке перезапускать веб-сервер, нужно перезапустить fpm:
service php-fpm restart

Создание виртуальных хостов.

Алгоритм добавления виртуального хоста следующий:

  • создать домашний каталог;
  • сделать копию /etc/nginx/sites-available/default в том же каталоге с новым именем и внести изменения;
  • сделать символическую ссылку созданного файла в /etc/nginx/sites-enabled/;
  • перезагрузить правила/конфиги nginx;
  • добавить запись в /etc/hosts (или DNS), чтобы получить возможность открывать в браузере.

Пара примеров. Начнем с «песочницы», где у нас будут всякие обрывки скриптов и тестовая фигня.
Для начала определимся, где у нас будут лежать домашние каталоги хостов и как их будем именовать. Как правило, единообразие в этом вопросе приводит к порядку и уменьшает головную боль в дальнейшем. Допустим, что пользователь в системе один, поэтому домашние каталоги расположим в /var/www (если нет — создадим, есть не пустой — очистим), а виртуальные хосты будем именовать через точку с local, например, для «песочницы» будет выглядеть как test.local.
Вы можете выбрать другой каталог, например в /home/user/www и выбрать другой принцип именования, но все же, рекомендую придерживаться единой схемы.

sudo -s
mkdir -p /var/www/test.local
chown -R user:user /var/www #где user — пользователь DE
cd /etc/nginx/sites-available
cp default test.local
nano test.local

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

Создаем ссылку (аналог команды a2ensite апача):
ln -s /etc/nginx/sites-available/test.local /etc/nginx/sites-enabled/

Удаляем дефолтный виртуальный хост:
rm /etc/nginx/sites-enabled/default

Перезагружаем правила:
service nginx reload
(отличается от restart тем, что не прерывает работы, полезно на работающих серверах)

Добавляем в /etc/hosts такую строчку:
127.0.0.1 test.local

Под юзером или в своей любимой IDE делаем файлик /var/www/test.local/test.php что угодно, вроде:
<?php
phpinfo
();
?>

Заходим в браузере на http://test.local

Установка и полноценная настройка phpmyadmin.
Приложения вроде phpmyadmin, drupal, wordpress и т. д. можно, конечно, поставить из пакетов, но... версии в пакетах практически всегда устаревшие, потянут апач, да и все равно потребуют серьезной настройки, так что будем ставить свежую версию и настраивать ее для получения максимальной функциональности.
Архив с последней версией можно получить тут http://www.phpmyadmin.net/, создаем каталог /var/www/mysql.local, распаковываем туда файлы из архива.
Настраиваем для него отдельный виртуальный хост, теперь это еще проще.
Копируем наш шаблон /etc/nginx/sites-available/test.local в /etc/nginx/sites-available/mysql.local, правим: убираем default в директиве listen, изменяем домашний каталог, имя сервера и пути к логам

создаем ссылку в sites-enabled, делаем reload
ln -s /etc/nginx/sites-available/mysql.local /etc/nginx/sites-enabled/
service nginx reload

добавляем запись в /etc/hosts
127.0.0.1 mysql.local
В принципе, phpmyadmin уже готов к работе и доступен из браузера через http://mysql.local, но локально каждый раз вводить пароль не комильфо, а часть функционала не будет задействована, пока не создать для phpmyadmin собственную базу.
Заходим в phpmyadmin под root, нажимаем «Импорт», выбираем файл /var/www/mysql.local/examples/create_tables.sql. Создастся база phpmyadmin, выбираем ее, нажимаем «Привилегии», «Добавить пользователя», указываем имя пользователя pma, хост — локальный, создать пароль — жмем «Генерировать», копируем пароль в буфер обмена. Должна стоять галочка «Выставить полные привилегии на базу данных phpmyadmin», глобальные привилегии не даем, жмем внизу «ОК».
Переименовываем файл /var/www/mysql.local/config.sample.inc.php в config.inc.php и правим:

Дополнительная информация по параметрам конфигурации http://php-myadmin.ru/doc/config.html.

Нажимаем в phpmyadmin иконку «выход» и видим, что авторизация больше не требуется, внизу правого фрейма больше нет предупреждений и у нас самая новая и полнофункциональная версия со всеми удобствами.

По аналогии вы можете сделать виртуальный хост под рабочий проект и еще неограниченное количество оных.

Поиск и решение проблем.

Если что-то не заработало — читайте логи. Не ленитесь писать для каждого виртуального хоста свой лог - будет намного проще найти причину проблемы. Также, если все работает верно, FPM передает ошибки и предупреждения stderr Nginx и результат будет писаться в /var/log/nginx/.
Также частой проблемой начинающих является превышение лимита client_max_body_size при передаче между nginx и fpm, возникающую, например, при попытке загрузить файл на сервер через POST. Решается добавлением
client_max_body_size 20M
в блок server отдельного виртуального хоста, либо в блок http в файл /etc/nginx/nginx.conf для всех хостов. На рабочем сервере желательно согласовать размер с настройками PHP.
Если встречается ошибка "could not build the server_names_hash, you should increase server_names_hash_bucket_size: 32", нужно добавить в http блок
server_names_hash_bucket_size 64;

На какие технологии стоит обратить внимание.

Для дальнейшей оптимизации рабочего сервера / VPS стоит обратить внимание на следующие вещи.
memcached — связующее программное обеспечение, реализующее сервис кэширования данных в оперативной памяти на основе парадигмы хеш-таблицы. Для работы из php есть расширения php5-memcache или php5-memcache. Также, nginx умеет брать статику / часть контента из memcached напрямую. Поддерживается плагинами многих готовых решений (drupal, wordpress etc).
zend opcache - данное расширение сохраняет компилированный байт код скрипта и повышает производительность, избавляя от интерпретации кода при каждом обращении к скрипту. В отличие от Zend Optimizer, Zend Opcache не загружает файлы, закодированные по Zend Guard, и является только акселератором. Входит в состав начиная с версии 5.5, однако собрать и подключить можно начиная с 5.3.

Версии PHP.

В (K)Ubuntu 12.04.3 LTS по умолчанию 5.3.10. Версию 5.5 можно получить, используя репозиторий ppa:ondrej/php5, а версию 5.4 - ppa:ondrej/php5-oldstable.
Для (K)Ubuntu 13.10 текущая версия 5.5.3.
Для Debian 7.3 текущая версия 5.4.4
В (K)Ubuntu 14.04 текущей будет 5.5.х, но поскольку она будет LTS, предположу, что после релиза появятся репозитории с пакетами 5.4 (не точно).

____________________________________________________________________
Буду признателен за дополнения и полезные советы для начинающих.

Комментарии (47)

0
Condor - 5 Февраль, 2014 - 07:09
Изображение пользователя Condor.

Nginx несомненно хорош, но заменить апач он сможет только после того, как научится работать с .htaccess.
Использую nginx кеширующим сервером перед апачем, но как отдельный сервер рановато будет, так CMS, которые часто используются в работе, требуют настроек в .htaccess.

+3
MacLeod - 5 Февраль, 2014 - 12:01
Изображение пользователя MacLeod.

Хороший вопрос.
В Nginx никогда не будет поддержки htaccess. Вот обоснование и цифры (к сожалению, на английском).
Если вкратце: такой подход в корне противоречит общему подходу nginx. Если включить htaccess в Apache - это означает, что каждый раз, когда Apache обслуживает файл или каталог, он должен проверить этот каталог и каждый каталог над ним, чтобы узнать, есть ли изменения в htaccess в любом их этих каталогов, при каждом обращении. Это жуткое расточительство и крайне отрицательно сказывается на производительности и потребляемых ресурсах.
Реализовать некую альтернативу, конечно, можно. Но если проводить аналогию - это все равно, что тащить в Linux поддержку виндовых bat-файлов, не желая изучать, например, bash. Хорошее знание (желание разобраться) nginx позволяет переписать любой функционал htaccess используя правильный подход.
На начальном этапе, можно использовать htaccess-конвертер для nginx или то многообразие готовых примеров nginx конфигов для, практически, всех распространенных CMS и фреймворков, которые можно найти в сети.
Лично я не вижу смысла держать апач ради 4-5 строчек в htaccess и успешно избавился от него везде.

0
Vorobey - 27 Март, 2014 - 23:57
Изображение пользователя Vorobey.

я правильно понял - если скрипт имеет .htaccess файл, то работать правила не будут по этой инструкции?

0
RA9OAJ - 28 Март, 2014 - 05:44
Изображение пользователя RA9OAJ.

Угу, поэтому юзаем вышеуказанный конвертер.

0
MacLeod - 28 Март, 2014 - 06:21
Изображение пользователя MacLeod.

Сходу, вероятно, нет. Но после описания функционала из .htaccess в конфиге nginx - все будет летать.

0
dm - 5 Февраль, 2014 - 12:39
Изображение пользователя dm.

Пока мне получалось обойтись одним nginx без апача. Как пример, кубунту.ру и множество других сайтов на одном nginx работает. А про какие CMS идет речь, в которых без .htaccess не обойтись?

0
Condor - 5 Февраль, 2014 - 13:03
Изображение пользователя Condor.

Joomla, Opencart.
Но и многие хостеры по-умолчанию используют LAMP, если ты принципиально хочешь что-то иное, нужен VDS.
Для обычных сайтов и интернет-магазинов, необходимости в VDS нет.
Но для высоконагруженных самописных сервисов, это да, лучшего решения чем nginx не найти.

0
dm - 5 Февраль, 2014 - 13:09
Изображение пользователя dm.

C джумлой не работаю, ничего сказать не могу, а вот opencart вполне себе на nginx без апача работает. Могу пример рабочего конфига nginx под него предоставить. Но у меня да, свой сервер на котором что хочу то и ворочу, сайты на друпале в основном, так же как и кубунту.ру.

0
MacLeod - 5 Февраль, 2014 - 13:14
Изображение пользователя MacLeod.

Навскидку:
http://docs.joomla.org/Nginx
https://github.com/david-rahrer/nginx-opencart
Подобные штуки прекрасно гуглятся. И подсмотреть там ключевые моменты для своего конфига - обычно никаких проблем не составляет.

0
Condor - 6 Февраль, 2014 - 13:52
Изображение пользователя Condor.

Да, пораскинув мозгами можно всй что угодно куда угодно прикрутить, и, скорее всего, это будет действительно работать быстрее.
Но опять же таки, для визитки булочной или парикмахерской, нафиг не нужен VDS, который будет стоить раза в 3-4 дороже, чем обычный ламповый хостинг.

+1
RA9OAJ - 14 Февраль, 2014 - 05:48
Изображение пользователя RA9OAJ.

Joomla спокойно живет и в nginx.

0
XaHyMaH - 16 Февраль, 2014 - 11:03
Изображение пользователя XaHyMaH.

Как можно поставить почтовый эмулятор? Чтобы проверять как работает mail() или Mail.

0
MacLeod - 16 Февраль, 2014 - 21:34
Изображение пользователя MacLeod.

Ну, это не винда, тут не нужны эмуляторы. Вы можете настроить почтовый сервер для локального домена так же, как сделали бы это на реальном сервере. Ключевые слова: sendmail, exim4, dovecot, postfix. Гуглите, выбирайте понравившийся, нужно будет разобраться, что отвечает за отправку, что за хранение, что за предоставление доступа. Плюс потребуется настройка локального DNS.
В /etc/php5/fpm/php.ini, возможно, потребуется настройка таких параметров как sendmail_path (по умолчанию испольуется sendmail, но можно вписать exim4 и т.д. Например:
sendmail_path = /usr/sbin/exim4 -t
Также можно указать sendmail_from.
Аналогом PHP mail() является сокетное соединение с удаленным сервером. Примеров реализации в сети навалом, также есть подобные плагины под различные фреймворки/CMS.

+2
MacLeod - 28 Декабрь, 2014 - 18:34
Изображение пользователя MacLeod.

Отвечаю на поступивший вопрос:
Вот сделали мы типа сервер. А как теперь с другой машины через браузер смотреть его?
На те что вордресс.локал и иже с ними?
На машине где устанавливали вроде все норм. А как с другой?
Ведь прикольнее когда сервер - это другой компьютер.

Мне казалось эти строчки
location / {
try_files $uri $uri/ /index.php;
}
должны что-то делать подобное.
Но заход с другого компа дает тока посмотреть на Вэлком nginx (((

1. Данные строчки работают уже с внутренней структурой виртуального хоста. Подробнее лучше почитать в документации:
про location
http://nginx.org/ru/docs/http/ngx_http_core_module.html#location
про try_files
http://nginx.org/ru/docs/http/ngx_http_core_module.html#try_files.
2. Если с другой машины отображается welcome to nginx, значит вы не удалили default из sites-enabled. В любом случае, один из хостов вы сможете наблюдать с других машин в сети - тот, который помечен как хост по умолчанию. Обратите внимание на конфиг test.local в статье, я его сделал дефолным через
listen 127.0.0.1:80 default;
Важно, что при этом остальные хосты должны быть без ключевого слова default, например в конфиге mysql.local:
listen 127.0.0.1:80;
В таком случае, при обращении с другой машины на http://ip_машины_с_nginx/, вы всегда будете попадать в test.local.
3. Для более полного понимания происходящего, желательно изучить основы работы протокола HTTP. Если совсем вкратце и просто, то любой запрос состоит из: типа запроса (GET, POST, PUT...), пути, заголовка и тела запроса.
Когда вы указываете http://test.local/ в браузере, браузер сначала резолвит имя в ip. В случае локального использования - адрес берется из /etc/hosts. После получения ip, браузер отправляет GET запрос следующего вида:
GET /
указывая в заголовке host: 'test.local' и еще несколько параметров.
Именно по параметру host из заголовка nginx определяет, какой виртуальный хост запрашивается, после чего обрабатывает url, идущий после GET.
Теперь почему "GET /" - потому, что в случае http://test.local/ идет обращение к корню виртуального хоста. Если бы в браузер был вбит адрес http://test.local/labuda.php, GET выглядел бы так:
GET /labuda.php
Или, в случае http://test.local/catalog/labuda.php, был бы таким:
GET /catalog/labuda.php
Теперь про обращение с другой машины. Допустим, что ip машины с nginx в сети - 192.168.1.150, тогда в браузере с другой машины этой подсети вы наберете http://192.168.1.150/, при этом запрос будет
GET /
а параметр host из заголовка будет содержать 192.168.1.150, но поскольку в конфигах такой не описан, запрос пойдет на хост, помеченный как default (как описано в п.2 выше).
Если вы хотите, чтобы все ваши хосты были доступны с других машин в сети - у вас в этой сети должен быть DNS-сервер, который бы резолвил нужные адреса вроде drupal.local или wordpress.local в ip машины с nginx. Это не часть настройки nginx, это часть настройки сети.


На реальном сервере или VPS/VDS нужно в параметре listen указывать фактический белый (внешний) ip этого сервера/VPS, который будет доступен всем. Опять же, при заходе на http://ip_этого_сервера/ будет выдаваться содержимое виртуального хоста, отмеченного как default. Далее, допустим, вы купили домен kubuntu.ru. Вам нужно делегировать управление его DNS записями двум (для надежности) DNS-серверам. Например, хостинг провайдеры предоставляют такую услугу или можно воспользоваться бесплатным сервисом от яндекса. Как только вы правильно настроите DNS и ваш домен начнет у всех пользователей интернет резолвить ip вашего сервера, при заходе на него через браузер с любой машины последует подключение на ваш сервер с параметром host равным kubuntu.ru. Если ваш сервер настроен на работу с ним - nginx отдаст содержимое, если нет - отдаст default. Аналогично настраиваются поддомены третьего уровня, например ivan.kubuntu.ru, в конфиге будет:
...
listen белый_ip_сервера:80;
...
server_name ivan.kubuntu.ru;
...

+1
MacLeod - 11 Декабрь, 2015 - 18:33
Изображение пользователя MacLeod.

В связи с релизом PHP 7.0, возможно, кому-нибудь станет интересно, кто там чего двигает и что делается.
Интервью с Дмитрием Стоговым (один из ведущих разработчиков PHP и техлид по вопросам производительности в Zend, наш соотечественник).

Хоть сам уже давно считаю PHP проигравшим любой application style/event based модели, было интересно.
0
MacLeod - 16 Февраль, 2016 - 19:51
Изображение пользователя MacLeod.

Решил проверить, намедни, как будет работать один из моих форумов на движке vBulletin 4.x на PHP7 (на момент проверки 7.0.3).
Нарвался на забавную несовместимость.
Как известно, в PHP для реализации коллбэков, вместо указателей на функции, используется обращение к функциям через переменные.

<?php

class SomeClass
{
        public function
SomeFunc()
        {
                echo
"SomeFunc called\n";
        }
};

$obj = new SomeClass;

?>

Такой вариант продолжает работать:
<?php

$callback
= 'SomeFunc';
$obj->$callback();

?>

А такой:
<?php

$tag_info
['callback'] = 'SomeFunc';
$obj->$tag_info['callback']();

?>

выдает следующее:
PHP Notice:  Array to string conversion in /home/max/tmp/test.php on line 33
PHP Notice:  Undefined property: SomeClass::$Array in /home/max/tmp/test.php on line 33
PHP Fatal error:  Uncaught Error: Function name must be a string in /home/max/tmp/test.php:33
Stack trace:
#0 {main}
  thrown in /home/max/tmp/test.php on line 33

не смотря на то, что is_string($tag_info['callback']) выдает true.
То есть, при вызове воспринимается как массив, а не как элемент ассоциативного массива типа string.
Можно прокостылить так:
<?php

$tag_info
['callback'] = 'SomeFunc';
$callback = $tag_info['callback'];
$obj->$callback();

?>

либо использовать области видимости при подобных вызовах (новая фича 7 версии).

0
Vorobey - 26 Май, 2016 - 01:18
Изображение пользователя Vorobey.

Настраиваю phpmyadmin конфиг

При заходе в mysql.local пишет Welcom to nginx!, а при mysql.local/index.php 404

Хочу в домашнем каталоге чтоб все было. kubuntu 16.04

0
MacLeod - 26 Май, 2016 - 09:08
Изображение пользователя MacLeod.

1. Основная ошибка - пропустили шаг с созданием симлинка на конфиг в /etc/nginx/sites-enabled/.
У вас в /etc/nginx/sites-available/ может находиться любой хлам, наброски, старые конфиги и даже невалидные конфиги. Nginx читает только конфиги, на которые сделаны симлинки, например:
ln -s /etc/nginx/sites-available/mysql.local /etc/nginx/sites-enabled/
2. Вовсе необязательно разносить хосты по отдельным IP (у вас - "listen 127.0.0.3:80;"), в случае если собираетесь использовать имена (server_name), хотя это ваше право.
3. Эта конструкция "fastcgi_pass 127.0.0.3:9000;" - точно работать не будет. Nginx проксирует запросы на php-fpm и этот параметр используется для задания пути, куда проксировать, т.е. реально прослушиваемый php-fpm'ом ip/порт или unix-сокет.
В 16.04 php-fpm по умолчанию прослушивает unix-сокет, получить можно через:
root@home:~# cat /etc/php/7.0/fpm/pool.d/www.conf | grep 'listen ='
listen = /run/php/php7.0-fpm.sock

следовательно вписываем так:
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
Или перенастраиваем php-fpm как нам нравится и вписываем другие значения.
4. В свежих версиях конструкция "include fastcgi_params;" тоже не будет работать, параметры перенесли в snippets/fastcgi-php.conf.

P.S. Не забудьте, что для работы phpMyAdmin нужны расширения php7.0-mysql и php7.0-mbstring. Без последнего запросы будут выполняться с ошибкой 500, а причины писаться в /var/log/nginx/mysql.local.error.log.

0
Vorobey - 26 Май, 2016 - 23:15
Изображение пользователя Vorobey.

Спасибо подхватил конфиг - ошибся с
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
                include snippets/fastcgi-php.conf;

Ругалось на отсутствие mb_detect_encoding()

Решает проблему sudo apt-get install php-mbstring

Как вообще понять каких модулей не хватает. Каждый раз смотреть в лог и недостающее устанавливать?

+1
MacLeod - 27 Май, 2016 - 08:12
Изображение пользователя MacLeod.

Логи - универсальный способ определить причину проблем.
Помимо этого, в случае локальной машины, можно выставить в /etc/php/7.0/fpm/php.ini
error_reporting = E_ALL
display_errors = On

чтобы все ошибки и предупреждения вываливались прямо на страницу.
Ну, а еще можно заглянуть в документацию https://docs.phpmyadmin.net/en/latest/require.html#php и посмотреть требования =)

0
Vorobey - 9 Июнь, 2016 - 00:17
Изображение пользователя Vorobey.

Как отключить ошибки "..extension is deprecated.." ?
Перепробовал любые комбинации.
Работает только display_errors = Off но мне нужно другие ошибки видеть...
В корне сайта нет php.ini в index.php тоже отключено.
Вобщем какую директиву не установи все равно ругается на mysql_ нужно mysqli_
php5.5
ps в админ панели выводится содержимое ошибки одной строкой и не сильно напрягает.
А вот на сайте ошибка в типе содержимого. Очевидно перед буфером вываливает и гадит vqmod - но удалить его сейчас нельзя, нужно доделать все. display_errors = Off все отлично.

0
MacLeod - 9 Июнь, 2016 - 07:09
Изображение пользователя MacLeod.

Перепробовал любые комбинации.
Вы великий комбинатор или программист? =)
Вспоминаем побитовые логические операции...

Параметры, касаемо того, какие ошибки рапортовать, все находятся в переменной error_reporting.

Это означает, что отображаться будет вообще всё:
error_reporting = E_ALL

Это вовсе не означает, что нужно выбрать один из вариантов. Их можно сочетать.
Например, мы можем отображать все опции (E_ALL), но отключим нужный нам вариант E_DEPRECATED, который так злостно ругается на функции mysql_*.

Получается:
error_reporting = E_ALL & ~E_DEPRECATED

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

Посмотрим, как E_ALL отображается в двоичном виде:
0000000000000000000000000000000000000000000000000111111111111111
как видим - всё включено.

Теперь посмотрим как выглядит в двоичном виде E_DEPRECATED:
0000000000000000000000000000000000000000000000000010000000000000
ага, мы видим позицию, которая отвечает за отображение предупреждений об устаревших конструкциях.

Но как нам изменить данный бит в E_ALL на ноль?
Тоже просто - вначале применяем к E_DEPRECATED операцию побитового отрицания (инверсии, знак ~), получаем:
1111111111111111111111111111111111111111111111111101111111111111
После чего объединяем данное значение с E_ALL при помощи побитового "и" (операция &), что оставит истинными только те биты, которые истинны в обоих значениях, получаем:
0000000000000000000000000000000000000000000000000101111111111111
Как видим - получилось то же "все включено", за исключением бита, отвечающего за E_DEPRECATED.

Проверяем с помощью скрипта
<?php mysql_connect(); ?>
который при error_reporting = E_ALL выдаст
PHP Deprecated:  mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in /home/max/test.php on line 3
PHP Warning:  mysql_connect(): Access denied for user ''@'localhost' (using password: NO) in /home/max/test.php on line 3

а при error_reporting = E_ALL & ~E_DEPRECATED уже без deprecated:
PHP Warning:  mysql_connect(): Access denied for user ''@'localhost' (using password: NO) in /home/max/test.php on line 3

Соответственно, можно сочетать любые константы, например, E_ALL & ~E_DEPRECATED & ~E_STRICT или как-то еще.
Почему PHP-шники не любят побитовые операции? =)

0
Vorobey - 9 Июнь, 2016 - 22:16
Изображение пользователя Vorobey.

Получается:
error_reporting = E_ALL & ~E_DEPRECATED
естественно! Это работало на apache2
Яж говорю: любой параметр выводит сообщение о устаревшей функции.

ps

Почему PHP-шники не любят побитовые операции?бесполезная вещь

0
MacLeod - 10 Июнь, 2016 - 00:10
Изображение пользователя MacLeod.

Яж говорю: любой параметр выводит сообщение о устаревшей функции.
Вот apache тут точно не при чем. Варианта два:
1) вы ошиблись и отредактировали не тот php.ini (от другой версии или от cli);
2) где-то в стриптах есть вызов функции error_reporting(E_ALL); которая переопределяет значение из php.ini.

На коротком скрипте как я показывал выше проверяли?

бесполезная вещь
Как бы не так. Битовые поля и операции с ними позволяют делать самые эффективные структуры данных. Видимо, вы еще не сталкивались с обработкой больших объемов.
http://blog.getspool.com/2011/11/29/fast-easy-realtime-metrics-using-redis-bitmaps/ - простой пример, как получить количество уникальных посетителей за текущий день, для 128 миллионов пользователей запрос выполняется за 50 миллисекунд с потреблением памяти всего в 16 мегабайт. При этом результат содержит актуальные данные в реальном времени, без какого-либо кэширования.

0
Vorobey - 12 Июнь, 2016 - 01:21
Изображение пользователя Vorobey.

есть вызов функции error_reporting(E_ALL);в vqmod/vqcache/vq2-system_startup.php:error_reporting(E_ALL);
что за идиот его придумал(vqmod)...

0
XaHyMaH - 29 Май, 2016 - 10:35
Изображение пользователя XaHyMaH.

Не могу поставить php5-fpm на 16.04 - package is not available

0
dm - 29 Май, 2016 - 10:39
Изображение пользователя dm.

Вероятно потому, что в 16.04 php 7-ой версии.

sudo apt install php7-fpm

0
MacLeod - 29 Май, 2016 - 10:50
Изображение пользователя MacLeod.

Я статью писал в январе 2014-го, надо бы правки внести с учетом новых дистрибутивов...
В 16.04 выбросили старье, имя пакета теперь php7.0-fpm, соответственно названия пакетов с расширениями теперь тоже начинается с 'php7.0-'.

0
Vorobey - 3 Июнь, 2016 - 01:01
Изображение пользователя Vorobey.

Возможно на всю эту связку поставить php 5.5 (как 14,04)?
Чтобы для конкретного хоста можно устанавливать версию php.

Получилась жопа конкретная. Работает только PhpMyadmin и самописные скрипты, все остальное нужно фактически допиливать с нуля - это не реально.

+3
MacLeod - 3 Июнь, 2016 - 04:02
Изображение пользователя MacLeod.

Можно.

sudo apt-add-repository ppa:ondrej/php
sudo apt-get update
sudo apt-get dist-upgrade

При этом php7 обновится на свежую версию из ppa. Далее:

sudo apt-get install php5.5-fpm
и нужные модули для 5.5, имена их пакетов будут начинаться с 'php5.5-'. Кстати, можно таким же образом поставить версию 5.6.

Видим, что

Теперь делаем конфиги nginx в /etc/nginx/sites-available/:

и создаем на все три - симлинки в /etc/nginx/sites-enabled/. Обратите внимание, я сделал алиасы на бэкэнды для удобства использования в параметре fastcgi_pass.

Результат - http://i79.fastpic.ru/big/2016/0603/2d/42e5e2fbfdd210f9c2ffb1b9a7ca422d.png.
Итого, разные хосты используют различные версии PHP.

0
Vorobey - 4 Июнь, 2016 - 01:07
Изображение пользователя Vorobey.

Честно говоря я не понял для чего php_backends и где этот файл должен быть?

0
MacLeod - 4 Июнь, 2016 - 13:12
Изображение пользователя MacLeod.

Вы можете его не создавать, а в каждом хосте прописывать
fastcgi_pass unix:/run/php/php_версия-fpm.sock;
но, к примеру, после того как у вас наберется 15-20 хостов и вы решите изменить версию PHP для всех - вам придется править все конфиги хостов, либо, в случае использования алиасов, поправить только в одном месте.

0
Vorobey - 4 Июнь, 2016 - 21:35
Изображение пользователя Vorobey.

Работает.
а как насчет расширений
мне нужен DOMDocument php-xml он уже установлен.
Как выглядит инсталяция для других версий?

p.s.
Если я при установке php5 согласился(погарячился) скопировать конфиг от php7 - как его сгенерировать по новой?

0
MacLeod - 4 Июнь, 2016 - 22:14
Изображение пользователя MacLeod.

Какие-то совсем детские вопросы пошли.

мне нужен DOMDocument php-xml он уже установлен
php-xml - это метапакет,

Выше неоднократно повторял, что имена пакетов с расширениями начинаются с 'php5.5-', 'php7.0-' и т.д.
В вашем случае:
sudo apt-get install php5.5-xml

Если я при установке php5 согласился(погарячился) скопировать конфиг от php7 - как его сгенерировать по новой?
sudo apt-get purge php5.5.*
sudo apt-get install php5.5-fpm php5.5-xml php5.5-mbstring

0
Vorobey - 4 Июнь, 2016 - 23:03
Изображение пользователя Vorobey.

В какой файл писать конфигурацию .htaccess ?

0
MacLeod - 5 Июнь, 2016 - 00:39
Изображение пользователя MacLeod.

В Nginx нет никаких .htaccess файлов. На обработку и перенаправление запросов могут влиять, к примеру, параметры location/rewrite (как в вашем примере).
Естественно, данные блоки размещаются в конфигах хостов, внутри server, например:

З.Ы. Очень настоятельно рекомендую почитать документацию по location - http://nginx.org/ru/docs/http/ngx_http_core_module.html#location, чтобы всегда понимать, как происходит обработка запросов. К тому же, полное понимание даст вам возможность делать гибкую настройку, раздачу статики (не прибегая к бэкэнду) и даже возможность использования нескольких бэкэндов в рамках одного хоста.
0
Vorobey - 4 Октябрь, 2016 - 23:09
Изображение пользователя Vorobey.

Можно ли не имея домена(только ip) настроить свой сайт для отображения в таком духе ?196.155.1xx.1xx/example.localКак это должно выглядеть в конфиге /etc/nginx/sites-available/example.local

0
MacLeod - 10 Октябрь, 2016 - 03:09
Изображение пользователя MacLeod.

Ну... Не делается так. Точнее, это не будет альтернативой хостам на различных доменах.
Объяснение тут простое.
Если бы речь шла об обработке единичного запроса - проблем никаких, комбинация location/root/rewrite или даже, если хотите, proxy_pass.
Но для приложения (например, набора php-скриптов) у вас не получится, как в случае домена, обойтись настройкой только фронтэнда.
К примеру, картинка или ссылка у вас в итоговом HTML отображается как "/blabla/image.png". Куда пойдет браузер? Конечно на "196.155.1xx.1xx/blabla/image.png", но никак не на "196.155.1xx.1xx/example.local/blabla/image.png".
Даже если у вас будет в скриптах что-то вроде
<?php
$image_path
= 'http://' . $_SERVER['HTTP_HOST'] . '/blabla/image.png';
?>

то все равно не прокатит.
Какой тут выход? Добавить конфигурационную переменную, например
<?php
//$host_url_suffix = ''; // оставить пустым, если функционал не требуется
$host_url_suffix = '/example.local'; // эти строки где-то в конфиге,
$host_url = 'http://' . $_SERVER['HTTP_HOST'] . $host_url_suffix; // в одном экземпляре

$image_path = $host_url . '/blabla/image.png'; // такая обработка на всех страницах
?>

и так касаемо всех картинок и ссылок. То есть, имеет место добавление сего функционала в бэкэнд.
Собственно, в этом случае вы можете разместить скрипты уже в подкаталогах корня одного виртуального хоста и не мучить nginx.

И все же, я советую использовать DNS. Получите бесплатные домены 2-3 уровня и направляйте их на один IP с nginx, неважно, где они находятся.

0
masterlan - 19 Декабрь, 2016 - 15:18
Изображение пользователя masterlan.

Немного предистории.
Сайт был поднят на ubuntu.16.04.1.server.amd64+apache2+php5.6+mysql
По рекомендации разработчиков сайта, спустя месяц после его запуска, была выполнена замена apache2 на nginx.1.10.0+php5.6-fpm.
Также была установлена связка memcached+php-memcache.
После некоторого итеративного процесса "переноса" содержимого htaccess-файла в конфигурационный файл nginx-a удалось почти полностью вернуть функциональность сайта в исходное(апачевское) состояние.
Осталось только то самое "почти", а именно - мне никак не удаётся заставить nginx выполнить php-скрипт генерации sitemap.xml
Этот php-скрипт (sitemap.php) лежит в корне сайта и, насколько я смог понять его текст, занимается тем, что проверяет наличие файла sitemap.xml и время его модификации. В случае отсутствия или "старости" файла sitemap.xml он вызывает php-скрипт генерации файла sitemap.xml
и по завершении отдаёт его содержимое.
Все мои попытки запросить в браузере этот файл(sitemap.xml) закачиваются в либо 403-им кодом ответа от сервера, либо получением самого текста php-скрипта (sitemap.php), т.е. мне просто отдают php-файл вместо его запуска на сервере.

Вот текущее состояние конфигурационного файла nginx-a (имя сайта изменил дабы не быть уличённым в рекламе)

и фрагмент htaccess-файла, который я пытаюсь конвертировать

Прошу совета у экспертного сообщества, что и где "подкрутить-поменять"?

0
Гость - 20 Декабрь, 2016 - 02:16

Зачем заставлять nginx выполнять скрипт.
Я так понимаю index.php должен подключать sitemap.php и уже он анализирует, генерировать ему карту или нет. Если вы хотите напрямую example.com/sitemap.php то наверное так
index index.php sitemap.php

Но лучше тогда по крону+баш и пусть себе генерирует.

Забейте вы на эту карту сайта - утопия и лишняя нагрузка.
Поисковики на нее плевать хотели и ходят как им вздумается.
А поситителей это не добавит.

ps ждем более компетентного ответа)

0
masterlan - 20 Декабрь, 2016 - 15:46
Изображение пользователя masterlan.

Вы правы относительно крона.
Разработчики сайта именно так и поступили.
Сейчас по ночам генерируется актуальная копия sitemap.xml
А вот касательно реакции поисковиков(их ботов) на наличие и актуальность файла sitemap.xml, то тут существуют и отличные от вашего мнения.
Однако мой вопрос не совсем про sitemap.xml как таковой(он лишь конкретный повод), а про должное конфигурирование nginx-a.
Надеюсь таки довести его до ума с помощью сообщества.

0
MacLeod - 20 Декабрь, 2016 - 19:25
Изображение пользователя MacLeod.

Осталось только то самое "почти", а именно - мне никак не удаётся заставить nginx выполнить php-скрипт генерации sitemap.xml
Этот php-скрипт (sitemap.php) лежит в корне сайта и, насколько я смог понять его текст, занимается тем, что проверяет наличие файла sitemap.xml и время его модификации. В случае отсутствия или "старости" файла sitemap.xml он вызывает php-скрипт генерации файла sitemap.xml
и по завершении отдаёт его содержимое.

Nginx не выполняет php-скрпиты, он передает запрос бэкэнду (php-fpm), и, когда тот возвращает результат, отдает его клиенту. Это важно понимать, как и каждую директиву в конфиге. Метод "интуитивного тыка" - мало пригоден.
Также предположу, что sitemap.php сразу выплевывает текст XML-ки, как если бы читался .xml файл.

Все мои попытки запросить в браузере этот файл(sitemap.xml) закачиваются в либо 403-им кодом ответа от сервера, либо получением самого текста php-скрипта (sitemap.php), т.е. мне просто отдают php-файл вместо его запуска на сервере.

Если вы видели исходник скрипта, то, скорее всего, пытались сделать как-то так:
    location / {
        if (!-e $request_filename){
            rewrite ^/sitemap.xml$ /sitemap.php$1 break;
        }
    }

Хотя, если почитать http://nginx.org/ru/docs/http/ngx_http_rewrite_module.html#rewrite, там есть описание флагов:
last
завершает обработку текущего набора директив модуля ngx_http_rewrite_module, после чего ищется новый location, соответствующий изменённому URI;

Заменяете break на last и будет вам щасье. Хотя...

З.Ы. Конфиг у вас в ужасном состоянии. Зачем дублируете fastcgi*?
http://nginx.org/ru/docs/http/ngx_http_fastcgi_module.html#fastcgi_param
Обратите внимание, "Контекст: http, server, location". Т.е. вы можете определить их в контексте сервера (виртуального хоста) или как я показывал выше для отдельного типа файлов и иметь прозрачную структуру, в которой просто ориентироваться и просто изменять, вместо набора дублей.

0
masterlan - 20 Декабрь, 2016 - 22:20
Изображение пользователя masterlan.

То, что "Nginx не выполняет php-скрпиты, он передает запрос бэкэнду (php-fpm), и, когда тот возвращает результат, отдает его клиенту." я знаю. Моя фраза "заставить nginx выполнить php-скрипт" безусловно страдает смысловой неточностью.
Для однозначного "прочтения" тог, что делает скрипт sitemap.php привожу его полный текст ...

Попытка "тупо" вставить предложенный вами фрагмент в конфиг nginx-a приводит к:
nginx -t
nginx: [emerg] duplicate location "/" in /etc/nginx/sites-enabled/cms:192
nginx: configuration file /etc/nginx/nginx.conf test failed

Помещение контекста
if (!-e $request_filename){
rewrite ^/sitemap.xml$ /sitemap.php$1 break;
}
внутрь уже имеющегося в конфиге location "/" приводит к тому, что браузер по запросу https://cms.mydom.com/sitemap.xml получает(загружает) файл с именем sitemap.xml содержимым которого есть ни что иное, как выше опубликованный текст скрипта sitemap.php
Замена break на last имеет те же последствия.
Естественно эти попытки делались при заремлином блоке "location ~ ^/(sitemap.xml) {...}" из первоначально здесь опубликованного конфига.

А так хочется обещанного счастья :)
Готов пробовать любые ваши предложения/рекомендации.

P.S. Мой конфиг ужасен просто потому, что я не волшебник, я только учусь.

0
MacLeod - 21 Декабрь, 2016 - 14:30
Изображение пользователя MacLeod.

Ну, тогда стоит последовательно исключать варианты и найти причину.
1. Я написал независимый пример решения, а у вас в location / уже есть рерайт, который... Может поясните, что он делает?
2. sitemap.php действительно, в случае благоприятного исхода, отдает заголовок контент типа text/xml и содержимое. Стоит удостовериться, что при прямом обращении к нему там все выполняется ожидаемо.
3. Условие if (!-e $request_filename) проверяет, что запрашиваемый файл не существует (в данном случае работает аналогично апачевским RewriteCond %{REQUEST_FILENAME} !-f и RewriteCond %{REQUEST_FILENAME} !-d). Соответственно, если у вас существует sitemap.xml - условие выполняться не будет.
4. Сделайте самый минимальный вариант, который точно заработает, а потом уже постепенно добавляйте проверки и т.д., например:
    location /sitemap.xml {
        rewrite ^/sitemap.xml$ /sitemap.php$1 last;
    }

0
masterlan - 21 Декабрь, 2016 - 18:42
Изображение пользователя masterlan.

1. Мой вариант рерайта в "location /" - это попытка трансформации htaccess-ой конструкции
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php [L,QSA]

2. Убрал все упоминания про "sitemap" из конфига и запросил в браузере https://cms.mydom.com/sitemap.php
В ответ браузер показал мне текст самого файла sitemap.php

3. Файл с именем sitemap.xml - не существует.
Есть в каталоге /content/export/ файл с другим именем (его по ночам робот генерит и именно его должен был бы отдать, будучи исполненным, sitemap.php)

4. Удалил из конфига ВСЕ location и добавил ваш вариант.
Браузер закачал(не показывая его) мне файл sitemap.txt содержимое которого было тело скрипта sitemap.php.
И это естественно, ведь удалил все упоминания про fastcgi-сотоварищи.
Заменил ваш вариант на свой
location ~ ^/(sitemap.xml) {
fastcgi_index sitemap.php;
fastcgi_param SCRIPT_FILENAME $document_root/sitemap.php;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_pass unix:/var/run/php/php5.6-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_intercept_errors on;
include fastcgi_params;
}
Браузер показал мне тело скрипта sitemap.php
И вот этого я пока объяснить не могу.

Буду признателен за комментарии и новые идеи(подсказки).

0
MacLeod - 22 Декабрь, 2016 - 03:52
Изображение пользователя MacLeod.

1. Рерайт в таком случае вообще не нужен. Поясняю:
RewriteCond %{REQUEST_FILENAME} !-f # если запрос - не существующий файл
RewriteCond %{REQUEST_FILENAME} !-d # и не существующий каталог, то
RewriteRule ^(.*)$ /index.php [L,QSA] # как бы он ни выглядел, изменить его на /index.php, при этом является ссылкой с дописыванием строки запроса.
Подробнее тут - http://httpd.apache.org/docs/current/mod/mod_rewrite.html.

try_files $uri $uri/ /index.php?$args; # пробуем оригинальный запрашиваемый URI, потом его же как каталог (черта дроби в конце), и если все, кроме последнего отсутствуют - делаем внутреннее перенаправление на последний.
Подробнее тут - http://nginx.org/ru/docs/http/ngx_http_core_module.html#try_files.
Про зло - https://www.nginx.com/resources/wiki/start/topics/depth/ifisevil/.

2. Это очень плохо, значит у вас не работает общее направление запросов к php-файлам на бэкэнд (криво описан location ~ \.php$, либо на него пагубно влияют другие части конфига).

3. Ок.

4. Возьмите любой конфиг из моей статьи выше и допишите туда "мой вариант" (location /sitemap.xml).
Еще раз повторюсь: эта конструкция заменяет запрос с /sitemap.xml на /sitemap.php и... флаг last означает, что Nginx ищет другой location, который будет соответствовать этому новому запросу. Найдет правильно описанный location ~ \.php$ - отдаст его php-fpm'у, если нет - отдаст текст скрипта.
Ваш же вариант даже не знаю, как комментировать. Разве что "дорогой nginx! пойди туда, не знаю куда, принеси то, не знаю что". Ну и то, что для конкретного реквеста не нужна регулярка.

+1
Vorobey - 18 Январь, 2018 - 14:06
Изображение пользователя Vorobey.

Как правильно поставить несколько "одинаковых" условий?
Делаю редирект в зависимости от ip
        if ($remote_addr != 22.22.22.22) {
         return 301 https://$server_name$request_uri;
        }
Оно работает.
Нужно несколько IP адресов.
Люди пишут про хак с условиями - мне кажется должен быть другой выход.
----
p.s.
Сам спросил, сам отвечу )
geo $geo {
default 0;
22.22.22.22 1;
33.33.33.33 2;
}

server {
if ($geo = 0) {
  return 301 https://$server_name$request_uri;
}
}
Все равно выглядит паршиво...

Отправить комментарий

CAPTCHA на основе изображений
Введите цифры