Nginx установить переменную php

Раскрываем возможности map в nginx

map — мощная директива, которая может сделать ваши конфиги простыми и понятными.
Возможно, это самая недооцененная директива, из за того, что не все знают всех её возможностей.
Она в компактной форме помогает обрабатывать переменные, GET параметры, заголовки, куки и наборы бекендов (upstream).
Попробую раскрыть её возможности хабрапользователям.

Для простоты, в примерах директива map будет соседствовать с директивами из location.
В реальном конфиге место map — в блоке http.

Это директива, которая устанавливает значение одной переменной (правой), в зависимости от другой (левой).
Выглядит вот так:

В левой части можно использовать регулярные выражения, включая именованные выделения.
В правой части могут быть строки, переменные и regexp выделения из левой части.
Директива map описывается в блоке http.
Полное описание можно найти в документации.

Замена if на map

if в nginx реализован по своему, достаточно неочевидно.
Вкратце это описано на специальной странице.
Насколько я понимаю, if в nginx — это из разряда, когда мир крутится вокруг вас, а не наоборот.
На каждый if в location, nginx генерирует у себя два конфига, с if=true и с if=false.
Плюс, некоторые директивы ведут себя странно, или вообще не работают рядом с if в одном location.
Поэтому при работе с if всегда есть шанс совсем не того поведения, которое вы ожидали.
Для гарантированного поведения, if лучше заменять на map.

Читайте также:  Integer from double java

Рассмотрим примеры замен, от простого к сложному.

Установить переменной одно значение
  • не важно, сколько ещё if, или других директив окажется в location, эта переменная получит свое значение;
  • для nginx это менее затратно, так как значение переменной будет вычислено только в момент использования;
Установить переменной одно из нескольких значений
if ($arg_one = "one") < set $var_two "two"; >if ($arg_one = "three")

Уже виден выигрыш по компактности и читаемости.
Если нужно будет ещё редактировать условия, вам нужно поправить строчку в map.

Вложенные if (зависимость от нескольких условий)

Я находил в списках рассылки nginx вопросы насчет вложенных if, когда нужно учитывать несколько условий.
Вложенные if делать нельзя, можно сделать костыль из нескольких if.
А можно написать один map.
Возможно, вы не знаете, но в исходной части (где первая переменная) можно указывать не одну переменную, а целый текст, содержащий несколько переменных, в кавычках.
Например, вам нужно блокировать пользователей с user-agent «HackYou», долбящихся «POST» запросом по адресу «/admin/some/url».

Это, в принцципе, можно сделать с помощью if:

if ($http_user_agent ~ "HackYou") < set $block "A"; >if ($method = "POST") < set $block "$B"; > if ($uri = "/admin/some/url") < set $block "$C"; > if ($block = "ABC")
map "$http_user_agent:$method:$uri" $block < "HackYou:POST:/admin/some/url" "1"; >if ($block)

Двоеточие — просто для удобства восприятия.
В этом примере возникает «точка невозврата» в сторону map.
Если количество условий растет (например, несколько user-agent), реализовать их набором if уже не получится, или это будет слишком громоздкая конструкция.

http заголовки

Если вам нужно добавлять заголовки в зависимости от каких-то условий, с if это может стать проблемой.

Например, такая конструкция:

if ($arg_a = "1") < add_header X-one "one"; >add_header X-two "two"; 

Будет отдавать только один заголовок (X-one, если arg_a = true, и X-two, если false).
Это недостаток add_header и разработчики не будут это исправлять.
А если у вас несколько if с заголовками, может и не получиться добавить несколько разных заголовков одновременно.

Но тут на помощь приходит map:

map $arg_a $header_one < "1" "one"; >add_header X-one $header_one; add_header X-two "two"; 

Несколько заголовков — несколько map.
Если переменная будет пустой, nginx просто не создаст заголовок.
Вообще, в случае с if может помочь модуль headers_more, он лишен недостатка add_header насчет if.
Модуль headers_more интересен сам по себе, с его помощью можно гибко управлять любыми заголовками, как ответа, так и запроса (на бекенд).
В паре с директивой map этот модуль может реализовывать многие хотелки, включая генерацию нескольких кук.

Выбор upstream

В директивах типа proxy_pass (fastcgi_pass и прочие *_pass), где можно указывать upstream в качестве бекенда, можно использовать переменные.
Т.е. работает такое определение:

proxy_pass http://$php_backend; 

В этом случае имя сервера ищется среди описанных групп серверов и если не найдено, то определяется с помощью resolver’а.

В паре с map, это дает нам поле для фантазии.
Вот грубый пример — допустим, нам нужно такое:
Есть кука userid.
Если в её значении первое число от 0 до 4, то посылать запросы на upstream old_php_backend.
Если с 5 до 9 — на new_php_backend.
Если куки нет, или она пустая, или первый символ — не число, то на default_php_backend.

Обычно делается с помощью if, rewrite и нескольких location:

location /some/url/ < if ($cookie_userid ~ "~^4") < rewrite ^(.+)$ /old/$1 last; >if ($cookie_userid ~ "~^6") < rewrite ^(.+)$ /new/$1 last; >proxy_pass http://default_php_backend; > location /old/some/url/ < internal; rewrite ^/old/(.+)$ $1 break; proxy_pass http://old_php_backend; >location /new/some/url/ < internal; rewrite ^/new/(.+)$ $1 break; proxy_pass http://new_php_backend; >
map $cookie_userid $php_backend < "~^3" "old_php_backend"; "~^8" "new_php_backend"; default "default_php_backend"; >location /some/url/ < proxy_pass http://$php_backend; >

Это действительно работает, применяется на нагруженном сервисе, и с этим не наблюдается проблем.
Главное — не забывать про default, чтобы всегда было, куда направить запрос.
Этот прием можно применять и с geo/split_clients.
Например, в split_clients выделить 1% запросов и направить их на отдельный бекенд для тестов.

Переменную из map можно использовать в другой map

map $arg_a $var_a < "0" "1"; >map $var_a $var_b < "1" "2"; >map $var_b $var_c

Когда вы обратитесь к $var_c , последовательно сработает три директивы map.
При GET параметре a=0, $var_c будет содержать «3».
nginx прожевывает цепочку из 12 map’ов, дальше я не пробовал.
Можете попробовать, ради интереса, узнать максимальную длинну цепочки.
Обычно мне хватает пары map’ов, которые зависят друг от друга.
Мне это бывает полезно для формирования сложных заголовков и кук средствами nginx (когда надо добавить текст в заголовок, на бекенд отправить один заголовок, а клиенту — другой).
Это может пригодиться, как развитие примера с вложенными if.
В одном map вычисляем $var_a , в другом map вычисляем $var_b , а третий map зависит от «$var_a:var_b «.

Так же map работает с перменными из geo и split_clients.
В geo и split_clients результирующей переменной можно присвоить только простую строку, нельзя использовать переменные или регулярные выражения.
Если вам, в зависимости от ip, нужно что-то посложнее простой строки, geo+map помогут вам.
А связка split_clients+map поможет вам, например, гибко изменить заголовки для 1% пользователей.

split_clients "$XXX" $test_percent < 1% "1"; * "0"; >map "$test_percent:$http_user_agent" $test_mobile_users < "~*^1:.*iphone.*" "X-tester: iphone"; >more_set_input_headers $test_mobile_users; 

Если ip пользователя попал в тестовый 1% пользователей, и в его user-agent есть слово iphone, то вместе с запросом на бекенд отправляется заголовок «X-tester: iphone».
Разработчикам остается отреагировать на этот заголовок и отдавать тестовую версию сайта для айфонов.

Заключение

Как видите, map помогает делать сложную логику малым количеством команд.
Она позволяет избавиться от if в большинстве случаев.
А совместно с другими директивами, творит хитрые преобразования в несколько строк.
Я надеюсь, эти возможности помогут вам, с одной стороны, сократить конфиги, а с другой — реализовать хитрые хотелки.

Источник

How to pass custom parameters to PHP from Nginx?

I have tried changing the values of some parameters using fastcgi_param but was unsuccessful:

fastcgi_param PATH_INFO "/var/tmp"; 

I checked all the predefined arrays I could find:

echo '
'; echo "\n".'$GLOBALS'."\n"; var_dump($GLOBALS); echo "\n".'$_SERVER'."\n"; var_dump($_SERVER); echo "\n".'$_GET'."\n"; var_dump($_GET); echo "\n".'$_POST'."\n"; var_dump($_POST); echo "\n".'$_FILES'."\n"; var_dump($_FILES); echo "\n".'$_REQUEST'."\n"; var_dump($_REQUEST); echo "\n".'$_SESSION'."\n"; var_dump($_SESSION); echo "\n".'$_ENV'."\n"; var_dump($_ENV); echo "\n".'$_COOKIE'."\n"; var_dump($_COOKIE); echo "\n".'$php_errormsg'."\n"; var_dump($php_errormsg); echo "\n".'$HTTP_RAW_POST_DATA'."\n"; var_dump($HTTP_RAW_POST_DATA); echo "\n".'$http_response_header'."\n"; var_dump($http_response_header); echo "\n".'$argc'."\n"; var_dump($argc); echo "\n".'$argv'."\n"; var_dump($argv); echo '

';

The only one to show PATH_INFO was $_SERVER :

var_dump($_SERVER); // ["PATH_INFO"]=> string(0) "" 

But the value I set in nginx isn’t taken into account.

Q1: Do I need to configure anything at nginx/php level for the fastcgi_param directive to take effect?

Q2: Is the fastcgi_param directive limited to a predefined list of parameters (e.g. I can set PATH_INFO but not custom variables of my own such as FOO )?

Q3: If yes to Q2: is there a way to pass custom parameters to PHP from Nginx?

Источник

Русские Блоги

Apache / Nginx установлен на PHP, добавьте переменные среды сервера $ _Server

нужно

В PHP Development, для того, чтобы разделить онлайн-среду производства, это местная среда развития. Если мы сможем отличить его, судив $ _server ['runtime_enviroment'] - «Dev» или «Pro» » К сожалению, нет элемента RunTime_enviRoment в массиве $ _server. 

Во-первых, установлен NGINX FASTCGI_PARAM

В файле конфигурации NGINX вы можете установить в общем профиле Nginx, вы также можете установить в отдельной среде конфигурации веб-сайта, например www.tomener.com.conf

Добавьте соответствующую информацию о конфигурации для настройки сегмента сервера сервера среды:

Вот только добавляет значение значения fastcgi_param runtime_enviRoment ‘Pro’, больше вы можете добавить в спину

Затем перезапустите и перезапустите Nginx

Во-вторых, установить PHP Master Configuration File PHP-FPM.conf

Этот параметр должен быть помещен в основной файл конфигурации PHP-FPM.conf, который нельзя поместить в файл подконфионального конфигурации, установленного командой include, в противном случае будет сообщена ошибка: «Массив не прилипал в глобальном разделе»

Мой местоположение PHP-FPM.conf находится в /usr/local/php/etc/php-fpm.conf

Добавьте непосредственно в файл конфигурации:

env[RUNTIME_ENVIROMENT] = 'PRO' 

Перезапустите PHP-FPM после добавления

После добавления переменного значения $ _Server вышеупомянутым двумя способами, мы можем получить соответствующее значение переменной через $ _Server в файле PHP.

Тем не менее, говорится, что информация о конфигурации устанавливается Ninx’s FastCGI_PARAM. Когда Nginx и PHP взаимодействует, принесет большое количество передачи данных.

Переменные среды Apache Set

Вариабельное значение имена переменной stenv
 ServerAdmin [email protected] DocumentRoot "e:\wwwroot\demo" ServerName my.demo.com ErrorLog "logs/my.demo.com-error.log" CustomLog "logs/my.demo.com-access.log" common SetEnv RUNTIME_ENVIROMENT DEV Options Indexes FollowSymLinks AllowOverride All Require all granted 
http://man.chinaunix.net/newsoft/ApacheManual/mod/mod_env.html#setenv

Источник

Русские Блоги

Установите переменную среды сервера (Apache/Nginx) для PHP

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

Установите текущую переменную среды DEV

SetEnv RUNTIME_ENVIROMENT DEV

Пароль учетной записи базы данных

SetEnv MYSQL_USERNAME root SetEnv MYSQL_PASSWORD root

Формат файла конфигурации

 ServerAdmin [email protected].com DocumentRoot "/var/www/" ServerName localhost SetEnv RUNTIME_ENVIROMENT DEV SetEnv MYSQL_USERNAME root SetEnv MYSQL_PASSWORD root ErrorLog "logs/error.log" CustomLog "logs/access.log" common 

Установить переменные среды Nginx

инструкция

Установите текущую переменную среды DEV

fastcgi_param RUNTIME_ENVIROMENT 'DEV'

Пароль учетной записи базы данных

fastcgi_param MYSQL_USERNAME 'root' fastcgi_param MYSQL_PASSWORD 'root'

Формат файла конфигурации

Настройка в файле FASTCGI_PARAMS

fastcgi_param RUNTIME_ENVIROMENT 'DEV'; fastcgi_param MYSQL_USERNAME 'root'; fastcgi_param MYSQL_PASSWORD 'root';
server < listen 80; root /var/www; index index.php; server_name localhost; location / < index index.php; > location ~ .*\.(php|php5)?$ < fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; include fastcgi_params; > >

Установить переменные среды для сценария PHP

Временно установить для текущего пользователя

Временные настройки должны быть выполнены только

Настройка для текущего пользователя

существует ~/.bashrc (Разные системы разные)

Установите для всех пользователей (за исключением Root)

Создайте файл /etc/profile.d/test.sh , Напишите

Установить для всех пользователей (включая root)

существует /etc/environment Напишите

Обратите внимание, что эффективное время этого файла, когда пользователь входит в систему, поэтому для ROOT вам нужно перезагрузить машину

Установить в руководителе

Иногда скрипт PHP контролируется с руководителем, поэтому помните

Вызовите переменную среды сервера в PHP

В PHP есть два метода вызова:

$env = getenv('RUNTIME_ENVIROMENT');

Существует также супер -искренний -масштабный метод переменной:

$env = $_SERVER['RUNTIME_ENVIROMENT'];

Источник

Оцените статью