Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Котеров Д. В., Костарев А. Ф. - PHP 5. 2-е издание (В подлиннике) - 2008

.pdf
Скачиваний:
6114
Добавлен:
29.02.2016
Размер:
11.36 Mб
Скачать

174

Часть III. Основы языка PHP

$color = "right";

echo $$color; // выводит значение переменной $right ("красная") $$color = "несиняя"; // присваивает переменной $right новое значение

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

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

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

Ссылки на объекты

Чрезвычайно важное нововведение, появившееся в PHP версии 5, — улучшенная поддержка объектно-ориентированного программирования и, в частности, новый механизм копирования объектов. В PHP версии 4 переменные могли хранить объекты, которые полностью дублировались при копировании переменных через оператор

=. Например, сильно забегая вперед (не пугайтесь), рассмотрим код на PHP 4, при-

веденный в листинге 9.3.

Листинг 9.3. Файл objref.php

<?php ## Ссылки на объекты.

//Объявляем новый класс. class AgentSmith {}

//Создаем новый объект класса AgentSmith. $first = new AgentSmith();

//Присваиваем значение атрибуту класса. $first->mind = 0.123;

//Копируем объекты.

$second = $first;

//Изменяем "разумность" у копии! $second->mind = 100;

//Выводим оба значения.

echo "First mind: {$first->mind}, second: {$second->mind}"; ?>

Данная программа при запуске на интерпретаторе PHP 4 (обращаем еще раз ваше внимание на четвертую версию!) выведет два разных числа: 0.123 и 100, т. к. объекты $first и $second полностью индивидуальны и не имеют друг с другом ничего общего (во всяком случае, с точки зрения хранимых в них данных). Так происходит

Глава 9. Переменные, константы, типы данных

175

потому, что в PHP 4 переменные всегда хранят сами объекты, а не ссылки на них; следовательно, присваивание одной переменной другой ведет к копированию дан-

ных объектов.

Запустив тот же самый код в PHP 5, мы убедимся, что выводимые числа — одни и те же: 100 и 100. Почему так происходит? Дело в том, что в PHP 5 переменная хра-

нит не сам объект, а лишь ссылку на него. Попробуйте в программе написать:

echo $first;

Вы увидите что-то вроде "Object id #1" (и предупреждение о том, что нельзя преобразовывать объекты в строки). Это и есть ссылка на объект с номером 1. То же самое будет напечатано и при попытке вывести значение переменной $second: ведь

переменные ссылаются на один и тот же объект.

Так как переменные содержат лишь ссылки на объекты, при их присваивании копируются только эти ссылки, но не сами объекты. Это довольно просто понять: вы

можете сдать в гардероб свое пальто (объект) и получить на него номерок (ссылка), а затем пойти к Мастеру Номерков и сделать дубликат. У вас будет два номерка, но

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

Подробнее работу с объектами и ссылками на них мы рассмотрим в части V книги.

Некоторые условные обозначения

Как мы уже знаем, в PHP нет необходимости указывать тип какой-либо переменной

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

выполнения программы. Такие "подмены" будут вполне осмысленными, если, например, мы к строке "20" прибавим число 10 и получим результат 30 (а не "2010") —

это хороший пример того, как PHP выполняет преобразования из числа в строку и наоборот.

Но представьте себе, что мы хотим привести тип переменной $a к числу, а она на самом деле — массив. Ясно, что такое преобразование лишено всякого смысла —

о чем вам и сообщит (в лучшем случае) PHP, если вы попытаетесь, например, прибавить $a к 10. А может и не сообщить (скажем, если перевести массив в строку, то всегда получится строка "Array"). В то же время, дальше, когда мы будем рассматривать стандартные функции и операторы PHP (которых, кстати, очень много), в большинстве мест придется разъяснять, какой тип имеет тот или иной параметр

функции или оператора, причем все другие несовместимые с ним типы должны

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

же некоторые другие метасимволы. Вот пример описания функции по имени

FuncName:

<return_type> FuncName(<type1> $param1 [,<type1> $param2])

Функция делает то-то и то-то. Возвращает то-то.

176

Часть III. Основы языка PHP

Здесь должно быть приведено описание функции, возвращающей значение типа <return_type> и принимающей один или два аргумента (второй аргумент необязательный, на что указывают квадратные скобки). Тип первого параметра <type1>, а второго — <type2>. Описание возможных типов, которые мы здесь выделили угло-

выми скобками, приводится далее.

string

Обычная строка, или тип, который можно перевести в строку.

int, long

Целое число, либо вещественное число (в последнем случае дробная часть отсекается), либо строка, содержащая число в одном из перечисленных форматов. Если строку не удается перевести в int, то вместо нее подставляется 0, и никаких

предупреждений не генерируется!

double, float

Вещественное число, или целое число, или строка, содержащая одно из таких чисел.

bool

Логический тип, который будет восприниматься либо как ложь (нулевое число, пустая строка или константа false), либо как истина (все остальное). Этот тип редко указывается (вместо него пишут int, хотя это и неверно), но мы все же постараемся применять его там, где это возможно.

array

Массив, в общем случае ассоциативный (см. гл. 13), т. е. набор пар ключ=>значение. Впрочем, здесь может быть передан и список list.

list

Обычно это массив с целыми ключами, пронумерованными от 0 и следующими подряд. Так как список является разновидностью ассоциативного массива, то обычно вместо параметров функций типа list можно подставлять и параметры типа array. При этом, скорее всего, функция "ничего не заметит" и будет работать с этим массивом как со списком, "мысленно" пронумеровав его элементы. Можно также сказать, что список представляет собой упорядоченный набор значений (который можно, например, отсортировать в порядке возрастания), тогда как ассоциативный массив — упорядоченный набор пар значений, каждую из которых логически бессмысленно разъединять.

object

Объект некоторой структуры. Чаще всего эта структура будет уточняться.

void

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

mixed

Все, что угодно. Это может быть целое или дробное число, строка, массив или

объект... Например, параметр типа mixed имеет стандартная функция gettype()

Глава 9. Переменные, константы, типы данных

177

или функция settype(). Если написано, что функция возвращает значение типа mixed, это значит, что тип результата зависит от операндов и уточняется при описании функции.

resource

Значения этого типа возвращают различные функции, открывающие доступ

к каким-либо внешним объектам в программе. Например, функция fopen() воз-

вращает ресурс — дескриптор открытого файла. Для дальнейшей работы с файлом используется только его дескриптор.

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

Константы

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

смотрена такая конструкция, как константа.

Константа отличается от переменной тем, что, во-первых, ей нигде в программе

нельзя присвоить значение больше одного раза, а во-вторых, ее имя не предваряется

знаком $, как это делается для переменных. Например:

// Предположим, определена константа PI, равная 3.1416...

$a = 2.34

* sin(3 * PI / 8) + 5; //

использование константы

echo "Это число PI";

//

выведет "Это число PI"

echo "Это число ".PI;

//

выведет "Это число 3.1416..."

Хорошо, конечно, что не надо писать "доллар" перед именем константы. Однако,

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

Предопределенные константы

Константы бывают двух типов: одни — предопределенные (т. е. устанавливаемые

самим интерпретатором), а другие определяются программистом. Существует не-

сколько предопределенных констант.

__FILE__

Хранит имя файла, в котором расположен запущенный в настоящий момент код.

__LINE__

Содержит текущий номер строки, которую обрабатывает в текущий момент ин-

терпретатор. Эта своеобразная "константа" каждый раз меняется по ходу испол-

нения программы. (Впрочем, __FILE__ также меняется, если мы передаем управ-

ление в другой файл.)

178

Часть III. Основы языка PHP

PHP_VERSION

Версия интерпретатора PHP.

PHP_OS

Имя операционной системы, под управлением которой работает PHP.

TRUE или true

Эта константа нам уже знакома и содержит значение "истина".

FALSE или false

Содержит значение "ложь".

NULL или null

Содержит значение NULL.

Определение констант

Вы можете определить и свои собственные, новые константы. Делается это при по-

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

void define(string $name, string $value, bool $case_sen=true);

Определяет новую константу с именем, переданным в $name, и значением $value. Если необязательный параметр $case_sen равен true, то в дальнейшем в программе

регистр букв константы учитывается, в противном случае — не учитывается (по умолчанию, как мы видим, регистр учитывается). Созданная константа не может

быть уничтожена или переопределена.

Например:

define("pi", 3.14);

define("str", "Test string");

echo sin(pi/4);

echo str;

Просим обратить внимание на кавычки, которыми должно быть обрамлено имя

константы при ее определении. А также на то, что нельзя дважды определять константу с одним и тем же именем — это породит ошибку во время выполнения про-

граммы.

Проверка существования константы

В PHP существует также функция, которая проверяет, существует ли (была ли определена ранее) константа с указанным именем.

bool defined(string $name)

Возвращает true, если константа с именем $name была ранее определена.

Глава 9. Переменные, константы, типы данных

179

Отладочные функции

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

string print_r(mixed $expression, bool $return=false)

Эта функция — пожалуй, самая простая. Она принимает на вход некоторую переменную (или выражение) и распечатывает ее отладочное представление. Вот пример из документации:

$a = array('a'=>'apple', 'b'=>'banana', 'c'=>array('x', 'y', 'z'));

echo "<pre>"; print_r ($a); echo "</pre>";

Результатом работы этой программы будет следующий текст:

Array

(

[a]=> apple

[b]=> banana

[c]=> Array

(

[0]=> x

[1]=> y

[2]=> z

)

)

В случае, если параметр $return указан и равен true, функция ничего не печатает

вбраузер. Вместо этого она возвращает сформированное отладочное представление

ввиде строки. Это же относится и к двум остальным функциям.

string var_dump(mixed $expression, bool $return=false)

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

$a = array(1, array ("a", "b"));

echo "<pre>"; var_dump($a); echo "</pre>";

Результат работы:

array(2) {

[0]=>

int(1)

[1]=>

array(2) {

[0]=>

string(1) "a"

[1]=>

180

Часть III. Основы языка PHP

string(1) "b"

}

}

При отладке такое представление иногда оказывается весьма полезным.

string var_export(mixed $expression, bool $return=false)

Эта функция очень напоминает print_r(), но только она выводит значение переменной так, что оно может быть использовано прямо как "кусок" PHP-программы. Результат ее работы настолько интересен, что мы выделили пример в отдельный листинг (листинг 9.4).

Листинг 9.4. Файл var_export.php

<?php ## Использование var_export(). class SomeClass {

private $x = 100;

}

$a = array(1, array ("Programs hacking programs. Why?", "д'Артаньян")); echo "<pre>"; var_export($a); echo "</pre>";

$obj = new SomeClass();

echo "<pre>"; var_export($obj); echo "</pre>"; ?>

Результат работы этого скрипта таков:

array ( 0 => 1, 1 => array (

0 => 'Programs hacking programs. Why?',

1 => 'д\'Артаньян',

),

)

class SomeClass { private $x = 100;

}

Обратите внимание на две детали. Во-первых, функция корректно обрабатывает

апострофы внутри значений переменных — она добавляет обратный слэш перед ними, чтобы результат работы оказался корректным кодом на PHP. Во-вторых, для объектов (см. часть V) функция создает описание всех свойств класса, в том числе — и закрытых (private).

Результат работы функции var_export() можно использовать для автоматической генерации корректных PHP-скриптов из программы. Мы получаем программу, которая пишет другие программы. Кстати, в языке Perl для этой же цели служит модуль Data::Dumper.

Глава 9. Переменные, константы, типы данных

181

Резюме

В данной главе мы рассмотрели основные сущности, с которыми приходится иметь

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

ГЛАВА 10

Выражения и операции PHP

Листинги данной главы можно найти в подкаталоге expr.

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

Выражения

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

Самый простой пример выражения — переменная или константа, стоящая, скажем, в правой части оператора присваивания. Например, цифра 5 в операторе

$a = 5;

есть выражение, т. к. оно имеет значение 5. После такого присваивания мы вправе ожидать, что в $a окажется 5. Теперь, если мы напишем

$b = $a;

то, очевидно, в $b окажется также 5, ведь выражение $a в правой части оператора имеет значение 5.

Посмотрим еще раз на приведенный пример. Помните, мы говорили, что практически все, из чего мы составляем программу, — это выражения? Так вот, $b = $a — тоже выражение! (Впрочем, это не будет сюрпризом для знатоков C или Perl.) Нетрудно догадаться, какое оно имеет значение: 5. А это значит, что мы можем написать нечто вроде следующих команд:

$a = ($b = 10); // или просто $a = $b = 10

При этом переменным $a и $b присвоится значение 10. А вот еще пример, уже менее тривиальный:

$a = 3 * sin($b = $c + 10) + $d;

Глава 10. Выражения и операции PHP

183

Что окажется в переменных после выполнения этих команд? Очевидно, то же, что и в результате работы следующих операторов:

$b = $c + 10;

$a = 3 * sin($c + 10) + $d;

Мы видим, что в PHP при вычислении сложного выражения можно (если какая-то его часть понадобится нам впоследствии) задавать переменным значения этой части прямо внутри оператора присваивания. Такой прием может действительно сильно упростить жизнь и сократить код программы, "читабельность" которой сохранится на прежнем уровне, поэтому советуем им иногда пользоваться.

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

$a = 10 * 20;

$b = "" . (10 * 20);

echo "$a:".gettype($a).", $b:".gettype($b); // выведет "200:integer, 200:string"

Чтобы преобразовать одно значение в другое (например, нам может не понравиться, что $b — типа string, хотя содержит целое число), используются операторы преобразования типов. Эти операторы доступны как в функциональной, так и в префиксной операторной форме. Например, следующие две инструкции эквивалентны:

$a = intval($b);

$a = (int)$b;

Итак, перечислим операторы преобразования типов.

$b = intval(выражение) или $b = (int)(выражение)

Переводит значение выражения в целое число и присваивает его $b.

$b = doubleval(выражение) или $b = (double)(выражение)

Переводит значение в действительное число и присваивает его $b.

$b = strval(выражение) или $b = (string)(выражение)

Переводит значение выражения в строку.

$b = (bool)(выражение)

Преобразует значение выражения в логический тип. То есть, после выполнения этого оператора в $b окажется либо true, либо false.

Логические выражения

Логические выражения — это выражения, у которых могут быть только два значения: ложь и истина (или, что почти то же самое, 0 и 1). Что, поверили? Напрасно — на самом деле абсолютно любое выражение может рассматриваться как логическое в "логическом" же контексте (например, как условие для конструкции if-else). Ведь, как уже говорилось, в качестве истины может выступать любое ненулевое число, непустая строка и т. д., а под ложью подразумевается все остальное.

Тут вы можете оставить комментарий к выбранному абзацу или сообщить об ошибке.

Оставленные комментарии видны всем.