Файл: www/ycheb/php_teach/02.php
Строк: 292
<?php
include '../../config.php';
$title='Учебник PHP';
aut();
head();
?>
<html><head>
<title>Учебник PHP, Глава 2</title>
<meta http-equiv="Content-type" content="text/html; charset=Windows-1251">
</head>
<DIV class=infotxt>
<LI><A href="#a">Глава 2. Переменные и типы
данных </A>
<UL>
<LI><A href="#b">Целые числа </A>
<LI><A href="#c">Восьмеричная и
шестнадцатеричная запись </A>
<LI><A href="#d">Вещественные числа </A>
<UL>
<LI><A href="#e">Стандартная запись</A>
<LI><A href="#f">Научная запись</A>
</LI></UL>
<LI><A href="#g">Строковые значения </A>
<UL>
<LI><A href="#h">Строковое
присваивание</A>
<LI><A href="#i">Синтаксис встроенной
документации</A>
<LI><A href="#j">Обращение к отдельным
символам строк</A> </LI></UL>
<LI><A href="#k">Массивы </A>
<UL>
<LI><A href="#l">Одномерные
индексируемые массивы</A>
<LI><A href="#m">Одномерные
ассоциативные массивы</A>
<LI><A href="#n">Многомерные
индексируемые массивы</A>
<LI><A href="#o">Многомерные
ассоциативные массивы</A>
<LI><A href="#p">Смешанное
индексирование</A> </LI></UL>
<LI><A href="#q">Объекты</A>
<LI><A href="#r">Логические
величины(истина/ложь)</A>
<LI><A href="#s">Идентификаторы</A>
<LI><A href="#t">Переменные </A>
<UL>
<LI><A href="#u">Объявление
переменных</A>
<LI><A href="#v">Область видимых
переменных</A>
<LI><A href="#w">Статические
переменные</A> </LI></UL>
<LI><A href="#x">Переключение типов</A>
<LI><A href="#y">Преобразование типов</A>
<LI><A href="#z">Присваивание </A>
<UL>
<LI><A href="#aa">Присваивание по
значению</A>
<LI><A href="#bb">Присваивание по
ссылке</A> </LI></UL>
<LI><A href="#cc">Переменные в
переменных</A>
<LI><A href="#dd">Стандартные
переменные</A>
<LI><A href="#ee">Константы</A>
<LI><A href="#ff">Итоги</A> </LI></UL>
<UL></UL><A name=a></A>
<P> </P>
<P>Глава 2</P>
<P>Переменные и типы данных</P>
<P>Типы данных составляют основу любого языка программирования и являются
средством, с помощью которого программист представляет разные типы
информации. В РНР поддерживаются шесть основных типов данных:</P>
<UL>
<LI>целые числа;
<LI>вещественные числа;
<LI>строки;
<LI>массивы;
<LI>объекты;
<LI>логические величины. </LI></UL>
<P>Одним из столпов любого языка программирования является поддержка
числовых данных. В РНР поддерживаются как целые, так и вещественные числа
(двойной точности). Разные числовые форматы подробно описываются в
следующих разделах.</P>
<P><A href="http.html://doks.gorodok.net/0" name=b></A>Целые числа</P>
<P>Целое число не имеет дробной части и представляется последовательностью
из одной или нескольких цифр. Примеры целых чисел:</P>
<P>5</P>
<P>591</P>
<P>52</P>
<P><A name=c></A>Восьмеричная и шестнадцатеричная запись</P>
<P>В РНР поддерживается запись целых чисел в восьмеричной (по основанию 8)
и шестнадцатеричной (по основанию 16) системах счисления. Восьмеричные
числа начинаются с цифры 0, после которой следует серия цифр от 0 до 7.
Примеры:</P>
<P>0422</P>
<P>0534</P>
<P>Шестнадцатеричные целые числа имеют префикс 0х или 0Х и могут состоять
из цифр от 0 до 9 и букв от а (А) до f (F). Примеры:</P>
<P>0x3FF</P>
<P>0x22abc</P>
<P><A name=d></A>Вещественные числа</P>
<P>Вещественные числа (числа с плавающей точкой) отличаются от целых
наличием дробной части. Они используются для представления значений,
требующих повышенной точности, — например, температур или денежных
величин. В РНР поддерживаются два вещественных формата: стандартная и
научная (экспоненциальная) запись.</P>
<P><A name=e></A>Стандартная запись</P>
<P>Стандартная запись удобна для представления типичных вещественных чисел
— скажем, денежных величин. Примеры:</P>
<P>12.45</P>
<P>98.6</P>
<P><A name=f></A>Научная запись</P>
<P>Научная запись лучше подходит для представления очень больших и очень
малых чисел — скажем, межпланетных расстояний или размеров атомов.
Примеры:</P>
<P>Зе8</P>
<P>5.9736е24</P>
<P><A name=g></A>Строковые значения</P>
<P>Строкой (string) называется последовательность символов, которая
рассматривается как единое целое, но при этом обеспечивает доступ к
отдельным символам. Примеры строк:</P>
<P>thesaurus</P>
<P>49ers</P>
<P>abc</P>
<P>&%/$#</P>
<P>Обратите внимание: в РНР не поддерживается символьный тип данных.
Строковый тип может рассматриваться как единое представление для
последовательностей, состоящих из одного или нескольких символов.</P>
<P><A href="http.html://doks.gorodok.net/996" name=h></A>Строковое
присваивание</P>
<P>Строки делятся на две категории в зависимости от типа ограничителя —
они могут ограничиваться парой кавычек (" ") или апострофов (' '). Между
этими категориями существуют два принципиальных различия. Во-первых, имена
переменных в строках, заключенных в кавычки, заменяются соответствующими
значениями, а строки в апострофах интерпретируются буквально, даже если в
них присутствуют имена переменных,</P>
<P>Два следующих объявления дают одинаковый результат:</P>
<P>$food = "meatloaf";</P>
<P>$food = 'meatloaf';</P>
<P>Однако результаты следующих объявлений сильно различаются:</P>
<P>$sentence = "My favorite food is $food";</P>
<P>$sentence2 = 'My favorite food is $food';</P>
<P>Переменной $sentence присваивается строка</P>
<P>My favorite food is meatloaf.</P>
<P>Обратите внимание: переменная $food автоматически интерпретируется. С
другой стороны, переменной $sentence2 присваивается строка</P>
<P>My favorite food is $food.</P>
<P>В отличие от переменной $sentence, в $sentence2 осталась не
интерпретированная переменная $food. Различия обусловлены использованием
кавычек и апострофов при присваивании переменным $sentence и
$sentence2.</P>
<P>Прежде чем рассматривать второе фундаментальное различие между
строками, заключенными в апострофы и в кавычки, необходимо познакомиться
со служебными символами, используемыми в строках РНР. В РНР, как и в
большинстве современных языков программирования, строки могут содержать
служебные символы (например, символы табуляции или новой строки),
перечисленные в табл. 2.1.</P>
<P>Таблица 2.1. Служебные символы в строках</P>
<P>
<TABLE width="100%" border=1>
<TBODY>
<TR>
<TD width=127>Последовательность </TD>
<TD width=333>
<P align=center>Смысл </P></TD></TR>
<TR>
<TD align=middle width=127>n</TD>
<TD width=333>Новая строка</TD></TR>
<TR>
<TD align=middle width=127> r</TD>
<TD width=333>Возврат курсора</TD></TR>
<TR>
<TD align=middle width=127> t</TD>
<TD width=333>Горизонтальная табуляция</TD></TR>
<TR>
<TD align=middle width=127>\</TD>
<TD width=333>Обратная косая черта</TD></TR>
<TR>
<TD align=middle width=127> $</TD>
<TD width=333>Знак доллара</TD></TR>
<TR>
<TD align=middle width=127>"</TD>
<TD width=333>Кавычка</TD></TR>
<TR>
<TD align=middle width=127>[0-7]{1,3}</TD>
<TD width=333>Восьмеричная запись числа (в виде регулярного
выражения)</TD></TR>
<TR>
<TD align=middle width=127> x[0-9A-Fa-f]{l,2}</TD>
<TD width=333>Шестнадцатиричная запись числа (в виде регулярного
выражения)</TD></TR></TBODY></TABLE></P>
<P>Второе принципиальное различие заключается в том, что в строках,
заключенных в кавычки, распознаются все существующие служебные символы, а
в строках, заключенных в апострофы, — только служебные символы «\» и «».
Следующий пример наглядно демонстрирует различия между присваиванием
строк, заключенных в кавычки и апострофы:</P>
<P>$double_list = "item1nitem2nitem2";</P>
<P>$single_list = 'item1nitem2nitem2';</P>
<P>Если вывести обе строки в браузере, окажется, что строка в кавычках
содержит внутренние символы новой строки, а в строке в апострофах
последовательность n выводится как обычные символы. Хотя многие служебные
символы в браузерах несущественны, при форматировании для других условий
они играют очень важную роль. Помните об этом, выбирая между кавычками и
апострофами, и вам удастся избежать многих неожиданностей.</P>
<P><A name=i></A>Синтаксис встроенной документации</P>
<P>Второй вариант синтаксиса ограничения строк, представленный в HTML4,
называется встроенной документацией (here doc). В этом варианте синтаксиса
строка начинается с символов <<<, за которыми следует некоторый
идентификатор по вашему выбору, затем строка, присваиваемая переменной.
Конструкция заканчивается вторым экземпляром того же идентификатора.
Пример:</P>
<P>$paragraph = <<<DELIM</P>
<P>This is a string that</P>
<P>Will be interpreted exactly</P>
<P>As it is written in the</P>
<P>variable assignment,</P>
<P>DELIM;</P>
<P>Выбранный идентификатор не должен присутствовать в присваиваемой
строке. Более того, первый символ завершающего идентификатора должен
находиться в первом столбце строки, завершающей конструкцию.</P>
<P><A name=j></A>Обращение к отдельным символам строк</P>
<P>К отдельным символам строки можно обращаться как к элементам массива с
последовательной нумерацией (см. следующий раздел). Пример:</P>
<P>$sequence_number = "04efgh";</P>
<P>$letter = Ssequence_number[4];</P>
<P>Переменной $ letter будет присвоено значение g. Как вы узнаете из
следующего раздела, в РНР нумерация элементов массивов начинается с 0.
Соответственно, выражение $sequence_number[l] будет равно 4.</P>
<P><A name=k></A>Массивы</P>
<P>Массив представляет собой список однотипных элементов. Существует два
типа массивов, различающиеся по способу идентификации элементов. В
массивах первого типа элемент определяется индексом в последовательности.
Массивы второго типа имеют ассоциативную природу, и для обращения к
элементам используются ключи, логически связанные со значениями. Впрочем,
на практике операции с массивами обоих типов выполняются сходным образом.
По размерности массивы делятся на одномерные и многомерные.</P>
<P><A name=l></A>Одномерные индексируемые массивы</P>
<P>При обращении к элементам одномерных индексируемых массивов
используется целочисленный индекс, определяющий позицию заданного
элемента.</P>
<P>Обобщенный синтаксис элементов одномерного массива:</P>
<P>$имя[индекс1];</P>
<P>Одномерные массивы создаются следующим образом:</P>
<P>$meat[0] = "chicken";</P>
<P>$meat[l] = "steak";</P>
<P>$meat[2] = "turkey";</P>
<P>При выполнении следующей команды:</P>
<P>print $meat[1]:</P>
<P>в браузере выводится строка</P>
<P>steak</P>
<P>При создании массивов также можно воспользоваться функцией array ().
Массив $meat из предыдущего примера создается командой</P>
<P>$meat = аrrау("chicken", "steak", "turkey");</P>
<P>Приведенная выше команда pri nt приводит к тому же результату — выводу
строки steak.</P>
<P>Чтобы включить новый элемент в конец массива, можно просто присвоить
значение переменной массива без указания индекса. Следовательно, массив
$meat можно создать еще одним способом:</P>
<P>Smeat[] = "chicken";</P>
<P>$meat[] = "steak";</P>
<P>Smeat[] = "turkey";</P>
<P><A name=m></A>Одномерные ассоциативные массивы</P>
<P>Ассоциативные массивы особенно удобны в ситуациях, когда элементы
массива удобнее связывать со словами, а не с числами.</P>
<P>Предположим, вы хотите сохранить в массиве лучшие сочетания вин и блюд.
Проще всего было бы хранить в массиве пары «ключ/значение» — например,
присвоить сорт вина названию блюда. Самым разумным решением будет
использование ассоциативного массива:</P>
<P>Spairings["zinfandel"] = "Broiled Veal Chops";</P>
<P>$pairings["merlot"] = "Baked Ham";</P>
<P>$pairings["sauvignon"] = "Prime Rib";</P>
<P>$pairings["sauternes"] = "Roasted Salmon";</P>
<P>Ассоциативный массив заметно экономит время и объем программного кода,
необходимого для вывода определенных элементов массива. Допустим, вы
хотите узнать, с каким блюдом лучше всего идет «Мерло». Нужная информация
выводится простой ссылкой на элемент массива $pairings: print
$pairings["merlot"]; // Выводится строка "Baked Ham" Ассоциативные массивы
также можно создавать функцией РНР аггау():</P>
<P>Spairings = аrrау(</P>
<P>zinfandel => "Broiled Veal Chops",</P>
<P>merlot => "Baked Ham",</P>
<P>sauvignon => "Prime Rib",</P>
<P>sauternes => "Roasted Salmon");</P>
<P>Отличается только способ создания массива pairings, а функциональные
возможности остаются без изменений.</P>
<P><A name=n></A>Многомерные индексируемые массивы</P>
<P>Многомерные индексируемые массивы работают практически так же, как и их
одномерные прототипы, однако элементы в них определяются несколькими
индексами вместо одного. Теоретически размерность индексируемого массива
не ограничивается, хотя в большинстве приложений практически не
встречаются массивы с размерностью выше 3.</P>
<P>Обобщенный синтаксис элементов многомерного массива:</P>
<P>$имя[индекс1][индекс2]..[индексN];</P>
<P>Пример ссылки на элемент двухмерного индексируемого массива:</P>
<P>$position = $chess_board[5][4];</P>
<P><A href="http.html://doks.gorodok.net/19587" name=o></A>Многомерные
ассоциативные массивы</P>
<P>Многомерные ассоциативные массивы также существуют в РНР (и приносят
определенную пользу). Допустим, в массиве $раirings из предыдущего примера
должна храниться информация не только о сорте, но и о производителе вина.
Это можно сделать следующим образом:</P>
<P>$pairings["Martinelli"]["zinfandel"] = "Broiled Veal Chops";</P>
<P>$pairings["Beringer"]["merlot"] = "Baked Ham";</P>
<P>$pairings["Jarvis"]["sauvignon"] = "Prime Rib";</P>
<P>$pairings["Climens"]["sauternes"] = "Roasted Salmon";</P>
<P><A name=p></A>Смешанное индексирование</P>
<P>В многомерных массивах допускается смешанное индексирование (числовое и
ассоциативное). Допустим, вы хотите расширить модель одномерного
ассоциативного массива для хранения информации об игроках первого и
второго состава футбольной команды. Решение может выглядеть следующим
образом:</P>
<P>$Buckeyes["quarterback"] [1] = "Bellisari";</P>
<P>$Buckeyes["quarterback"] [2] = "Moherman":</P>
<P>$Buckeyes["quarterback"] [3] = "Wiley";</P>
<P>В РНР существует множество функций для создания массивов и операций с
ними — эта тема настолько обширна, что заслуживает отдельной главы. Работа
с массивами в РНР подробно описана в главе 13.</P>
<P><A name=q></A>Объекты</P>
<P>К пятому типу данных РНР относятся объекты. Объект представляет собой
переменную, экземпляр которой создается по специальному шаблону,
называемому классом. Концепции объектов и классов являются неотъемлемой
частью парадигмы объектно-ориентированного программирования (ООП).</P>
<P>В отличие от других типов данных, поддерживаемых в языке РНР, объекты
должны объявляться явно. Необходимо понимать, что объект — всего лишь
конкретный экземпляр класса, используемого в качестве шаблона для создания
объектов с конкретными характеристиками и функциональными возможностями.
Следовательно, объявление класса должно предшествовать объявлению
объектов, создаваемых на их основе. Пример объявления класса и
последующего создания объектов на его основе:</P>
<P>class appliance { </P>
<P>var power: </P>
<P>function set_power($on_off) { </P>
<P>$this->power = $on_off; </P>
<P>} </P>
<P>}</P>
<P>...</P>
<P>$blender = new appliance; </P>
<P>Определение класса задает атрибуты и функции, связанные с некоторой
структурой данных — в данном примере это структура с именем appliance
(устройство). У этой структуры имеется всего один атрибут power
(мощность). Для изменения этого атрибута создается метод set_power.</P>
<P>Помните: определение класса — всего лишь шаблон, и выполнять операции с
ним в программе невозможно; сначала нужно создать объекты на основе этого
шаблона. Объекты создаются при помощи ключевого слова new. Например, в
приведенном выше фрагменте создается объект $blender класса appliance.</P>
<P>После создания объекта $blender можно задать его мощность при помощи
метода</P>
<P>set_power: $blender->set_power("on");</P>
<P>Объектно-ориентированное программирование занимает столь важное место в
современных стандартах программирования, что его применение в РНР
заслуживает отдельной главы. Реализация ООП в РНР описана в главе 6.</P>
<P><A name=r></A>Логические величины (истина/ложь)</P>
<P>Логический тип данных принимает всего два значения: истинное (true) и
ложное (false). Логические величины создаются двумя способами: при
проверке условий и в виде значений переменных. Обе ситуации достаточно
просты.</P>
<P>Сравнения существуют в нескольких формах. Чаще всего они встречаются
при использовании оператора = в условной команде if. Пример:</P>
<P>if ($sum == 40) :</P>
<P>...</P>
<P>Результатом проверки является либо истина, либо ложь: переменная $sum
либо равна 40, либо не равна. Если переменная $sum равна 40, проверка дает
истинный результат. В противном случае результат равен false.</P>
<P>Логические величины также могут определяться явным присваиванием
переменной истинного или ложного значения. Пример:</P>
<P>$flag = TRUE;</P>
<P>if ($flag == TRUE) :</P>
<P>print "The flag is true!";</P>
<P>else :</P>
<P>print "The flag is false!";</P>
<P>endif;</P>
<P>Если переменная $flag истинна, выводится первое сообщение, а если ложна
— второе сообщение.</P>
<P>Возможен и другой вариант — представление истинных и ложных логических
величин в виде значений 1 и 0 соответственно. В этом случае предыдущий
пример выглядит так:</P>
<P>$flag = 1;</P>
<P>if ($flag == TRUE) ;</P>
<P>print "The flag is true!";</P>
<P>else :</P>
<P>print "The flag is false!";</P>
<P>endif;</P>
<P>Наконец, существует еще один способ:</P>
<P>$flag = TRUE: </P>
<P>// При выполнении этой команды косвенно </P>
<P>// проверяется условие "if ($flag == TRUE)" </P>
<P>if ($flag) :</P>
<P>print "The flag is true!"; </P>
<P>else :</P>
<P>print "The flag is false!"; </P>
<P>endif:</P>
<P><A name=s></A>Идентификаторы</P>
<P>Общий термин идентификатор применяется к переменным, функциям и другим
объектам, определяемым пользователем. Идентификаторы РНР должны
удовлетворять нескольким условиям:</P>
<P>Идентификатор состоит из одного или нескольких символов и начинается с
буквы или символа подчеркивания. Идентификатор может содержать только
буквы, цифры, символы подчеркивания и другие ASCII-символы с кодами от 127
до 255. Примеры:</P>
<P>
<TABLE border=1 width="100%">
<TBODY>
<TR>
<TD width=250>Допустимые идентификаторы</TD>
<TD width=250>
<P align=left>Недопустимые идентификаторы</P></TD></TR>
<TR>
<TD width=114>
<P>my_function</P></TD>
<TD width=178>
<P align=left>This&that</P></TD></TR>
<TR>
<TD width=114>Size</TD>
<TD width=178>!counter</TD></TR>
<TR>
<TD width=114>_someword</TD>
<TD width=178>4ward</TD></TR></TBODY></TABLE></P>
<P>В идентификаторах учитывается регистр символов. Следовательно,
переменная с именем $recipe отличается от переменных с именами $Recipe,
$rEciPe и $recipE.</P>
<P>Длина идентификаторов не ограничивается. Это удобно, поскольку
программист может точно описать смысл идентификатора в его имени.</P>
<P>Идентификатор не может совпадать с каким-либо из стандартных ключевых
слов РНР.</P>
<P><A href="http.html://doks.gorodok.net/0" name=t></A>Переменные</P>
<P>В примерах, приведенных выше, я попутно показал, как происходит
присваивание и изменение значений переменных. И все же стоит четко
сформулировать правила объявления переменных и выполнения операций с ними.
Ниже приводится подробное описание этих правил.</P>
<P><A name=u></A>Объявление переменных</P>
<P>Переменная представляет собой именованную область памяти, содержащую
данные, с которыми можно выполнять операции во время выполнения
программы.</P>
<P>Имена переменных всегда начинаются со знака доллара, $. Ниже приведены
примеры допустимых имен переменных:</P>
<P>$соlоr</P>
<P>$operating_system</P>
<P>$_some_variable</P>
<P>$model</P>
<P>Имена переменных должны соответствовать тем же условиям, что и
идентификаторы. Другими словами, имя переменной начинается с буквы или
символа подчеркивания и состоит из букв, символов подчеркивания, цифр или
других ASCII-символов в интервале от 127 до 255.</P>
<P>Следует заметить, что переменные в РНР, как и в языке Perl, не требуют
специального объявления. Вместо этого переменная объявляется при первом ее
использовании в программе. Более того, тип переменной косвенно
определяется по типу хранящихся в ней данных. Рассмотрим следующий
пример:</P>
<P>$sentence = "This is a sentence."; // $sentence интерпретируется как
строка</P>
<P>$price = 42.99: // $price интерпретируется как вещественное число</P>
<P>$weight = 185; // $weight интерпретируется как целое число</P>
<P>Переменные могут объявляться в любой точке сценария РНР, однако от
расположения объявления зависит то, откуда можно обращаться к данной
переменной.</P>
<P><A name=v></A>Область видимости переменных</P>
<P>Область видимости (scope) определяется как область доступности
переменной в той программе, в которой она была объявлена. В зависимости от
области видимости переменные РНР делятся на четыре типа:</P>
<UL>
<LI> локальные переменные;
<LI>параметры функций;
<LI>глобальные переменные;
<LI>статические переменные. </LI></UL>
<P>Локальные переменные</P>
<P>Переменная, объявленная внутри функции, считается локальной; другими
словами, на нее можно ссылаться только в этой функции. При любом
присваивании вне функции будет использоваться совершенно другая
переменная, которая не имеет ничего общего (кроме имени) с переменной,
объявленной внутри функции. При выходе из функции, в которой была
объявлена локальная переменная, эта переменная и ее значение
уничтожаются.</P>
<P>Основное достоинство локальных переменных — отсутствие непредвиденных
побочных эффектов, связанных со случайной или намеренной модификацией
глобальной переменной. Рассмотрим следующий пример:</P>
<P>$х = 4; </P>
<P>function assignx () { </P>
<P>$х = 0;</P>
<P>print "$x inside function is $x. <br>";</P>
<P>}</P>
<P>assignx(); </P>
<P>print "$x outside of function is $x. <br>";</P>
<P>При выполнении этого фрагмента выводится следующий результат: </P>
<P>$х inside function is 0. </P>
<P>$х outside of function is 4. </P>
<P>Как видите, программа выводит два разных значения переменной $х. Дело в
том, что переменная $х внутри функции assignx имеет локальную природу, и
изменение ее значения никак не отражается на значении, существующем за
пределами этой функции. Справедливо и обратное — модификация $х за
пределами функции никак не отражается на локальных переменных функции
assignx().</P>
<P>Параметры функций</P>
<P>В РНР, как и во многих других языках программирования, любые параметры,
передаваемые функции при вызове, должны быть объявлены в заголовке
функции. Хотя параметрам присваиваются аргументы, переданные извне, после
выхода из функции они становятся недоступными.</P>
<P>Параметры объявляются в круглых скобках после имени функции. Объявление
параметров практически не отличается от объявления типичной
переменной:</P>
<P>// Функция умножает переданное значение на 10 и возвращает
результат</P>
<P>function x10 ($value) {</P>
<P>$value = $value * 10;</P>
<P>return $value;</P>
<P>}</P>
<P>Хотя вы можете обращаться к параметрам в той функции, в которой они
были объявлены, и выполнять с ними необходимые операции, после завершения
функции параметры уничтожаются.</P>
<P>Глобальные переменные</P>
<P>Глобальные переменные, в отличие от локальных, доступны в любой точке
программы. Но чтобы изменить значение глобальной переменной, необходимо
специально объявить ее как глобальную в соответствующей функции. Для этого
перед именем переменной ставится ключевое слово GLOBAL. Пример:</P>
<P>$somevar = 15;</P>
<P>function addit() { </P>
<P>GLOBAL $somevar; </P>
<P>$somevar++; </P>
<P>print "Somevar is $somevar"; </P>
<P>} </P>
<P>addit(); </P>
<P>Будет выведено значение $somevar, равное 16. Допустим, вы забыли
включить следующую строку:</P>
<P>GLOBAL $somevar;</P>
<P>В этом случае $somevar будет присвоено значение 1, поскольку эта
переменная будет считаться локальной по отношению к функции addit( ).
Локальная переменная по умолчанию инициализируется 0, а затем к ней
прибавляется 1; таким образом, будет выведено значение 1.</P>
<P>Альтернативный способ объявления глобальных переменных связан с
использованием массива РНР $GLOBALS( ). Давайте вернемся к предыдущему
примеру и воспользуемся этим массивом для объявления глобальной переменной
$somevar: $somevar = 15;</P>
<P>function addit() { </P>
<P>$GLOBALS["somevar"]; </P>
<P>$somevar++; </P>
<P>}</P>
<P>addit();</P>
<P>print "Somevar is $somevar";</P>
<P>Каким бы способом ни обеспечивалась глобальная видимость переменной,
помните, что неосторожное использование глобальных переменных нередко
приводит к неожиданным результатам, причиняющим немало хлопот
программистам. Таким образом, хотя глобальные переменные очень удобны, при
их использовании необходима умеренность.</P>
<P><A href="http.html://doks.gorodok.net/996" name=w></A>Статические
переменные</P>
<P>Последний тип видимости переменных называется статическим. В отличие от
переменных, объявленных параметрами и уничтожаемых при выходе из функции,
статическая переменная сохраняет свое значение при повторном вызове. Для
объявления статической переменной перед ее именем ставится ключевое слово
STATIC: </P>
<P>STATIC $somevar; </P>
<P>Рассмотрим пример: </P>
<P>function keep_track() { </P>
<P>STATIC $count = 0; </P>
<P>$count++;</P>
<P>print $count;</P>
<P>print "<br>";</P>
<P>} </P>
<P>keep_track(); </P>
<P>keep_track(); </P>
<P>keep_track(); </P>
<P>Как будут выглядеть результаты работы этого сценария? Если бы
переменная $count не была объявлена статической (то есть являлась
локальной), результат выглядел бы так:</P>
<P>1 </P>
<P>1 </P>
<P>1 </P>
<P>Но поскольку переменная $count является статической, при каждом вызове
функции будет сохраняться ее предыдущее значение, поэтому результат будет
таким:</P>
<P>1 </P>
<P>2</P>
<P>3</P>
<P>Статические переменные особенно удобны при написании рекурсивных
функций — особого класса функций, которые многократно вызывают сами себя
до выполнения некоторого условия. Рекурсивные функции рассматриваются в
главе 4.</P>
<P><A name=x></A>Переключение типов</P>
<P>Иногда бывает удобно использовать переменные способами, не
предусмотренными при их создании. Допустим, вам захочется прибавить
строковое значение "15" к целому числу 12. К счастью, тип переменных РНР
может изменяться и без использования механизма явного преобразования. Этот
процесс, независимо от того, выполняется ли он прямо или косвенно,
называется переключением (juggling) типов. Лучше всего продемонстрировать
сказанное на конкретных примерах.</P>
<P>Предположим, вы суммируете две величины — строку и целое число. Как вы
думаете, что при этом произойдет? Результат зависит от содержимого строки.
Например, при суммировании целого числа со строковым представлением числа
будет получено целое число:</P>
<P>$variablel = 1;</P>
<P>$variable2 = "1";</P>
<P>$variable3 = $variablel + $variable2;</P>
<P>// $variable3 присваивается 4.</P>
<P>Другой пример переключения типов — суммирование целого числа с
вещественным. При этом целое число преобразуется к вещественному типу,
чтобы избежать потери точности:</P>
<P>$variablel = 3;</P>
<P>$variable2 = 5.4;</P>
<P>$variable3 = $variablel + $variable2;</P>
<P>// $variablel интерпретируется как вещественное число.</P>
<P>// и $variable3 присваивается 8.4.</P>
<P>Следует упомянуть о некоторых малоизвестных особенностях переключения
типов. Что произойдет при попытке суммирования целого числа и строки,
содержащей целое число, но не являющейся строковым представлением?
Рассмотрим следующий пример:</P>
<P>$variablel = 5;</P>
<P>$variable2 = "100 bottles of beer on the wall";</P>
<P>$variable3 = ;variable1 + $variable2;</P>
<P>// $variable3 присваивается 105</P>
<P>В результате переменной ;variable3 присваивается значение 105. Это
происходит из-за того, что лексический анализатор РНР определяет тип по
началу строки. Допустим, мы привели переменную $variable2 к виду "There
are 100 bottles of beer on the wall". Поскольку алфавитные символы трудно
интерпретировать как целое число, строка интерпретируется как 0, и
переменной $variable3 присваивается 5.</P>
<P>Хотя в большинстве случаев переключение типов обеспечивает желаемый
результат, существует способ явного приведения переменных к конкретному
типу. Эта тема рассматривается в следующем разделе.</P>
<P><A name=y></A>Преобразование типов</P>
<P>Явное приведение переменной к типу, отличному от того, который
изначально предназначался для нее, называется преобразованием (casting)
типа. Изменение типа может быть как временным, одноразовым, так и
постоянным.</P>
<P>Чтобы временно привести переменную к другому типу, достаточно
воспользоваться оператором преобразования типа — указать нужный тип перед
именем переменной в круглых скобках (табл. 2.2).</P>
<P>Таблица 2.2. Операторы преобразования типа переменных</P>
<P>
<TABLE width="100%" border=1>
<TBODY>
<TR>
<TD width=250>Оператор преобразования типа</TD>
<TD width=153>Новый тип</TD></TR>
<TR>
<TD width=231> (int) или (integer)</TD>
<TD width=150>Целое число</TD></TR>
<TR>
<TD width=231>(real), (double) или (float)</TD>
<TD width=153>Вещественное число</TD></TR>
<TR>
<TD width=231>(string)</TD>
<TD width=153>Строка</TD></TR>
<TR>
<TD width=231>(array)</TD>
<TD width=160>Массив</TD></TR>
<TR>
<TD width=231>(object)</TD>
<TD width=153>Объект</TD></TR></TBODY></TABLE></P>
<P>Простой пример преобразования типов: </P>
<P>$variable1= 13; // $variable1 присваивается целое число 13</P>
<P>$variable2 = (double) $variable1; // $variable2 присваивается 13.0</P>
<P>Хотя переменная $variable1 первоначально содержала целое число 13,
преобразование (double) преобразует ее к вещественному типу (поэтому число
13 превращается в 13.0). Полученное значение присваивается переменной
$variable2.</P>
<P>Из предыдущего раздела вы знаете, что при суммировании целого числа с
вещественным получается вещественный результат. Однако тип результата
можно изменить посредством явного преобразования типа:</P>
<P>$variablel = 4.0;</P>
<P>$variable2 = 5;</P>
<P>$variable3 = (int) $variable1 + $variable2; // $variable3 = 9</P>
<P>Следует заметить, что преобразование вещественного типа к целому всегда
сопровождается округлением:</P>
<P>$variablel = 14.7:</P>
<P>$variable2 = (int) $varlable1; // $variable2 = 14:</P>
<P>Строку или переменную другого типа также можно преобразовать в элемент
массива. В этом случае преобразованная переменная становится первым
элементом массива:</P>
<P>$variable1 = 1114;</P>
<P>$array1 = (array) $varable1;</P>
<P>print $array1[0]; // Выводится значение 1114</P>
<P>Наконец, любой тип данных можно преобразовать в объект. Переменная
становится атрибутом объекта, и ей присваивается имя scalar:</P>
<P>$model = "Toyota";</P>
<P>$new_obj = (object) $model;</P>
<P>Ссылка на исходное строковое значение выглядит так:</P>
<P>print $new_obj->scalar;</P>
<P><A name=z></A>Присваивание</P>
<P>Вы уже знаете, как присвоить значение переменной в сценарии РНР. Тем не
менее, некоторые тонкости, связанные с присваиванием, стоит выделить
особо. Вероятно, вам хорошо знаком механизм присваивания по значению, при
котором именованной переменной присваивается конкретное значение —
например, целое число 1 или строка "ciao". Однако существует и второй
механизм — присваивание по ссылке, также открывающее перед программистами
немало полезных возможностей. В следующих разделах оба механизма
рассматриваются более подробно.</P>
<P><A name=aa></A>Присваивание по значению</P>
<P>Это самый распространенный способ присваивания, при котором значение
просто заносится в область памяти, представленную именем переменной.
Примеры присваивания по значению:</P>
<P>$vehicle = "car"; </P>
<P>$amount =10.23; </P>
<P>В результате выполнения этих двух команд по адресу памяти,
представленному именем $vehicle, сохраняется строка "car", а по адресу,
представленному именем $amount, — значение 10.23.</P>
<P>Присваивание по значению также может выполняться в результате
выполнения команды return в функциях:</P>
<P>function simple () {</P>
<P>return 5;</P>
<P>}</P>
<P>$return_value = simple();</P>
<P>Функция simple( ) всего лишь возвращает значение 5, которое
присваивается некоторой переменной. В данном примере значение 5 будет
присвоено переменной $return_value. </P>
<P><A name=bb></A>Присваивание по ссылке</P>
<P>Другой способ заключается в присваивании переменной ссылки на область
памяти, занимаемую другой переменной. Вместо конкретного значения
переменная-приемник связывается с указателем (или ссылкой) на область
памяти, поэтому фактическое копирование не выполняется.</P>
<P>Чтобы присвоить значение по ссылке, укажите перед именем
переменной-источника символ & (амперсанд):</P>
<P>$dessert = "cake";</P>
<P>$dessert2 = $Sdessert;</P>
<P>$dessert2 = "cookies";</P>
<P>print "$dessert2 <br>"; // Выводится строка cookies</P>
<P>print Sdessert; // Снова выводится строка cookies</P>
<P>Как видно из приведенного фрагмента, после связывания переменной
$dessert2 со ссылкой на область памяти, занимаемую переменной $dessert,
любые изменения $dessert2 приводят к автоматической модификации $dessert
(и всех остальных переменных, ссылающихся на эту же область памяти).</P>
<P><A name=cc></A>Переменные в переменных</P>
<P>В некоторых ситуациях бывает удобно использовать переменные, содержимое
которых может динамически интерпретироваться как имя другой переменной.
Рассмотрим типичный случай присваивания:</P>
<P>$recipe = "spaghetti";</P>
<P>Оказывается, строку "spaghetti" можно интерпретировать как имя
переменной — для этого в команде присваивания перед именем исходной
переменной ставится второй знак $:</P>
<P>$$recipe = "& meatballs";</P>
<P>Эта команда присваивает строку "& meatballs" переменной с именем
"spaghetti". Следовательно, следующие две команды выводят одинаковые
результаты:</P>
<P>print $recipe $spaghetti;</P>
<P>print $recipe $($recipe);</P>
<P>В обоих случаях будет выведена строка "spaghetti & meatballs".</P>
<P><A name=dd></A>Стандартные переменные</P>
<P>В РНР поддерживается ряд стандартных переменных, предоставляющих в
распоряжение программиста довольно подробную информацию о внутренней
конфигурации. Значения одних переменных задаются РНР, другие изменяются в
зависимости от операционной системы и web-сервера, с которыми работает
РНР.</P>
<P>Вместо подробного описания всех стандартных переменных я выделю лишь те
переменные и функции, которые используются на практике многими
программистами.</P>
<P>Чтобы получить полный список переменных web-сервера, окружения и РНР,
определенных для вашей конфигурации системы, достаточно выполнить
следующий фрагмент:</P>
<P>while (list($var,$value) = each($GLOBALS)) :</P>
<P>echo "<BR>$var => $value";</P>
<P>endwhile;</P>
<P>В результате выводится список наподобие приведенного ниже. Потратьте
немного времени на просмотр полученных данных, а затем разберите
приведенные примеры.</P>
<P>GLOBALS =></P>
<P>HTTP_GET_VARS => Array </P>
<P>HTTP_COOKIE_VARS => Array </P>
<P>HOSTSIZE => 1000 </P>
<P>HOSTNAME => server1.apress.com </P>
<P>LOGNAME => unstrung </P>
<P>HISTFILESIZE => 1000 </P>
<P>REMOTEHOST => apress.com </P>
<P>MAIL -> /var/spool/mail/apress </P>
<P>MACHTYPE => 1386 </P>
<P>TERM => vt100 </P>
<P>HOSTTYPE => i386-linux </P>
<P>PATH => </P>
<P>/usr/sbin:/sbin:/usr/local
/bin:/bin:/usr/bin:/usr/X11R6/bin:/usr/local/Java/bin </P>
<P>HOME => /root </P>
<P>INPUTRC => /etc/inputrc </P>
<P>SHELL => /bin/csh </P>
<P>USER => nobody </P>
<P>VENDOR => intel </P>
<P>GROUP => root </P>
<P>HOST => server1.apress.com </P>
<P>OSTYPE => linux </P>
<P>PWD => /www/bin </P>
<P>SHLVL => 3_ => /www/bin/httpd </P>
<P>DOCUMENT_ROOT => /usr/local/apress/site.apress </P>
<P>HTTP_ACCEPT => */* </P>
<P>HTTP_ACCEPT_ENCODING => gzip, deflate </P>
<P>HTTP_ACCEPT_LANGUAGE => it.en-us;q=0.5 </P>
<P>HTTP_CONNECTION -> Keep-Alive </P>
<P>HTTP_HOST => www.apress.com </P>
<P>HTTP_USER_AGENT => Mozilla/4.0 (compatible; MSIE 5.0: Windows 98;
</P>
<P>CNETHomeBuild051099) </P>
<P>REMOTE_ADOR => 127.0.0.1 </P>
<P>REMQTE_PORT => 3207 </P>
<P>SCRIPT_FILENAME =>
/usr/local/apress/site.apress/j/environment_vars.php </P>
<P>SERVER_ADDR => 127.0.0.1 </P>
<P>SERVER_AOMIN => admin@apress.com </P>
<P>SERVER_NAME => www.apress.com </P>
<P>SERVERJORT => 80 </P>
<P>SERVER SIGNATURE => </P>
<P>Apache/1.3.12 Server at www.apress.com Port 80 </P>
<P>SERVER_SOFTWARE => Apache/1.3.12 (Unix) PHP/4.0.1 </P>
<P>GATEWAY_INTERFACE => CGI/1.1 </P>
<P>SERVER_PROTOCOL => HTTP/1.1 </P>
<P>REQUEST_METHOD => GET </P>
<P>QUERY_STRING => </P>
<P>REQUEST_URI => /j/environment_vars.php </P>
<P>SCRIPT_NAME => /j/environment_vars.php </P>
<P>PATH_TRANSLAETD =>
/usr/local/apress/site.apress/j/environment_vars.php </P>
<P>PHP_SELF => /j/environment_vars.php </P>
<P>argv => Array </P>
<P>argc => 0 </P>
<P>var => argc </P>
<P>value => argc </P>
<P>Как видите, стандартные переменные содержат разнообразные сведения —
как полезные, так и не очень. Вы можете вывести любую из этих переменных
по имени. Например, следующая команда выводит IP-адрес пользователя:</P>
<P>print "Hi! Your IP address is: $REMOTE_ADDR";</P>
<P>IP-адрес выводится в числовой форме (например, 208.247.106.187).</P>
<P>Кроме того, стандартные переменные могут использоваться для сбора
информации о браузере и операционной системе пользователя. Команда</P>
<P>print "Your browser is: $HTTP_USER_AGENT";</P>
<P>возвращает информацию следующего вида:</P>
<P>Your browser is: Mozina/4.0 (compatible: MSIE 5.0; Windows 98:
CNETHomeBuild051099)</P>
<P>Информация о браузере и операционной системе, в которой он работает,
может пригодиться при построении страниц, рассчитанных на специфические
форматы конкретных браузеров.</P>
<P>Для работы с массивами стандартных переменных необходимо включить
директиву track_vars в файл php.ini. В РНР версии 4.0.3 директива
track_vars включена постоянно.</P>
<P><A name=ee></A>Константы</P>
<P>Константой называется именованная величина, которая не изменяется в
процессе выполнения программы. Константы особенно удобны при работе с
заведомо постоянными величинами — например, числом π (3,141592) или
количеством футов в миле (5280).</P>
<P>В РНР константы определяются функцией define( ). После того как
константа будет определена, вы не сможете изменить (или переопределить) ее
в этой программе.</P>
<P>Например, определение числа я в сценарии РНР может выглядеть так:</P>
<P>define("'PI", "3.141592"); </P>
<P>Определенную константу можно использовать в программе:</P>
<P>print "The value of pi is". PI."<br>";</P>
<P>$pi2 - 2 * PI:</P>
<P>print "Pi doubled equals $pi2.";</P>
<P>Результат работы этого фрагмента будет таким:</P>
<P>The value of pi is 3.141592.</P>
<P>Pi doubled equals 6.283184.</P>
<P>В этом фрагменте следует обратить внимание на два обстоятельства.
Во-первых, в именах констант не указывается знак доллара. Во-вторых,
константу невозможно модифицировать (например, присвоить ей величину
2*РI); если константа используется в вычислениях, то результат приходится
сохранять в другой переменной.</P>
<P><A name=ff></A>Итоги</P>
<P>В этой главе был изложен довольно обширный материал, необходимый для
понимания и самостоятельного написания простых программ на РНР. В
частности, мы рассмотрели следующие темы:</P>
<UL>
<LI>допустимые типы данных (целые и вещественные числа, строки, массивы,
объекты, логические величины);
<LI>идентификаторы;
<LI>переменные (объявление, область действия);
<LI>переключение типов;
<LI>преобразование типов;
<LI>присваивание значений переменным (по значению, по ссылке);
<LI>константы. </LI></UL>
<P>Этот материал закладывает основу для создания более сложных сценариев.
В следующей главе мы перейдем к подробному изучению выражений, операторов
и управляющих конструкций языка РНР. К концу главы 3 ваших новых знаний
хватит для того, чтобы построить первое приложение РНР — простейший
календарь.</P></LI></DIV>
<center>
[ <a href="01.php">Назад</a> | <a href="index.php">Содержание</a> | <a href="03.php">Вперед</a> ]
</center><br>
<p style="color:#777777;">Другая полезная информация по языку PHP на портале <a href="http://www.php.su">PHP.SU</a></p>
</body>
</html>
<?php
echo gb.'<a href="../../ycheb">Учебники</a>'.div;
echo gb.'<a href="'.H.'enter">Прихожая</a>'.div;
foot(); ?>