Информация, полученная с помощью phpinfof()
Configuration
Environment
PHP Variables
PHP License
Полученная таким образом информация позволит узнать возможности РНР и использовать язык наиболее оптимальным образом. Некоторые переменные могут быть изменены программными средствами. Большую помощь могут оказать другие переменные, информация о которых не выведена функцией phpinfo(), а также постоянные РНР. Информацию о переменных и постоянных можно получить в приложении А (Краткий справочник по функциям РНР).
Текст в рисунках
В РНР существует несколько функций, которые позволяют выводить текст поверх рисунка. Рассмотрим простой пример вывода текста с применением фонта TTF. Для этого вначале откроем рисунок, определим два цвета для текста и для фона, укажем размер шрифта, местоположение файла, содержащего фонт, размер шрифта — и программа готова. Скрипт поместим в файл image3.phtm.
Файл image3.phtm
<?php
Header ("Content-type: image/jpeg");
$im = imagecreate (800, 900);
$black = ImageColorAllocate ($im, 0, 0, 0) ;
$white = ImageColorAllocate ($im, 255, 255, 255);
ImageTTFText ($im, 60, 0, 600, 400, $white, "C:/win/fonts/arial.ttf", "Writing text..."); ImageJPEG ($im);
ImageDestroy ($im);
?>
По сравнению с теми примерами, которые мы рассматривали ранее, здесь имеется новая функция ImageTTFText(). Эта функция используется для рисования текста с помощью фонта TTF. Аргументы функции (по порядку их появления) таковы: указатель рисунка, размер шрифта, угол наклона (отсчитывается против часовой стрелки, указывается в градусах, нулевому значению соответствует положение стрелки на трех часах), начальная точка местоположения текста, цвет шрифта, полный путь к файлу, содержащему фонт, наконец, строка, которая будет выведена в виде текста. Возвращаемые этой функцией значения (массив), а также прочие аргументы, которые использовать Не обязательно, описаны в приложении в кратком справочнике по функциям.
Если мы запросим файл image3.phtm, то получим такой ответ (рис. 5.7).
Слегка изменив параметры функции Image TTFText(), увидим другой вариант текста (файл image3_l.phtm) (рис. 5.8).
В этом примере функция imageTTFText() выглядит так:
ImageTTFText ($im, 60, 165, 600, 400, $white, "С:/win/fonts/ times.ttf",
`"Writing text...");
Текст может быть написан и поверх рисунка (файл image4.phtm):
<?php
Header ("Content-type: image/jpeg");
$im = ImageCreateFromJPEG ("001.jpg");
$blаск = ImageColorAllocate ($im, 0, 0, 0);
$white = ImageColorAllocate ($im, 255, 255, 255);
ImageTTFText ($im, 60, 135, 600, 400, $Ыаск, "C:/win/fonts/ arial.ttf",
"Writing text...");
ImageJPEG ($im);
ImageDestroy ($im);
?>
В окне броузера мы увидим такую картинку (рис. 5.9).
Поскольку параметры выводимого шрифта представляются в виде числовых и строковых аргументов функции, их легко можно менять, например, в зависимости от сколь угодно интересных обстоятельств, скажем от времени суток. Такой вариант приведен в файле image4_l.phtm:
<?php
Header ("Content-type: image/jpeg");
$im = ImageCreateFromJPEG ("001.jpg");
$black = ImageColorAllocate ($im, 0, 0, 0) ;
$white = ImageColorAllocate ($im, 255, 255, 255);
$time = localtime();
$a = 450 - 30*$time [2] ;
ImageTTFText ($im, 60, $a, 600, 400, $black, "C:/win/fonts/ arial.ttf",
"Writing text...");
Image JPEG ($im) ;,
ImageDestroy ($im);
?>
Этот скрипт посылает броузеру рисунок с надписью. Которая располагается в направлении часовой стрелки в соответствии с локальным временем на сервере. Так, если локальное время сервера 23 часа, то мы получим такой рисунок (рис. 5.10).
Иные возможности
РНР предоставляет возможность создавать программы, исполняемые на сервере. Это не единственный язык, разработанный специально для того, чтобы создавать гибкие Интернет-приложения. Существуют другие языки, например, язык Perl, которые позволяют создавать программы, выполняемые на сервере. Стандартные языки сценариев, например, язык JavaScript, также предоставляют богатые возможности управления выводимым содержанием web-страниц на сервере перед отправкой клиенту. Особенно полезен он оказывается при использовании технологии ASP компании Microsoft. Модуль ASP удобно устанавливается на платформе Windows и сразу после установки без необходимости дополнительного конфигурирования системы готов к работе.
При использовании технологии ASP необходимо придерживаться таких правил. Файлы с программами на языке JavaScript (или Jscript или VBScript) должны иметь расширение .asp и располагаться в выполняемом каталоге сервера. Фрагмент скрипта (выполняемый текст программы) отделяется от HTML-текста файла ярлыком <%@ (открывающий) и %> (закрывающий), скрипт должен начинаться с указания используемого языка: Language—«JavaScript». Можно использовать конструкцию <script language=«JavaScript» RUNAT^«Server»>. В последнем случае атрибут RUNAT содержит значение, соответствующее тому, что скрипт предназначен для выполнения на сервере. Однако в настоящем пособии мы не будем останавливаться на вопросах создания ASP файлов.
ОСНОВНЫЕ ЭЛЕМЕНТЫ ЯЗЫКА
Базовые элементы
Типы
Переменные
Константы
Инструкции
Язык РНР основан на известных языках программирования, таких как С, Java, Perl. Синтаксис РНР во многом заимствован у этих языков.
Базовые элементы
Выделение фрагмента РНР-кода в тексте phtm-файла
Первое, на чем важно остановиться, — это способ перехода из обычного HTML-кода к командам, написанным на РНР. Как осуществляется переход от HTML-разметки и текста к фрагменту, содержащему код РНР? Для этого используются специальные обозначения. Существует несколько способов того, чтобы показать, что в данном фрагменте располагается код РНР.
Способ 1. Для выделения фрагмента РНР-кода используются обрамляющие знаки </ и ?>. Например:
<? Echo("Здесь содержится текст, который будет выведен в окне броузера \n"); ?>
Способ 2. Фрагмент РНР кода помещается между знаками <?php и ?>. Например:
<?php echo("Что такое здесь сидит? \п Это доктор или кто? \п"); ?>
Способ 3. Использование ярлыка <script> с указанием атрибута language, значение которого равно строке, содержащей название языка РНР: <script language="php">. Например:
<script language="php">
echo ("Чего бы мы ни написали в этом месте, этот текст будет видим в окне броузера."); </script>;
Способ 4. Использование ярлыков в стиле asp, т.е. знаков <% и %>. При этом необходимо соответствующим образом сконфигурировать файл php.ini. Пример:
<% есhо("Пишем текст"); %>
В качестве примера рассмотрим простой файл, в котором используются все указанные способы. Файл l.phtm:
<htral>
<head>
<title>Cпособы выделения PHP кода в тексте .phtm файла. </title>
<body>
<р align="center"
В этом файле мы рассмотрим примеры того, какими способами можно выделить PHP-код в тексте phtm-файла.
<р><В>Способ 1.</В> Угловые скобки со знаками вопросов. <? Echo("Здесь содержится текст, который будет выведен в окне броузера \n") ; ?>
<р><В>Способ 2.</В> Угловые скобки со знаками вопросов и словом php в открывающей скобке, <?php echo ("Что такое здесь сидит? \n Это доктор или кто? \n"); ?>
<р><В>Способ 3.</В> Ярлык <i>script</i>. <script language="php">
echo ("Чего бы мы ни написали в этом месте, этот текст будет видим в окне броузера . " ) ;
</scrip.t>;
<р><В>Способ 1.</В> Угловые скобки со знаками процентов, как при использовании asp.
<% echo("Пишем тексты"); %>
</body>
</html>
Сохраняем файл в основном каталоге сервера и загружаем в броузер. В результате видим что-то похожее на то, что изображено на рис. 6.1.
Типы
В РНР поддерживаются следующие типы:
- array — массивы;
- floating-point numbers — числа с плавающей точкой («doubles»);
- integer — целые числа;
- object — объекты;
- string — строки.
Как правило, тип не устанавливается разработчиком, вместо этого он определяется интерпретатором РНР во время выполнения программы и зависит от контекста, в котором используется та или иная переменная.
Если возникает необходимость указать тип переменной в явном виде или преобразовать переменную к заданному типу, то для этого можно использовать cast или функцию settype(). При этом следует иметь в виду, что в зависимости от условий различные типы ведут себя по-разному (см. преобразование типов).
Целые числа
Целое число может быть определено с использованием одного из следующих форматов инициализации:
- $а = 1234; # десятичное число;
- $а = -123; # отрицательное число;
- $а = 0123; # восьмиричное число (начинается с 0, равно десятичному 83);
- $а = 0x12; # шестнадцатиричное (равно десятичному 18).
Максимально допустимое значение зависит от платформы, но, как правило, максимальное значение может задаваться в диапазоне 32.
Числа с плавающей точкой
Числа с плавающей точкой («doubles») могут записываться в одном из следующих вариантов:
- $а = 1,234;
- $а = 1,2еЗ.
Максимальное значение числа с плавающей точкой также зависит от платформы, как правило, оно достигает значения ~1,8е308 при этом допустимая точность составляет 14 десятичных знаков (64 бит).
Предупреждение.
Следует отметить, что десятичные дроби, например, 0,1 или 0,7, не могут быть превращены в двоичное представление с абсолютной сохранностью точности. Так, например, floor((0,1+0,7)*10) как правило возвращает значение 7, а не предполагаемое значение 8, поскольку выражение в скобках оказывается равным примерно значению 7,9999999999.... Этот факт является следствием того, что невозможно точно представить в виде десятичной записи дробные выражения, например, такие как 1/3.
Строки
Строки могут быть заданы с использованием одного из двух видов кавычек. При использовании двойных кавычек переменные могут быть раскрыты. Возможно использование специальных наборов символов.
При использовании одиночных кавычек можно использовать только две специальные последовательности символов «\\» и «\'».
Строки можно задавать с использованием синтаксис doc, т.е. при помощи знака «<<<», за которым указывается идентификатор. После этой комбинации следует строка. Строка заканчивается там, где в начале новой строки стоит тот же идентификатор, который открывал строковое значение и был расположен после <<<. Такая строка ведет себя так, как если бы она была помещена между знаками двойных кавычек. При этом можно пользоваться последовательностями специальных символов (табл. 6.1).
Пример
<?php
$str = <<<EOD
Example of string
spanning multiple lines
using heredoc syntax.
EOD;
/* Более сложный пример с переменными. */
class foo {
var $foo;
var $bar;
function foo() {
$this->foo = 'Foo'
$this->bar = array ('Bar1', 'Bar2', 'Bar3');
}
}
$foo = new foo () ;
$name = 'MyName';
echo <<<EOT
'Foo' ;
My name is "$name". I am printing some $foo->foo.
Now, I am printing some {$foo->bar[1] } .
This should print a capital 'A': \x41
EOT;
?>
Строки могут быть объединены при помощи оператора объединения строк '.' (точка). Отметим, что оператор сложения '+' не будет работать в такой ситуации. Символы внутри строки можно рассматривать в некотором смысле как элементы массива.
Пример работы со строками
<?php
/* Присваивание строки. */
$str = "This is a string";
/* Присоединение строки. */
$str = $str . "with some more text";
/* Еще один способ присоединения строки. */
$str .= "and a newline at the end.\n";
/* Строка завершится последовательностью '<p>Number: 9</p>' */ $num = 9;
$str = "<p>Number: $num</p>
/* В этом примере (одиночные кавычки) перегрузка переменных не будет произведена, строка будет содержать '<p>Number: $num</p>' */
$num = 9;
$str = '<p>Number: $num</p>';
/* Получаем первый символ строки */
$str = 'Это тест.';
$first = $str[0] ;
/* Получаем последний символ строки. */
$str = 'Это по-прежнему тест.';
$last = $str[strlen($str)-1];
?>
Преобразование строк
Когда строка преобразуется в численное значение, то результирующий тип и значение определяются по следующим правилам.
Строка преобразуется в тип double, если в ней содержатся символы '.', 'е', 'Е'. Если таких символов нет, то строка преобразуется в тип integer. Значение определяется по начальной части строки. Если строка начинается с допустимых числовых символов, то они будут использованы при определении числового значения. Если допустимые числовые символы не были найдены, то значением будет 0 (нуль). Допустимыми числовыми символами являются знаки + и -, за которыми следует одна или несколько цифр, десятичная точка и знак экспоненты в виде символов 'е' или 'Е', за которым следует одна или несколько цифр.
Более подробную информацию можно узнать, раскрыв страницу руководства UNIXF strtod(3).
Чтобы на практике проверить любой из приведенных выше примеров, скопируйте его в файл *.phtm и после присваивания поместите строку echo "\$foo= =$foo; type is ". gettype (S$oo) . «<br>\n";
Массивы
Одномерный массив
РНР поддерживает скалярные и ассоциативные массивы, между которыми не существует различия. Массив может быть создан при помощи функций list() и array(), массив также можно задать, указав значения его элементов в явном виде:
$а [ 0 ] = "abc" ;
$а [1] = "def";
$b["fоо"] = 13.
К массиву можно добавить элементы, если массив не существовал до того, как в него были добавлены элементы, то он будет создан.
$а[ ] = "hello"; // $а[2] == "hello"
$а[ ] = "world"; // $а[3] == "world"
Сортировку элементов массива можно произвести при помощи функций asort(), arsort(), ksort(), rsort(), sort(), uasort(), usort() и uksort(), каждая из них производит сортировку определенного типа. Можно пересчитать количество элементов, содержащихся в массиве, используя функцию count().
Можно перейти от одного элемента массива к последующему или предыдущему с помощью функций next() и prev(). Перебрать все элементы массива можно при помощи функции each().
Многомерный массив
Многомерные массивы создаются с использованием нескольких индексов. Вот ряд примеров создания массивов различной размерности.
На элементы массива можно ссылаться непосредственно внутри строк, заключенных в двойные кавычки:
$а [3] [ 'bar ' ] = 'Bob';
echo "This won't work: $a[3][bar]";
В результате работы получим строку This won't work: Array[bar] (рис. 6.3).
Чтобы всеже получить сам элемент массива перепишем пример в таком, виде:
$а[3]['bar'] = 'Bob';
echo "This will work: " . $a[3][bar];
Сейчас все работает как следует (рис. 6.4).
В случае наличия ошибок можно использовать такую конструкцию, в которой индексы помещены в фигурные скобки:
$а[3] [1 bar ' ] = 'Bob';
echo "This will work: {$a[3][bar]}";
Присвоить значения элементам многомерного массива можно различными способами, однако наиболее интересным представляется такой способ, когда используется команда array() для ассоциативных массивов. Вот примеры.
# Пример 1:
$a["color"] = "red";
$а["taste"] = "sweet";
$а["shape"] = "round";
$a["name"] = "apple";
$a[3] = 4;
#Пример 2:
$a = array(
"color" => "red",
"taste" => "sweet",
"shape " => "round",
"name" => "apple",
3 => 4
);
Функция array() может быть использована и с многомерными массивами:
<?
$а = array(
"apple" => array(
"color" => "red",
"taste" => "sweet",
"shape" => "round"
),
"orange" => array(
"color" => "orange",
"taste" => "tart",
"shape" => "round2
) ,
"banana" => array(
"color" => "yellow",
"taste" => "paste-y",
"shape" => "banana-shaped"
)
) ;
echo $a["apple"]["taste"]; # получим значение "sweet"
?>
Объекты
Инициализация объектов
Для инициализации объекта используется слово new и переменной присваивается экземпляр указанного объекта, например:
<?php
class foo {
function do_foo() {
echo "Doing foo.";
}
}
$bar = new foo;
$bar->do_foo () ;
?>
Подробное описание см. в разделе Классы и Объекты.
Приведение типов
В РНР не поддерживается явное определение типов переменных, тип определяется в зависимости от контекста, в котором появляется переменная. Иными словами, если, например, переменной var присваивается строка, то переменная var становится строковой переменной. Если после этого переменной var будет присвоено целое значение, то переменная будет иметь целый тип.
В качестве примера автоматического преобразования типов в РНР удобно рассмотреть оператор «+». Если хотя бы один из операндов этого оператора имеет тип double, то результат будет иметь тип, double. В противном случае операнды будут считаться имеющими тип. integer. Выполнение оператора не меняет тип самих операндов. Вот примеры:
$ foo = "0"; // $ f оо - string (ASCII 48)
$foo+ + ; // $ foo - string "1" (ASCII 49)
$ foo += 1; // $ f oo - integer (2)
$ foo = $ foo + 1.3; // $ foo - double (3.3)
$fоо = 5 + "10 Little Piggies";
$foo = 5 + "10 Small Pigs";
// $foo - integer (15)
// $foo - integer (15)
Если преобразование типов в двух последних строчках выглядит странным, то советуем просмотреть раздел, посвященный преобразованию строк.
Если всеже появляется необходимость преобразовать переменную к определенному типу, то рекомендуем обратиться к разделу Объявление типов. Для задания и изменения типа переменной используется функция settype().
Вышерассмотренные примеры можно дополнить строкой
echo "\$foo==$f оо; type is " . gettype ($foo) . "<br>\n";
Тогда мы сможем проверить автоматическое приведение типов на практике.
Примечание.
Поведение массивов при приведении типов не определено.
Пример.
$а = 1;
$а[0]
// $а — integer
// $а становится массивом, $а[0] равно "f
Этот пример не представляет никаких трудностей. Однако, рассмотрим другой пример:
// $а is a string
и I .. .
$а [ 0 ] = "f"; // What about string offsets? What happens?
Сейчас мы сталкиваемся с проблемой, а именно, возникает вопрос о том, должна ли переменная $а содержать массив, в котором первый элемент равен «f», или же «f» будет первым символом в строковой переменной $а?
Именно по причине существования такой проблемы принято считать, что результат приведения типов в таких ситуациях не определен. Решение вопроса находится в стадии проработки.
Объявление типов
Объявление типов в РНР работает, в основном, также, как в языке С: имя типа пишется в скобках перед переменной, тип которой объявляется. Вот пример:
$ foo = 10;
$bar = (double) $foo;
// $foo is an integer // $bar is a double
Возможно объявление следующих типов:
(int), (integer) — целый тип integer;
(real), (double), (float) — тип double;
(string) — тип string;
(array) — тип array;
(object) — тип object.
Внутри скобок при объявлении типов можно использовать пробелы и знаки табуляции, т.е. обе строки в примере ниже будут эквивалентны:
$ foo = (int) $bar;
$foo = ( int ) $bar;
He всегда представляется очевидным то, что произойдет при явном приведении различных типов к другим типам. Следует иметь в виду следующее.
При преобразовании скалярных и строковых переменных к массиву, значение переменной становится значением первого элемента этого массива:
$var = ' пока ';
$arr = (array) $var;
echo $arr[0]; // напишет 'пока'
При преобразовании скалярного типа или строки к объекту, значение переменной становится атрибутом объекта, именем такого атрибута является 'scalar':
$var = ' ciao ' ;
$obj = (object) $var;
echo $obj->scalar; // outputs 'ciao'
Переменные
Основные понятия
Переменные в языке РНР начинаются со знака доллара, который располагается перед именем переменной. Переменные чувствительны к регистру. Имя переменной должно начинаться с буквы верхнего или нижнего регистра, за которой могут быть расположены буквы, числа, знак подчеркивания.
Примеры:
$var = "Bob";
$Var = "Joe";
echo "$var, $Var"; // напишет "Bob, Joe"
$4site = 'not yet'; // ошибка, первый знак- цифра
$ 4site = 'not yet'; // верно, начинается со знака подчеркивания
Stflyte = 'mansikka'; // верно; 'д' - это ASCII 228.
Можно использовать русские буквы, например,
<?
$а[3]['ящур'] = 'Прыщ';
echo "Это работает: " . $а[3]['ящур'];
?>
Результат показан на рис. 6.5.
В РНР переменные всегда имеют значения. Если, например, мы присваиваем переменной выражение, то значение этого выражения будет передано переменной. Если после такого присваивания изменить значения переменных, входящих в выражение, то значение первой переменной (которой присвоено выражение) не будет изменено.
В РНР4 существует другой способ присваивания значений переменным — присваивание по ссылке. Иными словами, новая переменная может служить ссылкой на другую переменную. Изменения, произведенные с новой переменной, сказываются на первой переменной и
наоборот. Вторая переменная становится псевдонимом первой. При присваивании не происходит копирования значений. Это сказывается на скорости выполнения программ, скорость увеличивается. Однако увеличение скорости может быть заметно лишь при больших массивах или большом количестве присваиваний.
Чтобы создать ссылку достаточно поставить знак & перед переменной, для которой назначается ссылка.
Пример:
<?php
$foo = 'Bob'; // Присвоим значение 'Bob' переменной $foo
$bar = &$foo; // Ссылка на $foo посредством $bar.
$bar = "My name is $bar"; // Изменяем $bar... echo $foo; // $foo тоже изменилось
echo $bar; ?>
Только имена переменных можно использовать, ссылаясь на них. Ссылки на постоянные и литералы недопустимы.
<?php
$ foo = 25;
$bar = &$foo; // Создаем ссылку.
$bar = & (24 * 7); // Ошибка function test () { return 25;
}
$bar = &test(); // Ошибка.
?>
Заранее определенные переменные
В РНР существует ряд заранее определенных переменных, которые могут быть использованы во всех скриптах. Многие из таких переменных зависят от того, на каком сервере будет запущен скрипт и от других факторов. Не все переменные доступны в режиме вызова РНР из командной строки. Однако многие переменные доступны во всех конфигурациях.
Чтобы получить список всех заранее определенных переменных полезно обратиться к функции phpinfo(). Эта функция не выводит исчерпывающий список переменных, но она может дать список таких переменных, к которым мы определенно сможем иметь доступ посредством скриптов.
Переменные сервера Apache
Эти переменные создаются при работе сервера Apache. Если используется другой сервер, то, вероятно, не все из перечисленных переменных будут доступны. При этом могут использоваться другие переменные, которые не упомянуты в этом разделе. Большое количество переменных описано в спецификации CGI 1.1, поэтому такие переменные скорее всего будут присутствовать и на других серверах.
GA TEWA YJNTERFA СЕ
Какой вариант спецификации CGI используется на сервере, значение
'CGI/l.r.
SERVER_NAM Е
Имя сервера, выполняющего текущий скрипт.
SERVER_SOFTWARE
Строка, идентифицирующая сервер.
SERVERJPROTOCOL
Имя используемого протокола, например, 'HTTP/1.0';
REQUEST_METHOD
Какой использовался метод в процессе доступа к странице: 'GET', 'HEAD', 'POST', 'PUT'.
QUERY_STRING
Строка запроса, посредством которой открыта страница.
DOCUMENT_ROOT
Основной каталог, в котором находится документ, в котором исполняется данный скрипт (по тому, как сконфигурирован сервер).
НТТР_А ССЕРТ
Заголовок текущего запроса.
HTTP_ACCEPT_CHARSET
Заголовок запроса, содержащий кодировку, например, 'iso-8859-l,*,utf-8'.
HTTP_ENCODING
Заголовок, содержащий тип сжатия, например, 'gzip'.
HTTP_ACCEPT_LANGUAGE
Заголовок языка, например, 'еп'.
HTTP_CONNECTION
Заголовок соединения Connection, например, 'Keep-Alive'.
HTTP_HOST
Содержимое заголовка Host.
HTTPJREFERER
Адрес документа, сославшегося на текущий документ.
HTTP_USER_A GENT
Тип клиентского приложения, например, Mozilla/4.5 [en] (XI1; U; Linux 2.2.9 i586). Эта переменная может быть получена с помощью функции get_browser().
REMOTEADDR
Адрес IP, с которого произошло обращение на текущую страницу. REMOTE_PORT
Порт, с которого было произведено обращение к данной странице.
SCRIPT_FILENAME
Абсолютный путь к выполняемому в данное время скрипту.
SERVER_ADMIN
Значение директивы SERVER_ADMIN.
SERVER_PORT
Порт, на котором работает сервер. По умолчанию используется порт 80.
SERVER_SIGNA TURE
Подпись сервера, содержащая версию сервера и имя хоста.
PA TH_TRANSLA TED
Файловая система по отношению к положению текущего скрипта после преобразования виртуальных каталогов в реальные.
SCRIPT_NAME
Содержит путь к текущему скрипту.
REQUEST_URI
Идентификатор URI, использованный для доступа к текущему скрипту, например, yindex.html'.
Переменные окружения
Эти переменные заимствуются из глобального окружения, в котором функционирует РНР и web-cepBep.
Переменные РНР
Эти переменные создаются РНР.
argv
Массив аргументов, переданных скрипту.
агдс
Количество параметров в командной строке, переданных скрипту. PHPJSELF
Имя файла, содержащего текущий скрипт.
HTTP_COOKIE_VARS
Ассоциативный массив переменных, переданных скрипту посредством HTTP cookies. Работает при включенной директиве track_vars или <?php_track_vars?> при активизации внутри скрипта.
Н TTP_GET_ VARS
Ассоциативный массив переменных, переданных скрипту с помощью метода get. Чтобы переменная была доступна, необходимо включить режим отслеживания переменных при помощи директивы track_vars или с помощью <?php_track_vars?>.
HTTP_POST_VARS
Ассоциативный массив переменных, переданных скрипту при помощи метода POST. Работает при включенной директиве track_vars или < ?php_track_vars? >.
Область видимости переменных
Область видимости переменных — это контекст программы, внутри которого определена и может быть использована переменная. Как правило, в РНР все переменные имеют одну и ту же область видимости, которая распространяется на все включенные в скрипт файлы. Например:
$а = 1;
include "b.inc";
Здесь переменная $а будет доступна для всего скрипта, расположенного в файле b.inc. Однако, важно иметь ввиду, что внутри функций, определенных пользователем, создаются локальные переменные, область видимости которых ограничена такой функцией. Например:
$а = 1; /* global scope */ Function Test () {
echo $a; /* reference to local scope variable */
}
Test ();
Этот скрипт не выведет ничего, так как выражение echo использует; локальную переменную, а внешняя переменная $а не передается! функции в виде фактического параметра (функция вообще не содержит параметров). В этом РНР отличается от С, где глобальные переменные оказываются доступными для пользовательских функций. Для того чтобы глобальная переменная была доступна внутри функции,! необходимо внутри функции объявить ее глобальной, например: $а = 1; $Ь = 2;
Function Sum () { global $а, $b; $b = $а + $b;
}
Sum (); echo $b;
Такой скрипт выведет «3». Здесь мы видди, что переменные Sa и $Ь объявлены глобальными внутри функции SumQ. Количество используемых внутри функции глобальных переменных неограничено.
Другой метод осуществить доступ к глобальным переменным - использование заранее определенного массива SGLOBALS. С помощью этого массива предыдущий пример может быть переписан в виде: $а = 1; $Ь = 2;
Function Sum () {
$GLOBALS["b"] = $GLOBALS["a"] + $GLOBALS["b"];
}
Sum () ; echo $b;
Массив SGLOBALS представляет собой ассоциативный массив имен глобальных переменных, которые используются в качестве клю- чей-индексов этого массива, значениями элементов массива являются значения глобальных переменных.
Кроме глобальных переменных могут быть использованы статические переменные. Если внутри функции используется обычная переменная, то при повторном возвращении к функции такая переменная может быть потеряна, как, например, это произойдет для следующего фрагмента кода: Function Test () { $а = 0; echo $а; $а++;
}
Создавать такую функцию довольно бессмысленно, так как при каждом обращении к ней переменная $а будет устанавливаться равной О и увеличение ее на единицу каждый раз будет приводить к значению 1. При этом эта переменная не будет сохранять изменения, произведенные в предыдущем обращении к функции. Чтобы изменить ситуацию, необходимо определить переменную. Чтобы изменить ситуацию, необходимо определить переменную $а как static. Перепишем пример в таком виде:
Function Test () { static $а = 0; echo $а; $а+ + ;
}
Сейчас переменная $а при повторном обращении к функции TestQ сохраняет значение, присвоенное ей при предыдущем обращении к функции TestQ. Повторного присваивания значения 0 не будет произведено.
Статические переменные могут быть использованы в целях определения рекурсивных функций, т.е. таких функций, которые внутри себя производят обращение к самим себе. При создании рекурсивных функций необходимо соблюдать осторожность, так как в такой ситуации легко ошибиться и создать бесконечный цикл. В следующем примере используется рекурсивная функция, число итераций (повторов) которой ограничено числом 10, в которой использована статическая переменная Seount.
<?
Function Test () {
static $count = 0;
$count++;
echo $count; echo "<P>"; if ($ count < 10) { Test ();
)
$count—;
}
Test () ;
?>
Переменные переменных (имена переменных)
Иногда оказывается полезным использование имен переменных, или переменных для переменных. Переменные переменных могут быть динамически (программными средствами) изменены. Обычные .имена могут быть созданы с использованием такого рода инструкций:
$а = "hello";
Строка 'hello' может использоваться как имя переменной, если мы запишем такое выражение:
$$а = "world";
Сейчас имена образуют некую древовидную иерархию. Переменная $а содержит 'hello', а переменная Shello содержит 'world'. Приведем пример, который выведет текст HELLO WORLD:
echo "$а ${$а}";
Эта строка выведет в точности то же самое, что и строка
echo "$а $hello";
См. рис. 6.7.
При использовании имен имени при работе с массивами важно правильно установить порядок имен, к которым относятся индексы. Для этого удобно использовать скобки. Если мы напишем $$а[1], то анализатору будет необходимо знать, к чему относится индекс, к переменной $а или к переменной $$а. Для того, чтобы не возникало такого вопроса, используются скобки: в первом случае мы напишем ${$а[1]}, а во втором случае — ${$а}[1].
Внешние переменные
Формы HTML
Внешние переменные могут бьггь получены скриптом посредством получения форм. Когда скрипт получает форму, то переменные, содержащиеся в форме, становятся доступны этому скрипту. Рассмотрим пример.
Пример с переменной из формы:
<form action="script.phtm" method="post">
Имя: cinput type="text" name="name"><br> cinput type^'submit'^ </form>
После того, как форма будет отправлена серверу, РНР создаст переменную $name, в которой будет размещено значение, введенное в текстовое поле формы. РНР также имеет возможность распознавать массивы, переданные с помощью форм, однако такие массивы должны быть одномерными.
Более сложный пример:
<form action="array.php" method="post">
Имя: cinput type="text" name="personal[name]"><br> Email: cinput type="text" name="personal[email]"><br> Пиво: <br>
<select multiple name="beer[]">
<option va1ие="Холстен">Холстен <option уа1ие="Будвайзер">Будвайзер <option value="Бaлтикa">Бaлтикa </select> <input type="submit">
</form>
Если включена директива track_vars (можно использовать <?php_track_vars?>), то полученные переменные независимо от метода POST или GET, могут быть доступны через ассоциативные глобальные массивы SHTTPPOSTVARS и $HTTP_G ET VARS в зависимости от метода получения переменных.
Переменные элемента отправки формы типа IMAGE
При отправке форму можно использовать ярлык <mpul type=«image»>:
<input type=image src="image.gif" name="sub">
Если сейчас щелкнуть в любом месте рисунка формы, то эта форма будет отправлена вместе с переменными sub_x и sub_y. Эти переменные содержат координаты положения указателя мыши во время щелчка. В момент получения таких переменных происходит изменение имен, так как броузер посылает переменные, в которых вместо значка подчеркивания используется точка. РНР преобразует точки в знаки подчеркивания.
HTTP Cookies
РНР поддерживает механизм передачи cookies удобным образом. Можно использовать функцию SetCookie() для задания cookies. Все полученные от броузера в http-заголовке cookies автоматически преобразуются в соответствующие переменные наподобие того, как это происходит при передаче форм с помощью методов get и post.
Если возникает необходимость передать при помощи одного экземпляра cookie нескольких значений, то можно использовать квадратные скобки после имени cookie. Например:
SetCookie ("MyCookie [ ]", "Testing", time()+3600);
Определенные таким образом cookies заменят старые, если у них совпадут имена. Чтобы такого не происходило, можно воспользоваться счетчиком.
Пример SetCookie
$Count++;
SetCookie ("Count", $Count, time ()+3600) ;
SetCookie ("Cart[$Count]", $item, time ()+3600) ;
Переменные окружения
PHP автоматически создает переменные окружения, которые доступны так же, как и обычные переменные.
echo $НОМЕ; /* Показать переменную окружения НОМЕ. */
Точки в именах внешних переменных
Как правило, РНР не изменяет имена внешних переменных. Однако, существует одно исключение. Если внешняя переменная содержит точку (а точка не может использоваться в именах РНР), то могут произойти неприятности.
$varname.ext; /* недопустимый символ в имени переменной */
При этом анализатор воспримет конструкцию как переменную Svarneame, объединенную оператором объединения строк с конструкцией ext. Очевидно, что это не приведет к желаемым последствиям.
Поэтому РНР заменяет точки в получаемых именах переменных знаками подчеркивания.
Определение типов переменных
Поскольку в РНР типы переменных определяются автоматически и зависят от контекста, в котором появляются переменные, то не всегда бывает очевидным то, к какому типу относится та или иная переменная. Для определения типа переменных существует набор функций, среди которых назовем следующие: gettype(), is_long(), is_double(), is_string(), is_array(), is__object().
Константы
В языке PHP существует механизм создания констант, которые будут существовать наряду с константами, которые всегда существуют при работе РНР. Во многом константы походят на переменные, за тем исключением, что константы не могут быть изменены после того, как они будут определены. Константы определяются при помощи функции define().
Приведем список заранее определенных констант, существующих всегда, если работает РНР.
FILE
Значением этой константы является имя текущего phtm-файла. Если эта константа используется в файле, на который был осуществлен запрос или который был вставлен в родительский файл, то константа равна имени вставленного (но не родительского) файла.
LINE
Номер текущей строки в том порядке, как эта строка появляется в текущем файле.
РНР_ VERSION
Строка, указывающая номер версии РНР.
PHP_OS
Имя операционной системы, на которой работает РНР.
Пример
<?
echo PHP_VERSION."<Р>" ;
echo PHP_OS; ?>
На экране мы увидим запрошенную информацию (рис. 6.8).
TRUE
Значение true.
FALSE
Значение false.
E_ERROR
Ошибка, не являющаяся ошибкой, обнаруженной при проверке синтаксиса, но являющаяся фатальной.
E_WARNING
Обозначает ситуацию, когда РНР обнаружил некоторые ошибки, однако, возможно продолжение работы скрипта.
E_PARSE
Анализатор обнаружил фатальную ошибку синтаксиса. Продолжение работы невозможно.
E_NOTICE
Замечание о том, что возникла ситуация, связанная (или не связанная) с возникновением ошибки (не фатальной).
E_ALL
Все перечисленные выше константы Е_* объединяются этим именем.
Пример задания констант:
<?php
define("CONSTANT", "Hello world.");
echo CONSTANT; // выдает "Hello world."
?>
Пример использования FILE и LINE
<?php
function report_error ($file, $line, $message) {
echo "An error occured in $file on line $line: $message.";
}
report_error( FILE , LINE , "Something went wrong!");
?>
Инструкции
Инструкции являются одними из наиболее важных составных блоков программы на РНР. Практически все, что бы ни было записано на РНР, является инструкцией. Простейший, хотя и не самый строгий вариант определения инструкции таков. Инструкцией является все, что имеет значение.
Одними из наиболее основных примеров инструкции являются константы и переменные. Например когда мы записываем выражение «$а=5», то мы присваиваем '5' переменной $а. '5' имеет значение 5. После присваивания $а будет иметь значение 5.
Несколько более сложным примером инструкций (или выражений) является пример с функциями. Например:
Function foo () {
return 5;
}
Если вам приходилось программировать раньше, то вы уже знакомы с функциями, поэтому вы понимаете, что для определенной выше функции написать выражение $с = foo() — это почти то же самое, если написать $с = 5, и это действиетально так. Функции представляют собой выражения, значением которых является возвращаемое функцией значение. Поскольку функция foo() возвращает 5, то значение выражения 'foo()' будет целое число 5. Как правило, функции возвращают не какое-то фиксированное значение, а для определения возвращаемого значения производят определенные вычисления.
Понятно, что значениями в языке РНР могут быть не только целые числа, гораздо более часто встречаются другие типы. РНР поддерживает три скалярных типа: целые числа, числа с плавающей точкой и строки. Скалярными величинами называются такие величины, которое не могут быть разделены на более мелкие составные части в отличие, например, от массивов. В РНР также существует два составных типа. Это массивы и объекты. Каждый такой тип может быть присвоен переменной, а также любой из них может быть возвращен в виде значения функции.
В качестве примера выражений полезно рассмотреть условные выражения. Значением условных выражений всегда бывает либо 0, либо 1, это обозначает false и true соответственно. Среди операторов, которые используются в инструкциях сравнения, используются такие операторы, как > (больше), >= (больше или равно), == (равно), != (не равно), < (меньше) и <= (меньше или равно). Такие выражения часто используются внутри условных операторов, в частности при использовании оператора if.
Еще один пример выражения, состоящего из тернарного оператора.
$first ? $second : $third
Значением такого выражения является значение выражения $second, но только в том случае, если значением выражения $first будет true (или отличное от нуля), если же значением первого выражения будет О (или false), то все выражение в целом примет значение, равное значению выражения $third.
В качестве упражнения приведем пример с использованием различных выражений. {
/* присваивает значение 5 двум переменным $а и $Ь */ /* постфиксное увеличение и присваивание, присваивает исходное значение переменной $а (5) переменной $с */
/* префиксное увеличение и присваивание, присваивает увеличенное значение переменной $Ь (6) переменным $d и $е */
обе переменные $d и $е равны б */
/* присваивает двойное значение переменной $d перед тем, как $d будет увеличено на единицу, т.е. 2*6 = 12 присваивается переменной $f */
/* присваивает двойное значение увеличенной на единицу переменной $е переменной $д, т.е. 2*7 = 14 присваивается $д */'
Function double($i) return $ i * 2;
}
$b = $a = 5; $c = $a++;
$e = $d = ++$b;
/* с этого момента $f = double($d++) ;
$g = double(++$e) ;
$h = $g += 10; /* вначале переменная $g увеличивается на 10,
принимая значение 24, а затем значение 2 4 присваивается переменной $h, , т.ё. и $h, и $д принимают значение 24. */
В начале этого раздела мы предпололжили, что практически все описываемые нами типы инструкций являются выражениями. Однако, строго говоря, не каждое выражение является инструкцией. Если выражение состоит из нескольких элементов, разделенных одним или несколькими значками точки с запятой, то такое выражение не может считаться инструкцией, однако, составные части такого выражения по-прежнему являются инструкциями. Выражение в целом не является инструкцией,, поскольку оно не имеет одного определенного значения. Каждая отдельная инструкция, входящая в такое выражение, имеет значение, и для всего выражения в целом таких значений может быть несколько.
УПРАВЛЕНИЕ ХОДОМ ВЫПОЛНЕНИЯ ПРОГРАММЫ
Операторы
Арифметические операторы
Операторы присваивания
Побитовые операторы
Операторы сравнения
Операторы управления ошибками
Операторы выполнения системных команд
Операторы увеличения и уменьшения на единицу
Логические операторы
Иерархия операторов
Операторы для работы со строками
Управление последовательностью выполнения инструкций
Функции
Функции, определяемые пользователем Аргументы функции Возвращаемые значения Ключевое слово old_function Переменные функции
Классы и объекты
Ссылки
Что такое ссылки
Для чего используются ссылки
Чем не являются ссылки
Возвращение значений при помощи ссылок
Операторы
Арифметические операторы
Арифметические операторы (табл. 7.1) используются для осуществления обычных арифметических действий, которым нас обучали в школе.
Оператор деления(«/») возвращает целую величину (результат целочисленного деления) в том члучае, когда оба оператора — целые (или строка, преобразованная в целое). Если каждый операнд является величиной с плавающей запятой, то выполнится деление с плавающей запятой.
Операторы присваивания
Основным оператором присваивания является оператор обычного присваивания «=». Это не знак равенства. Этот оператор присваивает значение, расположенное справа от него левому операнду.
Значением выражения присваивания является присваиваемая величина. Так, выражение «$а = 3» имеет значение 3. Этот факт позволяет использовать довольно тонкие конструкции, например:
$а = ($Ь = 4) + 5; // теперь $а равно 9, а $Ь стало равным 4.
Существуют и другие операторы присваивания, они включют в себя комбинации оператора присваивания с арифметическими операторами. Например:
$а = 3; $а += 5; // теперь $а равно 8, как если бы мы написали: $а = $а + 5;
$b = "Hello ";
$ b .= "There!"; // теперь $b равно "Hello There!", как если бы мы написали $b = $b . "There!";
Побитовые операторы
Побитовые операторы позволяют работать с определенными дельными битами (табл. 7.2).
Операторы сравнения
Операторы сравнения, как и подобает в соответствии с их названием, позволяют сравнивать величины (табл. 7.3).
Операторы обработки ошибок
В РНР определен оператор управления ошибками. Это оператор Если этот оператор вставлен перед выражением, то все сообщения об ошибках, генерируемые этим выражением, будут проигнорированы, Если включена опция track_errors, то все сообщения об ошибках будут сохранены в глобальной переменной $php_errormsg. При возникновении очередной ошибки значение этой переменной переписывается, поэтому при необходимости следует своевременно воспользоваться текущим значением этой переменной.
<?php
/* Умышленная ошибка */
$res = @mysql_query ("select name, code from 'namelist") or die ("Query failed: error was '$php_errormsg'");
?>
См. также error_reporting().
Предупреждение.
Оператор @ отключает вывод сообщений о критических ошибках, приводящих к прекращению выполнения скрипта.
Оператор выполнения системных команд
В РНР существует один оператор выполнения системных команд - оператор обратных кавычек. Это не одиночные, а обратные кавычки, РНР предпримет попытку выполнить системную команду, размещенную между обратными кавычками. Результат работы системной команды можно сохранить в виде значения переменной. Например:
$ output = 'Is -al';
echo "< system pre>$output</pre>" ;
См. также (), passthru(), exec(), popen(), escapeshellcmd().
Операторы увеличения и уменьшения
В РНР поддерживаются операторы увеличения и уменьшения на единицу, подобные тем, что используются в языке С (табл. 7.4).
Простой скрипт с примером:
<?php
echo "<hЗ>Постфиксный увеличения</hЗ>";
$а = 5;
echo "Будет 5: " . $а++ . "<br>\n";
echo "Будет 6: " . $а . "<br>\n";
echo "<hЗ>Префиксный увеличения</hЗ>";
$а = 5;
echo "Будет 6: " . ++$а . "<br>\n";
echo "Будет be 6: " . $а . "<br>\n";
echo "<hЗ>Постфиксный уменьшения</hЗ>" ;
$а = 5;
echo "Будет 5: " . $а— . "<br>\n";
echo "Будет 4: " . $а . "<br>\n";
echo "<113>Префиксный уменьшения</hЗ>" ;
$а = 5;
echo "Будет 4: " . —$а . "<br>\n";
echo "Будет 4: " . $а . "<br>\n";
?>
На экране мы увидим то, что изображено на рис. 7.1.
Логические операторы
Логические операторы соответствуют обычным классическим логическим операциям (табл. 7.5).
Разница в двух операторах «and» и «оr» состоит в разнице их приоритетов (см. ниже).
Иерархия операторов
Между операторами устанавливается старшинство, т.е. порядок, в котором эти операторы будут выполняться. Приведенная ниже табл. 7.6 показывает старшинство операторов
Операторы для работы со строками
Для работы со строками существует два оператора. Основным оператором является оператор объединения строк (.) — точка. Этот оператор возвращает строку, состоящую из строки, хранящейся в левом операнде, объединенную со строкой, хранящейся в правом операнде. Второй оператор — это оператор объединения строк с присваиванием ('.='), который присваивает левому операнду исходное значение левого операнда, объединенное в общую строку со значением правого операнда.
$а = "Hello ";
$b = $а . "World!"; // $b содержит "Hello World!"
$a = "Hello";
$a .= "World!"; // сейчас $a содержит "Hello World!"
Управление последовательностью выполнения инструкций
В этом разделе мы рассмотрим следующие операторы и функции! используемые для задания последовательности выполнения инструкций РНР.
else.
elseif
Альтернативный синтаксис условных операторов
while.do..while.for.
foreach.
break.
continue.
switch.
Специальные конструкции
Required().
Include().
require_once().
include_once().
Все программы на языке PHP состоят из блоков выражений, из блоков инструкций. Выражения могут быть выражениями, содержащими присваивания, вызовы функций, циклы, условные выражения и пустые выражения. Каждое выражение, как правило, заканчивается знаком точки с запятой. Набор выражений может быть сгруппирован в отдельный самостоятельный блок. Для этого выражения, образующие такой блок, помещаются между открывающей и закрывающей фигурными скобками. Такой блок выражений представляет собой самостоятельное выражение. В данной главе мы рассматриваем различные типы такого рода выражений.
if
Конструкция, содержащая IF, предоставляет одну из наиболее ценных возможностей многих языков, включая язык РНР. Она позволяет организовать выполнение фрагментов кода с проверкой выполнения того или иного условия. Возможности РНР по использованию выражения IF похожи на возможности, предоставляемые языком С. Синтаксис таков: if (expr) statement
Вначале вычисляется значение «ехрг». Если ехрг равно TRUE, то РНР выполнит «statement», а если FALSE, то выражение statement не будет выполнено.
Следующий пример выведет фразу 'a is bigger than b', если $a больше $b: if ($a > $b)
print "a is bigger than b";
Часто требуется исполнить больше чем одно выражение с проверкой условия. В этом случае нет необходимости включать каждое выражение в конструкцию IF. Вместо этого можно сгруппировать несколько выражений в блок выражений с использованием фигурных скобок. Следующий код не только выведет фразу, но и присвоит значение $а переменной $Ь:
if ($а > $b) { print "a is bigger than b"; $b = $a; }
Выражения IF могут быть вложены друг в друга. Уровень вложенности не ограничивается.
else
Иногда возникает необходимость проверить условие и в случае его выполнения выполнить заданное выражение, а в случае невыполнения условия, выполнить другое выражение. Для организации такого поведения используется конструкция ELSE. ELSE расширяет возможности IF в части возможностей обработки выражений.
Пример, приведенный ниже, выведет фразу 'a is bigger than b' если $a больше $b, и 'a is NOT bigger than b', в противном случае: if ($a > $b) print "a } else {
print "a
}
Выражение, расположенное после ELSE, выполняется только в том случае, если выражение, следующее за IF, равно FALSE, а если есть конструкции ELSEIF, то если и они также равны FALSE (см. ниже).
elseif
Конструкция ELSEIF, как и следует из ее названия, является комбинацией IF и ELSE. ELSEIF, как и ELSE, позволяет выполнить выражение, если значение IF равно FALSE, но в отличие от ELSE оно выполнится только тогда, если выражение ELSEIF равно TRUE. На-
{
is bigger than b"; is NOT bigger than b";
пример, следующий код выведет 'a is bigger than b' если$а>$Ь, 'a is equal to b' если $a==$b, и 'a is smaller than b' если$а<$Ь:
if ($a > $b) {
print "a is bigger than b"; } elseif ($a == $b) {
print "a is equal to b"; } else {
print "a is smaller than b";
}
Внутри одного выражения IF может быть несколько ELSEIF. Первое выражение ELSEIF (если таковое есть), равное TRUE, будет выполнено. В РНР можно написать 'else if (два слова), что будет значить то же самое, что и 'elseif (одно слово). Выражение ELSEIF будет выполнено только если выражение IF и все предыдущие ELSEIF, равны FALSE, а данный ELSEIF равен TRUE.
Альтернативный синтаксис операторов
РНР предлагает и иной путь для группирования операторов, содержащих IF, а именно для операторов if, while, for, switch. В таких конструкциях вместо фигурных скобок используются другие обозначения. Вместо открывающей скобки используется двоеточие (:). Закрывающая скобка заменяется одним из следующих слов: endif;, endwhile;, endfor;, endswitch;, (в зависимости от оператора).
Наиболее часто такие конструкции используются при осуществлении вставки блоков HTML внутрь оператора IF, но они могут использоваться в любом месте. Вместо использования фигурных скобок за «IF (statement)» должно следовать двоеточие, одно или несколько выражений и завершающий ENDIF. Вот пример:
<?php if ($а==5): ?> А = 5 <?php endif; ?>
В этом примере блок «А = 5» вставлен внутрь выражения IF, который представлен с применением двоеточия. Блок HTML будет передан клиенту только тогда, когда $а равно 5.
Такой синтаксис применим как к ELSE, так и к ELSEIF (ехрr). Вот еще один пример: if ($а == 5) :
print "а РАВНО 5"; print "..."; elseif ($а == б) :
print "а РАВНО б"; print " ! 1 !";
else:
print "а НЕ РАВНО НИ 5, НИ б"; endif;
См. также while, for, if.
while
Смысл действий оператора WHILE весьма прост. Этот оператор аналогичен оператору while в языке С.
while (ехрг) statement
Он предписывает выполнять вложенный в тело конструкции while оператор (или набор операторов, заключенных в фигурные скобки) до тех пор, пока выражение ехрг имеет значение TRUE. Значение выражения проверяется каждый раз при очередном начале цикла (при возврате к началу блока операторов), так что если значение выражения изменится внутри цикла, то он не прервется до конца блока. В случае, если значение ехрг равно FALSE с самого начала, цикл не выполняется ни разу.
Как и в случае с оператором IF, мы можем сгруппировать несколько операторов внутри фигурных скобок или использовать альтернативный синтаксис:
WHILE(ехрг): выражения ... ENDWHILE;
Следующие варианты представления операторов эквивалентны (оба выводят числа с 1 по 10):
/* example 1 */
$i = 1;
while ($i <= 10) { print $i++; }
/* example 2 */
$i = 1;
while ($i <= 10) : print $i; $i + + ;
endwhile;
do., while
Цикл DO..WHILE очень похож на WHILE за исключением того отличия, что значение логического выражения в случае с оператором do ... while проверяется не до, а после окончания выполнения блока операторов. Основное отличие состоит в том, что DO..WHILE гарантированно выполнится хотя бы один раз, что в случае WHILE не обязательно.
Для циклов DO...WHILE существует только один вид синтаксиса:
$i = 0;
do {
print $i; } while ($i>0) ;
Этот цикл выполнится один раз, так как после окончания итерации будет проверено значение логического выражения, а оно равно FALSE (Si не больше 0), и выполнение цикла завершится.
Программисты, использующие язык С, могут быть знакомы с иным вариантом употребления DO...WHILE, позволяющем прекратить исполнение блока операторов в середине, не выполняя блок до конца, путем внедрения его в цикл DO...WHILE(0) оператора BREAK. Следующий пример демонстрирует такую возможность:
do {
if ($i < 5) {
print "i еще не слишком велико"; break;
}
$i *= $factor;
if ($i < $minimum_limit) { break;
}
print "i уже достаточно велико";
.. . дальнейший код... } while(0);
For
Циклы FOR — наиболее мощные циклы в РНР. Они работают подобно тому, как работают циклы FOR в С. Синтаксис цикла FOR:
FOR (exprl; ехрг2; ехргЗ) statement
Первое выражение (exprl) всегда вычисляется в начале цикла. В начале каждой итерации вычисляется ехрг2. Если оно равно TRUE, то цикл продолжается и выполняются вложенный оператор (или блок операторов). Если оно равно FALSE, то цикл заканчивается. В конце каждой итерации вычисляется ехргЗ.
Каждое из этих выражений может быть пустым. Если ехрг2 пусто, то цикл продолжается бесконечно (РНР по умолчанию считает его равным TRUE, как и в С). Такая ситуация оказывается не столь бесполезной, как может показаться, так как зачастую бывает нужно закончить выполнение цикла, используя оператор BREAK в сочетании с логическим условием, вместо использования логического выражения в FOR.
Рассмотрим следующие примеры. Все они выводят числа с 1 по 10:
/* пример 1 */
for ($i = 1; $i <= 10; $i + + ) { print $i;
}
/* пример 2 */
for ($i = 1;;$i++) { if ($i > 10) { break;
}
print $i;
}
/* пример 3 */
$i = 1; for (;;) {
if ($i > 10) { break;
}
print $i; $i + + ;
/* пример 4 */
for ($i = 1; $i <= 10; print $i, $i + +) ;
Конечно, первый вариант кажется лучшим (или, может быть, четвертый). Важно то, что возможность использования пустых выражений в цикле FOR зачастую оказывается полезной.
РНР также поддерживает альтернативный синтаксис FOR:
FOR (exprl; ехрг2; ехргЗ): выражение; ...; endfor;
Другие языки используют оператор foreach для того, чтобы обрабатывать массивы или списки. РНР использует для этого оператор while и функции listQ и eachQ. (Смотрите описания этих функций.)
foreach
В PHP4 существует конструкция foreach, напоминающая аналогичные конструкции других языков, например, языка Perl. Эта конструкция предоставляет удобный вариант просмотреть все элементы массива и выполнить определенные действия с ними. Эта конструкция может быть использована с применением двух вариантов синтаксиса. Первый вариант:
foreach(array_expression as $value) statement
Второй вариант представляется небольшим расширением первого:
foreach(array_expression as $key => $value) statement
Такая конструкция организует цикл проверки всех элементов массива, имя которого дано в array_expression. При каждом повторе цикла значение текущего элемента массива присваивается переменной $ value, а внутренний указатель в массиве перемещается на одну позицию вперед.
Второй вариант синтаксиса позволяет задавать текущее значение для $кеу, равное значению элемента массива, для каждого цикла.
Примечание.
В начале выполнения цикла внутренний указатель возвращается к первому элементу массива, поэтому вызывать функцию reset() перед циклом нет необходимости. Кроме того, оператор foreach работает не с самим массивом, а с копией этого массива.
Следующие примеры оказываются функционально одинаковыми;
reset ($arr);
while (list(, $value) = each ($arr)) ( echo "Value: $value<br>\n" ;
}
foreach (Sarr as $value) {
echo "Value: $value<br>\n" ;
}
Еще один пример одинаковых конструкций:
reset ($arr);
while (list($key, $value) = each ($arr)) { echo "Key: $key; Value: $value<br>\n";
}
foreach ($arr as $key => $value) {
echo "Key: $key; Value: $value<br>\n";
}
Еще несколько примеров использования конструкции foreach:
/* foreach example 1: value only */ $a = array (1, 2, 3, 17); foreach ($a as $v) {
print "Current value of \$a: $v.\n";
}
/* foreach example 2: value (with key printed for illustration) */ $a = array (1, 2, 3, 17) ;
$i = 0; /* for illustrative purposes only */
foreach ($a as $v) {
print "\ $a[$i] => $k.\n";
}
/* foreach example 3: key and value */ $a = array (
"one" => 1, "two" => 2, "three" => 3, "seventeen" => 17
) ;
foreach($a as $k => $v) {
print "\$a[$k] => $v.\n";
}
break
Оператор break прерывает выполнения циклов for, while и структур switch.
break может (но не обязан) иметь числовой аргумент, который указывает количество вложенных структур, прекращение выполнения которых будет осуществлено этим оператором break.
$arr = array ('one', 'two', 'three', 'four', 'stop', 'five');
while (list (, $val) = each ($arr) ) ( if ($val == 'stop') {
break; /* You could also write 'break 1;' here. */
echo "$val<br>4\n";
} ' S
/* Using the optional argument. */
$i = 0;
while (++$i) {
switch ($i) { case 5:
echo "At 5<br>\n";
break 1; /* Exit only the switch. */ case 10:
echo "At 10; quitting<br>\n";
break 2; /* Exit the switch and the while. */ default:
break;
}
}
continue
Оператор continue используется внутри структур циклов для того, чтобы пропустить следующую за оператором часть цикла при выполнении текущей итерации (текущего шага цикла) и перейти к следующему шагу цикла, начав выполнение его с начала. Оператор continue может иметь необязательный числовой аргумент, указывающий количество вложенных циклов, окончание которых будет пропущено, while (list ($key, $value) = each ($arr)) { if (!($key % 2)) ( // skip odd members continue;
}
do_something_odd ($value);
}
$i = 0;
while ($i++ < 5) {
echo "Outer<br>\n"; while (1) {
echo " Middle<br>\n"; while (1) (
echo " Inner<br>\n"; continue 3;
}
echo "This never gets output.<br>\n";
}
echo "Neither does this.<br>\n";
switch
Оператор switch работает также, как последовательность, состоящая из нескольких операторов IF, которые имеют одинаковое выражение. Часто оказывается необходимым осуществлять проверку и сравнение одной и той же переменной (или выражения) и выполнять те или иные действия в зависимости от того, каким будет значение этой переменной (или выражения). Для этого используется оператор switch.
В приведенном ниже примере одна и та же задача решается двумя разными способами (при помощи операторов if и при помощи оператора switch).
if ($i == 0) {
print "i equals 0";
}
if ($i == 1) {
print "i equals 1";
}
if ($i == 2) {
print "i equals 2";
}
switch ($i) { case 0:
print "i equals 0"; break; Case 1:
print "i equals 1"; break; case 2:
print "i equals 2"; break;
}
Чтобы избежать ошибок, полезно понимать механизм работы оператора switch. Выражения оператора выполняются строка за строкой, однако вначале код не будет выполняться. Код будет выполнен лишь в том случае, когда выражение, стоящее после case, совпадет с указанным в начале оператора выражением. Затем будет выполняться код без прерываний до конца блока switch. Чтобы прервать выполнение операторов, необходимо поместить инструкцию break. Вот пример:
switch ($i) { case 0:
print "i equals 0"; case 1:
print "i equals 1"; case 2:
print "i equals 2";
}
В этом примере если $i равняется 0, то будут выполнены все операторы print. Если $i равно 2, то будут выполнены только два оператора print. И лишь при выполнении условия равенства $i двум мы получаем то, что и предполагается, т.е. будет выполнен лишь последний оператор.
В операторе switch проверка условия осуществляется лишь один раз, а затем происходит сравнение этого результата со значениями, указанными в case. В случае с оператором elseif проверка условия происходит на каждом шаге.
Еще один пример:
switch ($i) { case О case 1 case 2
print "i is less than 3 but not negative";, break; case 3:
print "i is 3";
}
В этом операторе может использоваться специальная конструкция default, в которой можно указать выражение, выполняемое в том случае, если явных совпадений не было найдено. Вот пример:
switch ($i) { case 0:
print "i equals 0"; break; case 1:
print "i equals Inbreak; case 2:
print "i equals 2"; break; default:
print "i is not equal to 0, 1 or 2";
Выражение, стоящее в операторе case, должно быть приводимо к простому типу, т.е. к целому числу или числу с плавающей точкой, а
также к строке. Объекты и массивы не могут использоваться в качестве выражения, если только они не являются ссылками на простые типы и не могут быть приведены к ним.
Для переключателей switch может быть использован альтернативный синтаксис.
switch ($i) : case 0:
print "i equals 0"; break; case 1:
print "i equals 1"; break; case 2:
print "i equals 2"; break; default:
print "i is not equal to 0, 1 or 2";
endswitch;
Некоторые функции, используемые для управления последовательностью выполнения инструкций
requiref)
Функция require() производит вставку (в том месте, где используется эта функция) запрашиваемого файла. Функция похожа на препро- цессорную директиву #include в языке С.
Если в РНР включена возможность использования URL-адресов («URL fopen wrappers»), то в качестве аргумента функции require() может быть указан URL-адрес наряду с именами локальных файлов. См. также описание функции fopen().
При работе с функциями include() и require(), важно иметь в виду то, что анализ PHP-кода прекращается в месте вставки файла, вставляемый фрагмент анализируется в режиме HTML, начиная с начала вставляемого файла. После того, как будет обнаружен конец вставляемого файла, вновь вступает в силу режим анализатора РНР. По этой причине все содержимое вставляемого файла, если оно должно быть выполнено с использованием РНР, должно быть вставлено внутрь открывающего и закрывающего ярлыков РНР.
Слово requireQ по сути своей не является функцией РНР, оно I скорее представляет собой специальную конструкцию языка. По этим причинам эту «функцию» нельзя использовать внутри других, содержащих ее выражений, а также осуществлять попытки прочитать возвращаемое ею значение, так как она не возвращает никакого значения.
В отличие от функции include(), функция requireQ всегда осуществляет вставку запрошенного файла даже в том случае, когда строка PHP-кода, в которой расположена инструкция requireQ, не будет никогда выполнена. Если вставка файла должна быть осуществлена в зависимости от выполнения тех или иных условий, необходимо использовать инструкцию include(). В то время как условное выражение не влияет на require(), инструкция include() не будет выполнена, если встретится во фрагменте условного оператора, условие которого принимает значение false.
По аналогии с условными операторами, на поведение инструкции requireQ не влияют операторы циклов. Однако, условия циклов будут приняты во внимание в случае использования инструкции include(). Это означает, что если инструкция requireQ будет помещена внутрь цикла, то вставка указанного в качестве аргумента файла будет осуществляться на каждом шаге оператора. Чтобы избежать этого, можно использовать инструкцию includeQ.
require ('header.inc') ;
Вставленный при помощи инструкции requireQ код наследует все переменные, которые содержались в той строке исходного файла, в которой находилась инструкция requireQ. Если же инструкция require() была размещена внутри функции, то весь код, размещенный в вызываемом файле, будет выполняться также, как если бы он было размещен внутри этой функции.
Если запрошенныйпри помощи requireQ файл открывается с использованием протокола HTTP с применением fopen, а сервер, на котором расположен файл, рассматривает запрошенный файл, как файл с PHP-кодом, то переменные могут быть переданы запрашиваемому файлу при помощи обычной строки запроса URL таким способом, как это делается с использованием метода HTTP GET. Такой способ по сути своей отличается от простого включения файла в вызывающий файл с помощью инструкции requireQ, поскольку в этом случае файл предварительно будет обработан на удаленном сервере, так как все программные инструкции будут уже выполнены, а вместо инструкции requireQ будет вставлен результат выполнения РНР-кода на удаленном сервере.
/* В этом примере подразумевается, что сервер с именем someserver сконфигурирован так, что производит обработку файлов .php, но не обрабатывает файлы . txt files. */
/* Не работает, t"); /* Работает. */ require ("file.php"); /* Работает. */
Си. также include(), require_onceQ, include_once(), readfileQ, virtual().
includeQ
Инструкция includeQ осуществляет вставку (в то место, где расположена инструкция) и выполнение указанного в качестве аргумента файла.
Если в РНР включена возможность использования URL-адресов («URL fopen wrappers»), то в качестве аргумента функции requireQ может быть указан URL-адрес наряду с именами локальных файлов. См. также описание функции fopenQ.
Вставляемый фрагмент рассматривается как HTML-код. Если вставляемый фрагмент должен быть интерпретирован как PHP-код, то такой фрагмент вставляемого файла должен быть расположен внутри открывающего и закрывающего ярлыков РНР.
Пример:
$files = array ('first.inc1, 'second.inc', 'third.inc');
for ($i = 0; $i < count($files); $i++) { include $files[$i];
)
Инструкция includeQ отличается от requireQ, она выполняется всякий раз, когда встречается как часть PHP-кода, в то время как инструкция requireQ выполняется единожды независимо от того, где она встречается в исходном PHP-коде и будет ли она выполнена по условиям операторов программы, т. е. вне зависимости, что покажет условие, если инструкция расположена внутри условного оператора, например, внутри оператора if.
Можно использовать такие конструкции, содержащие в себе includeQ, как, например (учитывая, что oncludeQ — это не функция, а специальная конструкция языка):
/* Это, однако, ошибочно, и не будет работать так, как предполагается. */ if ($condition)
include($file);
else
include($other); /* Это правильно. */ if ($condition) {
include($file);
} else {
include($other);
}
Еще один пример:
/* Здесь предполагается наличие файла test.inc, расположенного в
той же директории, что и основной файл. */
<?php
echo "Before the return <br>\n"; if (1) {
return 27;
}
echo "After the return <br>\n"; ?>
Предполложим, что основной файл main.phtm содержит следующий код: <?php
$retval = include ('test.inc');
echo "File returned: '$retval1<br>\n"; ?>
При обращении к файлу main.phtm произойдет ошибка во второй строке, тем не менее результат работы должен быть таким (см. рис. 7.2): Before the return File returned: '27'
Сейчас измением содержимое файла main.html и сделаем его таким:
<?php
include ('test.inc');
echo "Back in main.html<br>\n"; ?>
Сейчас PHP4 возвратит такой ответ (см. рис. 7.3):
Before the return Back in main.html
В варианте РНРЗ мы увидели бы такой ответ:
Before the return 27Back in main.html Parse error: parse error in main.html on line 5
Ошибка произошла потому, что выражение return было включено за пределами функционального блока в файле test.inc. Если исправить ошибку, то ответ будет таким:
Before the return 27Back in main.html)
Вставленный при помощи инструкции requireQ код наследует все переменные, которые содержались в той строке исходного файла, в которой находилась инструкция require(). Если же инструкция requireQ была размешена внутри функции, то весь код, размещенный в вызываемом файле, будет выполняться так же, как если бы он было размещен внутри этой функции.
Если запрошенныйпри помощи iticlude() файл открывается с использованием протокола HTTP с применением fopen, а сервер, на котором расположен файл, рассматривает запрошенный файл, как файл с PHP-кодом, то переменные могут быть переданы запрашиваемому файлу при помощи обычной строки запроса URL таким способом, как это делается с использованием метода HTTP GET. Такой способ по сути своей отличается от простого включения файла в вызывающий файл с помощью инструкции includeQ, поскольку в этом случае файл предварительно будет обработан на удаленном сервере, так как все программные инструкции будут уже выполнены, а вместо инструкции includeQ будет вставлен результат выполнения РНР-кода на удаленном сервере. /* Сервер someserver выполняет файлы .php, но не выполняет файлы .txt files. */
/* Не будет работать; file.txt не исполняется сервером someserver. */ include ("http://someserver/file.txt?varone=l&vartwo=2");
/* не будет работать; поиск будет осуществлен в локальной файловой системе для файла 'file.php?varone=l&vartwo=2 1 . */ include ("file.php?varone=l&vartwo=2") ;
/* Работает. */
include ("http://someserver/file.php?varone=l&vartwo=2" ) ;
$varone = 1;
$vartwo = 2;
include ("file.txt"); /* Работает. */
include ("file.php"); /* Работает. */
См. также requireQ, requirejonceQ, includejonceQ, readftleQ, virtualQ.
requirejonce ()
Эта инструкция работает во многом схожим образом с тем, как работает инструкция require(). Единственное отличие состоит в том, что эта инструкция осуществляет вставку указанного файла в исходный текст лишь один раз, что позволяет избежать возникновения ошибок. Вот пример использования require_опсе():
<?php
define(PHPVERSION, floor(phpversion())); echo "GLOBALS ARE NICE\n"; function goodTeaO {
return "Oolong tea tastes good!";
) ?>
Файл foolib.inc <?php
require ("utils.inc"); function showVar($var) { if (PHPVERSION == A) {
printer($var); } else {
dump_var($var);
}
}
// прочие инструкции . . .
Затем можно создать файл cause_error_require.phtm
Пример файла cause_error_require.phtm
<?php
require("foolib.inc");
/* the following will generate an error */ require("utils.inc");
$foo = array("1",array("complex","quaternion"));
echo "this is requiring utils.inc again which is also\n";
echo "required in foolib.inc\n";
echo "Running goodTea: ".goodTea()."\n" ;
echo "Printing foo: \n";
showVar($foo); ?>
Изменения в foolib.inc:
require_once ("utils.inc"); function showVar($var) {
Файл avoid_error_require_once.phtm
require_once("foolib.inc"); require_once("utils.inc");
$foo = array ("1",array("complex","quaternion")) ;
После выполнения мы получим: GLOBALS ARE NICE
This is requiring globals.inc again which is also Required in foolib.inc
Running goodTea: Oolong tea tastes good! Printing foo: Array (
[0] => 1 [1] => Array (
=> complex
=> quaternion
)
)
Заметим, что данная инструкция работает по аналогии с директивой препроцессора С #include, т.е. в момент работы анализатора и перед тем, как скрипт будет выполнен. Вставляемый фрагмент из файла не должен быть фрагментом, вставляемым динамически во время выполнения скрипта. Для таких целей подойдут инструкции includeQ и include jonceQ.
См. также require(), includeQ, include jonceQ, get_requiredJiles(), getjincludedJilesQ, readfdeQ, virtualQ.
include_once()
Инструкция include_onceQ осуществляет вставку и исполнение кода файла, указанного в качестве аргумента. Поведение этой инструкции схоже с поведением инструкции includeQ с той разницей, что. вставка кода происходит только один раз.
См. также requireQ, includeQ, require_onceQ, get_requiredJiles(), getjncludedJilesQ, readfileQ, virtualQ.
Функции
В этом разделе мы рассмотрим такие вопросы.
Функции, определяемые пользователем.
Аргументы функции.
Возвращаемые значения.
Ключевое слово old_function.
Переменные функции.
Функции, определяемые пользователем
Функции могут быть определены с использованием следующего синтаксиса:
function f оо ($arg $arg 2, . . ., $arg n) { echo "Example function.\n" ; return $retval;
}
В теле функции может быть размещен любой допустимый РНР- код, включая описания других функций и классов. В РНРЗ функция должна была быть определена до того, как к ней будет произведено обращение. В РНР4 таких ограничений уже нет. РНР не поддерживает перегрузку типов для функций, здесь также нет возможности отменить определение функции или определить функцию заново.
В РНРЗ не поддерживается переменное число аргументов функции, хотя поддерживается использование аргументов по умолчанию. В РНР4 поддерживается как переменное число аргументов, так и аргументы по умолчанию, а также ссылки на другие функции. Для получения дополнительной информации см. func_num_args(), func_get_arg(), func_get_args().
Аргументы функции
Информация может быть передана функции с использованием списка аргументов функции, который представляет собой список переменных и констант, отделенных друг от друга запятыми.
В РНР используется передача переменных с их значениями, передача по ссылке и передача значений по умолчанию. Возможно использования списка аргументов переменной длйны и ссылок для функций, см. описание func_num_args(), funcjget_arg(), Junc_get_args().
Пример:
function takes_array($input) {
echo "$input[0] + $inputfl] = $input[0]+$input[1];
}
Аргументы, передаваемые по ссылкам
По умолчанию аргумент функции передаются в виде своих значений, таким .образом, если значение переменной будет изменено внутри функции, то значение переменной за пределами функции не будет изменено. Если стоит задача изменения значения переменной и за пределами функции, то аргументы должны быть переданы по ссылке.
Для того, чтобы аргумент был передан функции по ссылке, следует использовать знак &, поместив его перед именем аргумента в описании функции. Вот пример:
function add_some_extra(&$string) {
$string .= 'and something extra.';
}
$str = 'This is a string, ';
add_some_extra($str);
echo $str; // outputs 'This is a string, and something extra.'
Если необходимо передать аргумент по ссылке для функции, которая не принимает ссылки на аргументы по умолчанию, то сделать это можно, поместив знак & перед именем аргумента при обращении к функции. Например:
($bar) {
' and something extra.'; is a string, ' ;
\
// outputs 'This is a string, 1
// outputs 'This is a string, and something extra.'
Значения аргументов по умолчанию
Можно определить значения аргментов по умолчанию внутри самой функции подобно тому, как это делается в С++ для скалярных аргументов:
function makecoffee ($type = "cappucino") { return "Making a cup of $type.\n";
}
echo makecoffee ();
echo makecoffee ("espresso");
Этот код выведет такой ответ (рис. 7.4):
Making a cup of cappucino.
Making а сир of espresso.
function foo $bar .=
)
$ s tr = 'This foo ($str); echo $str; foo (& $ s tr) ; echo $str;
Значением по умолчанию должна быть константа, а не, например, переменная или экземпляр класса.
При задании аргументов по умолчанию следует помнить, что все значения аргументов, задаваемые по умолчанию, должны быть описаны справа по отношению к тем аргументам, для которых не указываются значения по умолчанию. В противном случае программа не будет работать таким образом, как задумано. Вот пример:
function makeyogurt 4$type = "acidophilus", $flavour) { return "Making a bowl of $type $ flavour.\n";
}
echo makeyogurt ("rasberry"); // не будет работать как положено
Этот пример выведет примерно такой результат (рис. 7.5):
Warning: Missing argument 2 in call to makeyogurt () in functest.html on line 41 Making a bowl of rasberry .
Сравним предыдущий пример со следующим:
function makeyogurt ($flavour, $type = "acidophilus") { return "Making a bowl of $type $flavour.\n";
}
echo makeyogurt ("rasberry");
// работает так, как и предоплагалось
Результат работы будет выглядеть так (рис. 7.6): Making a bowl of acidophilus raspberry.
Список аргументов переменной длины
В РНР4 список аргументов может состоять из переменного числа аргументов, размещенных в списке. Для работы со списками аргументов переменной длины удобно использовать функции func_num_args(), func_get_arg(), fiinc_get_args(). Для создания функций со списком аргументов переменной длины нет специальных правил, функции определяются так же, как и обычно.
Значения, возвращаемые функцией
Значение может быть возвращено функцией, для этого может быть использован оператор return. Функция может возвращать значения любого типа, включая списки объектов.
function square ($num) { return $num * $num;
}
echo square (4); // outputs 46'.
Функция не может возвратить несколько значений одновременно, однако, можно возвратить список значений, и это во многом подобно тому, как если бы было возвращено несколько значений сразу.
function small_numbers() {
return array (0, 1, 2);
}
list ($zero, $one, $two) = small_numbers();
Чтобы функция могла возвратить указатель, расположенный внутри функции, необходимо использовать оператор ссылки & как в опи-
сании функции, так и в том месте, где возвращаемое значение присваивается переменной:
function &returns_reference() { return &$someref;
}
$newref = &returns reference();
old Junction
Выражение old_function позволяет создавать функции с использованием старого синтаксиса PHP/FI2, при этом слово functiuon следует заменить словом old_function.
Переменные функции
В РНР поддерживаются переменные функции. Это значит то, что если в скрипте встречается переменная, за которой следуют скобки, то РНР произведет поиск функции с именем, равным тому, к чему может быть приведено значение упомянутой переменной, после чего будет предпринята попытка выполнить эту функцию. Такое поведение может быть использовано для создания повторных обращений к функции, использования таблиц функций и т.п. Вот пример:
<?php
function foo() {
echo "In foo()<br>\n";
}
function bar( $arg = ' ' ) {
echo "In bar(); argument was ' $arg'.<br>\n" ;
}
$func = 1foo ' ;
$func () ;
$func = ' bar' ;
$func( 'test' ) ;
?>
Результат выполнения файла показан на рис. 7.7.