50090 (597472), страница 3
Текст из файла (страница 3)
echo “Список month2:
” ;
foreach ($_REQUEST[’month2’] as $key=>$value)
echo “$key = $value
”;
?>
Прием с автомассивом в поле для списка с множественным выбором выглядит довольно элегантно. Однако не стоит думать, что он применим только к этому элементу формы: автомассивы можно применять и в любых других полях. Вот пример, создающий два переключателя (кнопки со значениями вкл/выкл), один элемент ввода строки и одно текстовое (многострочное) поле, причем все данные после запуска сценария, обрабатывающего эту форму, будут представлены в виде одного-единственного автомассива:
Листинг txt.html. Применение автомассивов
Применение автомассивов
Однострочный текст”>
Многострочный текст
а1ue = “Нажмите кнопку, чтобы запустить сценарий! «>
В окне браузера форма выглядит следующим образом:
Листинг hello3.php. Сценарий обработки автомассивов
echo “г>Список month3:
” ;
foreach ($_REQUEST[’Arr’] as $key=>$value)
echo “$key = $value
”;
?>
Видно, что РНР совершенно нет никакого дела до того, в каких элементах формы мы используем автомассивы — он в любом случае обрабатывает все одинаково. И это, пожалуй, не только правильно, но и удобно.
2.6. Обработка массивов
Рассмотрены почти все возможности РНР по автоматической трансляции данных формы. Напоследок взглянем на еще одно полезное свойство РНР. Пусть имеется такая форма:
Листинг txt1.html. Форма для примера «Обработка массивов»
Обработка массивов
Имя:
Адрес:
Город:
Новомocковск
Kиев
а1ue = “Нажмите кнопку, чтобы запустить сценарий! «>
В окне браузера форма выглядит следующим образом:
После передачи подобных данных сценарию на РНР в нем будет инициализирован ассоциативный массив $Data с ключами name, address и city. То есть, имена полям формы можно давать не только простые, но и представленные в виде одномерных ассоциативных массивов.
В сценарии к отдельным элементам формы можно обратиться при помощи указания ключа массива: например, $_REQUEST ['Data'] ['city'] обозначает значение той радиокнопки, которая была выбрана пользователем, а $_REQUEST ['Data'] ['name'] — введенное имя.
Предупреждение. В сценарии обязательно нужно заключать ключи в кавычки или апострофы. В противном случае интерпретатором будет выведено предупреждение. В то же время, в параметрах name полей формы, наоборот, нужно их избегать — так устроен РНР.
Напишем сценарий.
Листинг hello4.php. Сценарий для обработки массива
echo “г>Список month4
” ;
foreach ($_REQUEST[’Data’] as $key=>$value)
echo “$key = $value
”;
?>
2.7. Особенности обработки независимых переключателей
Рассмотрим вопрос, который находит частое практическое применение в Web-программировании. Независимый переключатель (checkbox или более коротко — флажок) имеет одну довольно неприятную особенность, которая иногда может помешать Web-программисту. Если перед отправкой формы пользователь установил независимый переключатель в выбранное состояние, то сценарию в числе других параметров приходит пара имя_флажка=значение. В то же время, если флажок не был установлен пользователем, указанная пара не посылается.
Для упрощения обработки, хотелось бы, чтобы в невыбранном состоянии флажок также присылал данные, но только значение было равно какой-нибудь специальной величине — например, нулю или пустой строке.
Добиться этого эффекта в РНР довольно несложно. Достаточно воспользоваться одноименным скрытым полем (hidden) со значением, равным, например, нулю, поместив его перед нужным флажком.
Листинг checkbox.php. Особенности обработки независимых переключателей
if (@$_REQUEST[’doGo’] )
{
foreach (@$_REQUEST [’known’] as $k=>$v)
{
if($v) echo «Вы знаете язык $k!
»;
else echo «Вы не знаете языка $k.
»;
}
}
?>
Какие языки программирования вы знаете?<br>
PHP
Perl
Инструкция foreach предназначена для перебора всех элементов массива, указанного в ее первом аргументе.
Теперь в случае, если пользователь не выберет никакой из флажков, браузер отправит сценарию пару known [язык] = 0, сгенерированную соответствующим скрытым полем, и в массиве $_request [' known'] создастся соответствующий элемент:
Если пользователь выберет флажок, эта пара также будет послана, но сразу же после нее последует пара known [язык] =1, которая «перекроет» предыдущее значение:
Если бы не были включены скрытые поля в форму, сценарий печатал бы только сообщения о тех языках, которые «знает пользователь», пропуская языки, ему «неизвестные». В рассмотренном случае сценарий реагирует и на сброшенные флажки.
Такой способ немного увеличивает объем данных, передаваемых методом post, за счет тех самых пар, которые генерируются скрытыми полями. Впрочем, в реальной жизни это «увеличение» практически незаметно (особенно для POST-форм).
2.8. Диагностика создаваемых массивов
Напомним, какие массивы создает РНР, когда обрабатывает данные, пришедшие из формы:
● $_GET — содержит GET-параметры, пришедшие скрипту через переменную окружения QUERY_STRING. Например, $_GET [' login'];
● $_post — данные формы, пришедшие методом post;
● $_cookie — все cookies, которые прислал браузер;
● $_REQUEST — объединение трех перечисленных выше массивов.
Именно переменную $_REQUEST рекомендуется использовать в скриптах, потому что таким образом мы не «привязываемся» жестко к типу принимаемых данных (get или post);
● $_server — содержит переменные окружения, переданные сервером (отсюда и название).
Может показаться, что это много. Чтобы не запутаться в переменных, рассмотрим полезный прием, помогающий при отладке сценариев: можно вывести все переменные в браузер.
Листинг dump.php. Вывод всех переменных в браузер
<pre>
GLOBALS)?>
pre>
Задача данного сценария — распечатать в браузер все глобальные переменные программы (включая описанные выше массивы) в читабельном представлении. Глобальные переменные доступны через используемый массив $GLOBALS. Встроенная функция print_r() делает все остальное.
Страница, генерируемая данным сценарием, весьма интересна. Рекомендуем поэкспериментировать с ней, передавая программе различные GET-данные (включая многомерные массивы) и подставляя ее в атрибут action различных HTML-форм.
3. КАКОЙ РЕЖИМ ВЫБРАТЬ: register_globals=off & on ?
В рассмотренных примерах каждый раз при обращении к переменным, полученным из полей формы, писали:
$_REQUEST[' … ']
Это делать необходимо из-за того, что все данные из полей формы PHP помещает в глобальный массив $_REQUEST.
В ранних версиях РНР (вплоть до РНР 4.1) существовал способ, позволяющий работать с полями формы значительно проще. По умолчанию РНР не помещал данные в $_REQUEST, а создавал обыкновенные глобальные переменные для каждого из полей формы. Например, можно было написать такой сценарий:
php
echo”Hello, $name!”;
?>
Запустив его с нужным параметром, например: http://localhost/hello.php?name=Виктор Сергеевич, можно увидеть корректную страницу приветствия: РНР создал глобальную переменную $name, значение которой и напечатано:
Такой режим работы называется register_globals и поддерживается в РНР по сей день. При этом в файле php.ini этот параметр находится во включенном состоянии:
Однако, начиная с PHP 4.2.0, register_globals по умолчанию выключен в файле php.ini:
Разработчики РНР поступили так по соображениям безопасности: часто скрипты, написанные в расчете на включенный register_globals, обнаруживали проблемы с защитой.
Внимание |
Начиная с PHP 4.2.0, значение директивы register_globals по умолчанию установлено в off (отключено, раньше было on - включено). Положение register_globals в off делает предопределенные переменные доступными в глобальной области видимости. Например, чтобы получить: ● $DOCUMENT_ROOT, вам необходимо будет использовать $_SERVER['DOCUMENT_ROOT'] вместо $DOCUMENT_ROOT; ● $_GET['id'] из URL http://www.example.com/test.php?id=3 вместо $id; ● $_ENV['HOME'] вместо $HOME. Использование доступных зарезервированных предопределенных переменных PHP, таких как суперглобальные массивы, является предпочтительным. |
Предупреждение! |
В PHP 4.2.0 и позднее, набор по умолчанию предопределённых переменных, доступных в глобальной области видимости, изменён. Отдельные переменные ввода и сервера по умолчанию больше не размещаются непосредственно в глобальной области видимости; они размещаются в суперглобальных массивах. Вы можете форсировать старое поведение, установив register_globals в 'On' в вашем файле php.ini. |
Суперглобальные переменные PHP $GLOBALS Содержит ссылку на каждую переменную, доступную в данный момент в глобальной области видимости скрипта. Ключами этого массива являются имена глобальных переменных. $GLOBALS существует, начиная с PHP 3. $_SERVER Переменные, установленные web-сервером либо напрямую связанные с окружением выполнения текущего скрипта. Аналог старого массива $HTTP_SERVER_VARS (который по-прежнему доступен, но не рекомендуется). $_GET Переменные, передаваемые скрипту через HTTP GET. Аналог старого массива $HTTP_GET_VARS (который по-прежнему доступен, но не рекомендуется). $_POST Переменные, передаваемые скрипту через HTTP POST. Аналог старого массива $HTTP_POST_VARS (который по-прежнему доступен, но не рекомендуется). $_COOKIE Переменные, передаваемые скрипту через HTTP cookies. Аналог старого массива $HTTP_COOKIE_VARS (который по-прежнему доступен, но не рекомендуется). $_FILES Переменные, передаваемые скрипту через HTTP post-загрузку файлов. Аналог старого массива $HTTP_POST_FILES (который по-прежнему доступен, но не рекомендуется). Для дополнительной информации смотрите Загрузка методом POST. $_ENV Переменные, передаваемые скрипту через окружение. Аналог старого массива $HTTP_ENV_VARS (который по-прежнему доступен, но не рекомендуется). $_REQUEST Переменные, передаваемые скрипту через механизмы ввода GET, POST и COOKIE, и которым, следовательно, нельзя доверять. Наличие и порядок включения переменных в этот массив определяется в соответствии с директивой конфигурации PHP variables_order. Этот массив не имеет прямых аналогов в версиях PHP до 4.1.0 |
Рекомендуется писать скрипты с расчетом на выключенный register_globals.
Сценарий, корректно работающий при выключенном register_globals, будет работать и при включенном режиме. Но не наоборот.
Для повышения безопасности работы нужно сконфигурировать PHP с опцией register_globals = off. Отключив возможность внедрения отправленных пользователем переменных в PHP-код, можно уменьшить количество заражённых переменных, которые потенциальный взломщик может попытаться направить вам. Для подделки отправляемой информации понадобится дополнительное время, а ваши внутренние переменные будут эффективно изолированы от отправляемых пользователем данных.