Информация, полученная с помощью 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 languageJavaScript» RUNATServer»>. В последнем случае атрибут RUNAT содержит значение, соответствующее тому, что скрипт предназначен для выполнения на сервере. Однако в настоя­щем пособии мы не будем останавливаться на вопросах создания ASP файлов.

 

Глава 6

 

ОСНОВНЫЕ ЭЛЕМЕНТЫ ЯЗЫКА

Базовые элементы

Типы

Переменные

Константы

Инструкции

 

Язык РНР основан на известных языках программирования, таких как С, 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 typeimage»>:

<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. */

 

В начале этого раздела мы предпололжили, что практически все описываемые нами типы инструкций являются выражениями. Однако, строго говоря, не каждое выражение является инструкцией. Если вы­ражение состоит из нескольких элементов, разделенных одним или несколькими значками точки с запятой, то такое выражение не может считаться инструкцией, однако, составные части такого выражения по-прежнему являются инструкциями. Выражение в целом не является инструкцией,, поскольку оно не имеет одного определенного значения. Каждая отдельная инструкция, входящая в такое выражение, имеет значение, и для всего выражения в целом таких значений может быть несколько.

 

 

Глава 7

 

УПРАВЛЕНИЕ ХОДОМ ВЫПОЛНЕНИЯ ПРОГРАММЫ

Операторы

Арифметические операторы

Операторы присваивания

Побитовые операторы

Операторы сравнения

Операторы управления ошибками

Операторы выполнения системных команд

Операторы увеличения и уменьшения на единицу

Логические операторы

Иерархия операторов

Операторы для работы со строками

Управление последовательностью выполнения инструкций

Функции

Функции, определяемые пользователем Аргументы функции Возвращаемые значения Ключевое слово 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 In­break; 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.