View file php/azy/glava2.txt

File size: 33.4Kb
Глава 2 

Переменные и типы данных 

Типы данных составляют основу любого языка программирования и являются средством, с помощью которого программист представляет разные типы информации. В РНР поддерживаются шесть основных типов данных: 

целые числа; 
вещественные числа; 
строки; 
массивы; 
объекты; 
логические величины. 
Одним из столпов любого языка программирования является поддержка числовых данных. В РНР поддерживаются как целые, так и вещественные числа (двойной точности). Разные числовые форматы подробно описываются в следующих разделах. 

Целые числа 

Целое число не имеет дробной части и представляется последовательностью из одной или нескольких цифр. Примеры целых чисел: 

5 

591 

52 

Восьмеричная и шестнадцатеричная запись 

В РНР поддерживается запись целых чисел в восьмеричной (по основанию 8) и шестнадцатеричной (по основанию 16) системах счисления. Восьмеричные числа начинаются с цифры 0, после которой следует серия цифр от 0 до 7. Примеры: 

0422 

0534 

Шестнадцатеричные целые числа имеют префикс 0х или 0Х и могут состоять из цифр от 0 до 9 и букв от а (А) до f (F). Примеры: 

0x3FF 

0x22abc 

Вещественные числа 

Вещественные числа (числа с плавающей точкой) отличаются от целых наличием дробной части. Они используются для представления значений, требующих повышенной точности, - например, температур или денежных величин. В РНР поддерживаются два вещественных формата: стандартная и научная (экспоненциальная) запись. 

Стандартная запись 

Стандартная запись удобна для представления типичных вещественных чисел - скажем, денежных величин. Примеры: 

12.45 

98.6 

Научная запись 

Научная запись лучше подходит для представления очень больших и очень малых чисел - скажем, межпланетных расстояний или размеров атомов. Примеры: 

Зе8 

5.9736е24 

Строковые значения 

Строкой (string) называется последовательность символов, которая рассматривается как единое целое, но при этом обеспечивает доступ к отдельным символам. Примеры строк: 

thesaurus 

49ers 

abc 

&%/$# 

Обратите внимание: в РНР не поддерживается символьный тип данных. Строковый тип может рассматриваться как единое представление для последовательностей, состоящих из одного или нескольких символов. 

Строковое присваивание 

Строки делятся на две категории в зависимости от типа ограничителя - они могут ограничиваться парой кавычек (" ") или апострофов (' '). Между этими категориями существуют два принципиальных различия. Во-первых, имена переменных в строках, заключенных в кавычки, заменяются соответствующими значениями, а строки в апострофах интерпретируются буквально, даже если в них присутствуют имена переменных, 

Два следующих объявления дают одинаковый результат: 

$food = "meatloaf"; 

$food = 'meatloaf'; 

Однако результаты следующих объявлений сильно различаются: 

$sentence = "My favorite food is $food"; 

$sentence2 = 'My favorite food is $food'; 

Переменной $sentence присваивается строка 

My favorite food is meatloaf. 

Обратите внимание: переменная $food автоматически интерпретируется. С другой стороны, переменной $sentence2 присваивается строка 

My favorite food is $food. 

В отличие от переменной $sentence, в $sentence2 осталась не интерпретированная переменная $food. Различия обусловлены использованием кавычек и апострофов при присваивании переменным $sentence и $sentence2. 

Прежде чем рассматривать второе фундаментальное различие между строками, заключенными в апострофы и в кавычки, необходимо познакомиться со служебными символами, используемыми в строках РНР. В РНР, как и в большинстве современных языков программирования, строки могут содержать служебные символы (например, символы табуляции или новой строки), перечисленные в табл. 2.1. 

Таблица 2.1. Служебные символы в строках 

Последовательность  Смысл 
 
\n  Новая строка  
 \r  Возврат курсора  
 \t  Горизонтальная табуляция  
\\  Обратная косая черта  
  \$  Знак доллара  
\"  Кавычка  
\[0-7]{1,3}  Восьмеричная запись числа (в виде регулярного выражения)  
 \x[0-9A-Fa-f]{l,2}  Шестнадцатиричная запись числа (в виде регулярного выражения)  

Второе принципиальное различие заключается в том, что в строках, заключенных в кавычки, распознаются все существующие служебные символы, а в строках, заключенных в апострофы, - только служебные символы '\\' и '\'. Следующий пример наглядно демонстрирует различия между присваиванием строк, заключенных в кавычки и апострофы: 

$double_list = "item1\nitem2\nitem2"; 

$single_list = 'item1\nitem2\nitem2'; 

Если вывести обе строки в браузере, окажется, что строка в кавычках содержит внутренние символы новой строки, а в строке в апострофах последовательность \n выводится как обычные символы. Хотя многие служебные символы в браузерах несущественны, при форматировании для других условий они играют очень важную роль. Помните об этом, выбирая между кавычками и апострофами, и вам удастся избежать многих неожиданностей. 

Синтаксис встроенной документации 

Второй вариант синтаксиса ограничения строк, представленный в HTML4, называется встроенной документацией (here doc). В этом варианте синтаксиса строка начинается с символов <<<, за которыми следует некоторый идентификатор по вашему выбору, затем строка, присваиваемая переменной. Конструкция заканчивается вторым экземпляром того же идентификатора. Пример: 

$paragraph = <<<DELIM 

This is a string that 

Will be interpreted exactly 

As it is written in the 

variable assignment, 

DELIM; 

Выбранный идентификатор не должен присутствовать в присваиваемой строке. Более того, первый символ завершающего идентификатора должен находиться в первом столбце строки, завершающей конструкцию. 

Обращение к отдельным символам строк 

К отдельным символам строки можно обращаться как к элементам массива с последовательной нумерацией (см. следующий раздел). Пример: 

$sequence_number = "04efgh"; 

$letter = Ssequence_number[4]; 

Переменной $ letter будет присвоено значение g. Как вы узнаете из следующего раздела, в РНР нумерация элементов массивов начинается с 0. Соответственно, выражение $sequence_number[l] будет равно 4. 

Массивы 

Массив представляет собой список однотипных элементов. Существует два типа массивов, различающиеся по способу идентификации элементов. В массивах первого типа элемент определяется индексом в последовательности. Массивы второго типа имеют ассоциативную природу, и для обращения к элементам используются ключи, логически связанные со значениями. Впрочем, на практике операции с массивами обоих типов выполняются сходным образом. По размерности массивы делятся на одномерные и многомерные. 

Одномерные индексируемые массивы 

При обращении к элементам одномерных индексируемых массивов используется целочисленный индекс, определяющий позицию заданного элемента. 

Обобщенный синтаксис элементов одномерного массива: 

$имя[индекс1]; 

Одномерные массивы создаются следующим образом: 

$meat[0] = "chicken"; 

$meat[l] = "steak"; 

$meat[2] = "turkey"; 

При выполнении следующей команды: 

print $meat[1]: 

в браузере выводится строка 

steak 

При создании массивов также можно воспользоваться функцией array (). Массив $meat из предыдущего примера создается командой 

$meat = аrrау("chicken", "steak", "turkey"); 

Приведенная выше команда pri nt приводит к тому же результату - выводу строки steak. 

Чтобы включить новый элемент в конец массива, можно просто присвоить значение переменной массива без указания индекса. Следовательно, массив $meat можно создать еще одним способом: 

Smeat[] = "chicken"; 

$meat[] = "steak"; 

Smeat[] = "turkey"; 

Одномерные ассоциативные массивы 

Ассоциативные массивы особенно удобны в ситуациях, когда элементы массива удобнее связывать со словами, а не с числами. 

Предположим, вы хотите сохранить в массиве лучшие сочетания вин и блюд. Проще всего было бы хранить в массиве пары 'ключ/значение' - например, присвоить сорт вина названию блюда. Самым разумным решением будет использование ассоциативного массива: 

Spairings["zinfandel"] = "Broiled Veal Chops"; 

$pairings["merlot"] = "Baked Ham"; 

$pairings["sauvignon"] = "Prime Rib"; 

$pairings["sauternes"] = "Roasted Salmon"; 

Ассоциативный массив заметно экономит время и объем программного кода, необходимого для вывода определенных элементов массива. Допустим, вы хотите узнать, с каким блюдом лучше всего идет 'Мерло'. Нужная информация выводится простой ссылкой на элемент массива $pairings: print $pairings["merlot"]; // Выводится строка "Baked Ham" Ассоциативные массивы также можно создавать функцией РНР аггау(): 

Spairings = аrrау( 

zinfandel => "Broiled Veal Chops", 

merlot => "Baked Ham", 

sauvignon => "Prime Rib", 

sauternes => "Roasted Salmon"); 

Отличается только способ создания массива pairings, а функциональные возможности остаются без изменений. 

Многомерные индексируемые массивы 

Многомерные индексируемые массивы работают практически так же, как и их одномерные прототипы, однако элементы в них определяются несколькими индексами вместо одного. Теоретически размерность индексируемого массива не ограничивается, хотя в большинстве приложений практически не встречаются массивы с размерностью выше 3. 

Обобщенный синтаксис элементов многомерного массива: 

$имя[индекс1][индекс2]..[индексN]; 

Пример ссылки на элемент двухмерного индексируемого массива: 

$position = $chess_board[5][4]; 

Многомерные ассоциативные массивы 

Многомерные ассоциативные массивы также существуют в РНР (и приносят определенную пользу). Допустим, в массиве $раirings из предыдущего примера должна храниться информация не только о сорте, но и о производителе вина. Это можно сделать следующим образом: 

$pairings["Martinelli"]["zinfandel"] = "Broiled Veal Chops"; 

$pairings["Beringer"]["merlot"] = "Baked Ham"; 

$pairings["Jarvis"]["sauvignon"] = "Prime Rib"; 

$pairings["Climens"]["sauternes"] = "Roasted Salmon"; 

Смешанное индексирование 

В многомерных массивах допускается смешанное индексирование (числовое и ассоциативное). Допустим, вы хотите расширить модель одномерного ассоциативного массива для хранения информации об игроках первого и второго состава футбольной команды. Решение может выглядеть следующим образом: 

$Buckeyes["quarterback"] [1] = "Bellisari"; 

$Buckeyes["quarterback"] [2] = "Moherman": 

$Buckeyes["quarterback"] [3] = "Wiley"; 

В РНР существует множество функций для создания массивов и операций с ними - эта тема настолько обширна, что заслуживает отдельной главы. Работа с массивами в РНР подробно описана в главе 13. 

Объекты 

К пятому типу данных РНР относятся объекты. Объект представляет собой переменную, экземпляр которой создается по специальному шаблону, называемому классом. Концепции объектов и классов являются неотъемлемой частью парадигмы объектно-ориентированного программирования (ООП). 

В отличие от других типов данных, поддерживаемых в языке РНР, объекты должны объявляться явно. Необходимо понимать, что объект - всего лишь конкретный экземпляр класса, используемого в качестве шаблона для создания объектов с конкретными характеристиками и функциональными возможностями. Следовательно, объявление класса должно предшествовать объявлению объектов, создаваемых на их основе. Пример объявления класса и последующего создания объектов на его основе: 

class appliance { 

var power: 

function set_power($on_off) { 

$this->power = $on_off;  

} 

} 

... 

$blender = new appliance; 

Определение класса задает атрибуты и функции, связанные с некоторой структурой данных - в данном примере это структура с именем appliance (устройство). У этой структуры имеется всего один атрибут power (мощность). Для изменения этого атрибута создается метод set_power. 

Помните: определение класса - всего лишь шаблон, и выполнять операции с ним в программе невозможно; сначала нужно создать объекты на основе этого шаблона. Объекты создаются при помощи ключевого слова new. Например, в приведенном выше фрагменте создается объект $blender класса appliance. 

После создания объекта $blender можно задать его мощность при помощи метода 

set_power: $blender->set_power("on"); 

Объектно-ориентированное программирование занимает столь важное место в современных стандартах программирования, что его применение в РНР заслуживает отдельной главы. Реализация ООП в РНР описана в главе 6. 

Логические величины (истина/ложь) 

Логический тип данных принимает всего два значения: истинное (true) и ложное (false). Логические величины создаются двумя способами: при проверке условий и в виде значений переменных. Обе ситуации достаточно просты. 

Сравнения существуют в нескольких формах. Чаще всего они встречаются при использовании оператора = в условной команде if. Пример: 

if ($sum == 40) : 

... 

Результатом проверки является либо истина, либо ложь: переменная $sum либо равна 40, либо не равна. Если переменная $sum равна 40, проверка дает истинный результат. В противном случае результат равен false. 

Логические величины также могут определяться явным присваиванием переменной истинного или ложного значения. Пример: 

$flag = TRUE; 

if ($flag == TRUE) : 

print "The flag is true!"; 

else : 

print "The flag is false!"; 

endif; 

Если переменная $flag истинна, выводится первое сообщение, а если ложна - второе сообщение. 

Возможен и другой вариант - представление истинных и ложных логических величин в виде значений 1 и 0 соответственно. В этом случае предыдущий пример выглядит так: 

$flag = 1; 

if ($flag == TRUE) ; 

print "The flag is true!"; 

else : 

print "The flag is false!"; 

endif; 

Наконец, существует еще один способ: 

$flag = TRUE: 

// При выполнении этой команды косвенно  

// проверяется условие "if ($flag == TRUE)" 

if ($flag) : 

print "The flag is true!"; 

else : 

print "The flag is false!"; 

endif: 

Идентификаторы 

Общий термин идентификатор применяется к переменным, функциям и другим объектам, определяемым пользователем. Идентификаторы РНР должны удовлетворять нескольким условиям: 

Идентификатор состоит из одного или нескольких символов и начинается с буквы или символа подчеркивания. Идентификатор может содержать только буквы, цифры, символы подчеркивания и другие ASCII-символы с кодами от 127 до 255. Примеры: 

Допустимые идентификаторы  Недопустимые идентификаторы 
 
my_function 
 This&that 
 
Size  !counter  
_someword  4ward  

В идентификаторах учитывается регистр символов. Следовательно, переменная с именем $recipe отличается от переменных с именами $Recipe, $rEciPe и $recipE. 

Длина идентификаторов не ограничивается. Это удобно, поскольку программист может точно описать смысл идентификатора в его имени. 

Идентификатор не может совпадать с каким-либо из стандартных ключевых слов РНР. 

Переменные 

В примерах, приведенных выше, я попутно показал, как происходит присваивание и изменение значений переменных. И все же стоит четко сформулировать правила объявления переменных и выполнения операций с ними. Ниже приводится подробное описание этих правил. 

Объявление переменных 

Переменная представляет собой именованную область памяти, содержащую данные, с которыми можно выполнять операции во время выполнения программы. 

Имена переменных всегда начинаются со знака доллара, $. Ниже приведены примеры допустимых имен переменных: 

$соlоr 

$operating_system 

$_some_variable 

$model 

Имена переменных должны соответствовать тем же условиям, что и идентификаторы. Другими словами, имя переменной начинается с буквы или символа подчеркивания и состоит из букв, символов подчеркивания, цифр или других ASCII-символов в интервале от 127 до 255. 

Следует заметить, что переменные в РНР, как и в языке Perl, не требуют специального объявления. Вместо этого переменная объявляется при первом ее использовании в программе. Более того, тип переменной косвенно определяется по типу хранящихся в ней данных. Рассмотрим следующий пример: 

$sentence = "This is a sentence."; // $sentence интерпретируется как строка 

$price = 42.99: // $price интерпретируется как вещественное число 

$weight = 185; // $weight интерпретируется как целое число 

Переменные могут объявляться в любой точке сценария РНР, однако от расположения объявления зависит то, откуда можно обращаться к данной переменной. 

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

Область видимости (scope) определяется как область доступности переменной в той программе, в которой она была объявлена. В зависимости от области видимости переменные РНР делятся на четыре типа: 

  локальные переменные; 
параметры функций; 
глобальные переменные; 
статические переменные. 
Локальные переменные 

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

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

$х = 4; 

function assignx () { 

$х = 0; 

print "\$x inside function is $x. <br>"; 

} 

assignx(); 

print "\$x outside of function is $x. <br>"; 

При выполнении этого фрагмента выводится следующий результат: 

$х inside function is 0. 

$х outside of function is 4. 

Как видите, программа выводит два разных значения переменной $х. Дело в том, что переменная $х внутри функции assignx имеет локальную природу, и изменение ее значения никак не отражается на значении, существующем за пределами этой функции. Справедливо и обратное - модификация $х за пределами функции никак не отражается на локальных переменных функции assignx(). 

Параметры функций 

В РНР, как и во многих других языках программирования, любые параметры, передаваемые функции при вызове, должны быть объявлены в заголовке функции. Хотя параметрам присваиваются аргументы, переданные извне, после выхода из функции они становятся недоступными. 

Параметры объявляются в круглых скобках после имени функции. Объявление параметров практически не отличается от объявления типичной переменной: 

// Функция умножает переданное значение на 10 и возвращает результат 

function x10 ($value) { 

$value = $value * 10; 

return $value; 

} 

Хотя вы можете обращаться к параметрам в той функции, в которой они были объявлены, и выполнять с ними необходимые операции, после завершения функции параметры уничтожаются. 

Глобальные переменные 

Глобальные переменные, в отличие от локальных, доступны в любой точке программы. Но чтобы изменить значение глобальной переменной, необходимо специально объявить ее как глобальную в соответствующей функции. Для этого перед именем переменной ставится ключевое слово GLOBAL. Пример: 

$somevar = 15; 

function addit() { 

GLOBAL $somevar; 

$somevar++; 

print "Somevar is $somevar"; 

} 

addit(); 

Будет выведено значение $somevar, равное 16. Допустим, вы забыли включить следующую строку: 

GLOBAL $ somevar; 

В этом случае $somevar будет присвоено значение 1, поскольку эта переменная будет считаться локальной по отношению к функции addit( ). Локальная переменная по умолчанию инициализируется 0, а затем к ней прибавляется 1; таким образом, будет выведено значение 1. 

Альтернативный способ объявления глобальных переменных связан с использованием массива РНР $GLOBALS( ). Давайте вернемся к предыдущему примеру и воспользуемся этим массивом для объявления глобальной переменной $somevar: $somevar = 15; 

function addit() { 

$GLOBALS["somevar"]; 

$somevar++; 

} 

addit(); 

print "Somevar is $somevar"; 

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

Статические переменные 

Последний тип видимости переменных называется статическим. В отличие от переменных, объявленных параметрами и уничтожаемых при выходе из функции, статическая переменная сохраняет свое значение при повторном вызове. Для объявления статической переменной перед ее именем ставится ключевое слово STATIC: 

STATIC $somevar; 

Рассмотрим пример: 

function keep_track() { 

STATIC $count = 0; 

$count++; 

print $count; 

print "<br>"; 

} 

keep_track(); 

keep_track(); 

keep_track(); 

Как будут выглядеть результаты работы этого сценария? Если бы переменная $count не была объявлена статической (то есть являлась локальной), результат выглядел бы так: 

1 

1 

1 

Но поскольку переменная $count является статической, при каждом вызове функции будет сохраняться ее предыдущее значение, поэтому результат будет таким: 

1 

2 

3 

Статические переменные особенно удобны при написании рекурсивных функций - особого класса функций, которые многократно вызывают сами себя до выполнения некоторого условия. Рекурсивные функции рассматриваются в главе 4. 

Переключение типов 

Иногда бывает удобно использовать переменные способами, не предусмотренными при их создании. Допустим, вам захочется прибавить строковое значение "15" к целому числу 12. К счастью, тип переменных РНР может изменяться и без использования механизма явного преобразования. Этот процесс, независимо от того, выполняется ли он прямо или косвенно, называется переключением (juggling) типов. Лучше всего продемонстрировать сказанное на конкретных примерах. 

Предположим, вы суммируете две величины - строку и целое число. Как вы думаете, что при этом произойдет? Результат зависит от содержимого строки. Например, при суммировании целого числа со строковым представлением числа будет получено целое число: 

$variablel = 1; 

$variable2 = "1"; 

$variable3 = $variablel + $variable2; 

// $variable3 присваивается 4. 

Другой пример переключения типов - суммирование целого числа с вещественным. При этом целое число преобразуется к вещественному типу, чтобы избежать потери точности: 

$ variablel = 3; 

$variable2 = 5.4; 

$variable3 = $variablel + $variable2; 

// $v ariablel интерпретируется как вещественное число. 

// и $variable3 присваивается 8.4. 

Следует упомянуть о некоторых малоизвестных особенностях переключения типов. Что произойдет при попытке суммирования целого числа и строки, содержащей целое число, но не являющейся строковым представлением? Рассмотрим следующий пример: 

$variablel = 5; 

$variable2 = "100 bottles of beer on the wall"; 

$variable3 = ;variable1 + $variable2; 

// $variable3 присваивается 105 

В результате переменной ;variable3 присваивается значение 105. Это происходит из-за того, что лексический анализатор РНР определяет тип по началу строки. Допустим, мы привели переменную $variable2 к виду "There are 100 bottles of beer on the wall". Поскольку алфавитные символы трудно интерпретировать как целое число, строка интерпретируется как 0, и переменной $variable3 присваивается 5. 

Хотя в большинстве случаев переключение типов обеспечивает желаемый результат, существует способ явного приведения переменных к конкретному типу. Эта тема рассматривается в следующем разделе. 

Преобразование типов 

Явное приведение переменной к типу, отличному от того, который изначально предназначался для нее, называется преобразованием (casting) типа. Изменение типа может быть как временным, одноразовым, так и постоянным. 

Чтобы временно привести переменную к другому типу, достаточно воспользоваться оператором преобразования типа - указать нужный тип перед именем переменной в круглых скобках (табл. 2.2). 

Таблица 2.2. Операторы преобразования типа переменных 

Оператор преобразования типа  Новый тип  
 (int) или (integer)  Целое число  
(real), (double) или (float)  Вещественное число  
(string)  Строка  
(array)  Массив  
(object)  Объект  

Простой пример преобразования типов: 

$variable1= 13; // $variable1 присваивается целое число 13 

$variable2 = (double) $variable1; // $variable2 присваивается 13.0 

Хотя переменная $variable1 первоначально содержала целое число 13, преобразование (double) преобразует ее к вещественному типу (поэтому число 13 превращается в 13.0). Полученное значение присваивается переменной $variable2. 

Из предыдущего раздела вы знаете, что при суммировании целого числа с вещественным получается вещественный результат. Однако тип результата можно изменить посредством явного преобразования типа: 

$variablel = 4.0; 

$variable2 = 5; 

$variable3 = (int) $variable1 + $variable2; // $variable3 = 9 

Следует заметить, что преобразование вещественного типа к целому всегда сопровождается округлением: 

$variablel = 14.7: 

$variable2 = (int) $varlable1; // $variable2 = 14: 

Строку или переменную другого типа также можно преобразовать в элемент массива. В этом случае преобразованная переменная становится первым элементом массива: 

$variable1 = 1114; 

$array1 = (array) $varable1; 

print $array1[0]; // Выводится значение 1114 

Наконец, любой тип данных можно преобразовать в объект. Переменная становится атрибутом объекта, и ей присваивается имя scalar: 

$model = "Toyota"; 

$new_obj = (object) $model; 

Ссылка на исходное строковое значение выглядит так: 

print $new_obj->scalar; 

Присваивание 

Вы уже знаете, как присвоить значение переменной в сценарии РНР. Тем не менее, некоторые тонкости, связанные с присваиванием, стоит выделить особо. Вероятно, вам хорошо знаком механизм присваивания по значению, при котором именованной переменной присваивается конкретное значение - например, целое число 1 или строка "ciao". Однако существует и второй механизм - присваивание по ссылке, также открывающее перед программистами немало полезных возможностей. В следующих разделах оба механизма рассматриваются более подробно. 

Присваивание по значению 

Это самый распространенный способ присваивания, при котором значение просто заносится в область памяти, представленную именем переменной. Примеры присваивания по значению: 

$vehicle = "car"; 

$amount =10.23; 

В результате выполнения этих двух команд по адресу памяти, представленному именем $vehicle, сохраняется строка "car", а по адресу, представленному именем $amount, - значение 10.23. 

Присваивание по значению также может выполняться в результате выполнения команды return в функциях: 

function simple () { 

return 5; 

} 

$return_value = simple(); 

Функция simple( ) всего лишь возвращает значение 5, которое присваивается некоторой переменной. В данном примере значение 5 будет присвоен о переменной $return_value. 

Присваивание по ссылке 

Другой способ заключается в присваивании переменной ссылки на область памяти, занимаемую другой переменной. Вместо конкретного значения переменная-приемник связывается с указателем (или ссылкой) на область памяти, поэтому фактическое копирование не выполняется. 

Чтобы присвоить значение по ссылке, укажите перед именем переменной-источника символ & (амперсанд): 

$dessert = "cake"; 

$dessert2 = $Sdessert; 

$dessert2 = "cookies"; 

print "$dessert2 <br>"; // Выводится строка cookies 

print Sdessert; // Снова выводится строка cookies 

Как видно из приведенного фрагмента, после связывания переменной $dessert2 со ссылкой на область памяти, занимаемую переменной $dessert, любые изменения $dessert2 приводят к автоматической модификации $dessert (и всех остальных переменных, ссылающихся на эту же область памяти). 

Переменные в переменных 

В некоторых ситуациях бывает удобно использовать переменные, содержимое которых может динамически интерпретироваться как имя другой переменной. Рассмотрим типичный случай присваивания: 

$recipe = "spaghetti"; 

Оказывается, строку "spaghetti" можно интерпретировать как имя переменной - для этого в команде присваивания перед именем исходной переменной ставится второй знак $: 

$$recipe = "& meatballs" ; 

Эта команда присваивает строку "& meatballs" переменной с именем "spaghetti". Следовательно, следующие две команды выводят одинаковые результаты: 

print $recipe $spaghetti; 

print $recipe $($recipe); 

В обоих случаях будет выведена строка "spaghetti & meatballs". 

Стандартные переменные 

В РНР поддерживается ряд стандартных переменных, предоставляющих в распоряжение программиста довольно подробную информацию о внутренней конфигурации. Значения одних переменных задаются РНР, другие изменяются в зависимости от операционной системы и web-сервера, с которыми работает РНР. 

Вместо подробного описания всех стандартных переменных я выделю лишь те переменные и функции, которые используются на практике многими программистами. 

Чтобы получить полный список переменных web-сервера, окружения и РНР, определенных для вашей конфигурации системы, достаточно выполнить следующий фрагмент: 

while (list($var,$value) = each($GLOBALS)) : 

echo "<BR>$var => $ value"; 

endwhile; 

В результате выводится список наподобие приведенного ниже. Потратьте немного времени на просмотр полученных данных, а затем разберите приведенные примеры. 

GLOBALS => 

HTTP_GET_VARS => Array 

HTTP_COOKIE_VARS => Array 

HOSTSIZE => 1000 

HOSTNAME => server1.apress.com 

LOGNAME => unstrung 

HISTFILESIZE => 1000 

REMOTEHOST => apress.com 

MAIL -> /var/spool/mail/apress 

MACHTYPE => 1386 

TERM => vt100 

HOSTTYPE => i386-linux 

PATH => 

/usr/sbin:/sbin:/usr/local /bin:/bin:/usr/bin:/usr/X11R6/bin:/usr/local/Java/bin 

HOME => /root 

INPUTRC => /etc/inputrc 

SHELL => /bin/csh 

USER => nobody 

VENDOR => intel 

GROUP => root 

HOST => server1.apress.com 

OSTYPE => linux 

PWD => /www/bin 

SHLVL => 3_ => /www/bin/httpd 

DOCUMENT_ROOT => /usr/local/apress/site.apress 

HTTP_ACCEPT => */* 

HTTP_ACCEPT_ENCODING => gzip, deflate 

HTTP_ACCEPT_LANGUAGE => it.en-us;q=0.5 

HTTP_CONNECTION -> Keep-Alive 

HTTP_HOST => www.apress.com 

HTTP_USER_AGENT => Mozilla/4.0 (compatible; MSIE 5.0: Windows 98; 

CNETHomeBuild051099) 

REMOTE_ADOR => 127.0.0.1 

REMQTE_PORT => 3207 

SCRIPT_FILENAME => /usr/local/apress/site.apress/j/environment_vars.php 

SERVER_ADDR => 127.0.0.1 

SERVER_AOMIN => [email protected] 

SERVER_NAME => www.apress.com 

SERVERJORT => 80 

SERVER SIGNATURE => 

Apache/1.3.12 Server at www.apress.com Port 80 

SERVER_SOFTWARE => Apache/1.3.12 (Unix) PHP/4.0.1 

GATEWAY_INTERFACE => CGI/1.1 

SERVER_PROTOCOL => HTTP/1.1 

REQUEST_METHOD => GET 

QUERY_STRING => 

REQUEST_URI => /j/environment_vars.php 

SCRIPT_NAME => /j/environment_vars.php 

PATH_TRANSLAETD => /usr/local/apress/site.apress/j/environment_vars.php 

PHP_SELF => /j/environment_vars.php 

argv => Array 

argc => 0 

var => argc 

value => argc 

Как видите, стандартные переменные содержат разнообразные сведения - как полезные, так и не очень. Вы можете вывести любую из этих переменных по имени. Например, следующая команда выводит IP-адрес пользователя: 

print "Hi! Your IP address is: $REMOTE_ADDR"; 

IP-адрес выводится в числовой форме (например, 208.247.106.187). 

Кроме того, стандартные переменные могут использоваться для сбора информации о браузере и операционной системе пользователя. Команда 

print "Your browser is: $HTTP_USER_AGENT"; 

возвращает информацию следующего вида: 

Your browser is: Mozina/4.0 (compatible: MSIE 5.0; Windows 98: CNETHomeBuild051099) 

Информация о браузере и операционной системе, в которой он работает, может пригодиться при построении страниц, рассчитанных на специфические форматы конкретных браузеров. 

 Для работы с массивами стандартных переменных необходимо включить директиву track_vars в файл php.ini. В РНР версии 4.0.3 директива track_vars включена постоянно. 

Константы 

Константой называется именованная величина, которая не изменяется в процессе выполнения программы. Константы особенно удобны при работе с заведомо постоянными величинами - например, числом ? (3,141592) или количеством футов в миле (5280). 

В РНР константы определяются функцией define( ). После того как константа будет определена, вы не сможете изменить (или переопределить) ее в этой программе. 

Например, определение числа я в сценарии РНР может выглядеть так: 

define("'PI", "3.141592"); 

Определенную константу можно использовать в программе: 

print "The value of pi is". PI."<br>"; 

$pi2 - 2 * PI: 

print "Pi doubled equals $pi2."; 

Результат работы этого фрагмента будет таким: 

The value of pi is 3.141592. 

Pi doubled equals 6.283184. 

В этом фрагменте следует обратить внимание на два обстоятельства. Во-первых, в именах констант не указывается знак доллара. Во-вторых, константу невозможно модифицировать (например, присвоить ей величину 2*РI); если константа используется в вычислениях, то результат приходится сохранять в другой переменной. 

Итоги 

В этой главе был изложен довольно обширный материал, необходимый для понимания и самостоятельного написания простых программ на РНР. В частности, мы рассмотрели следующие темы: 

допустимые типы данных (целые и вещественные числа, строки, массивы, объекты, логические величины); 
идентификаторы; 
переменные (объявление, область действия); 
переключение типов; 
преобразование типов; 
присваивание значений переменным (по значению, по ссылке); 
константы. 
Этот материал закладывает основу для создания более сложных сценариев. В следующей главе мы перейдем к подробному изучению выражений, операторов и управляющих конструкций языка РНР. К концу главы 3 ваших новых знаний хватит для того, чтобы построить первое приложение РНР - простейший календарь.