PHP: Переменные и константы
Автор: | Артемьев Сергей Игоревич |
ICQ: | 438856621 |
email: | _spin_@bk.ru |
Переменная - это некая сущность, содержащая данные. Если тип данных это общее описание формата хранимых данных и способов работы с ними, то переменная представляет собой конкретный блок памяти компьютера. В этом блоке хранится значение переменной, а обратиться к блоку (и к значению) можно по имени переменной.
В PHP имя переменной всегда начинается со знака доллара ($), за которым обязательно должна следовать буква, после которой можно использовать буквы, цифры и знак подчёркивания. Имена чувствительны к регистру символов, т.е. переменные $value, $Value, $VALUE и $VaLuE - четыре РАЗНЫХ переменных, хотя их имя и читается одинаково.
Примеры синтаксически правильных имён переменных:
<php $varName $name_19 $x_____________99887 $иван_иваныч ?>
Пример некорректных имён:
<php $1_name $_user_pass ?>
Есть одно общее правило (для всех языков программирования), касающееся именования переменных. Правило очень простое: имена всегда должны быть осмысленными.
Пример плохо читаемого кода
<php $x_1 = func1($b); $u1 = $x_1['param1']; $u2 = $x_1['param2']; $u3 = $x_1['param3']; ?>
Краткость, конечно, сетстра таланта, но жертвовать простотой восприятия кода ради его компактности - неразумно. Тем более, что длина имени никак не влияет на производительнось скрипта. Но не стоит и впадать в противоположную крайность - давать переменным слишком длинные имена. Если имя должно состоять из двух и более слов - части имени нужно выделять заглавными буквами или разделять подчёркиваниями. Например, имя $strusernameadndomain намного лучше воспринимается в виде $str_UserNameAndDomain.
Пример хорошо читаемого кода
<php $user_data = get_user_data($userInfo); $user_id = $user_data['user_id']; $user_login = $user_data['user_login']; $user_name = $user_data['user_name']; ?>
Переменные бывают двух видов: обычные переменные (переменные-значения) и ссылочные переменные. Ключевое отличие между ними заключено в способе обработки данных. При присвоении значения обычной переменной присваиваемое значение полностью копируется, т.е. создаётся новый блок памяти, куда помещается копия исходного значения. При дальнейшей работе все изменения будут отражаться на этой копии, а не на исходных данных.
Ссылочные переменные работают иначе. При присвоении значения ссылочной переменной копируются не данные, а информация о том, где она лежит. В результате получается, что переменная указывает на тот же блок, в котором лежат исходные данные. Теперь если изменить значение ссылочной переменной, то изменится исходное значение.
Рассмотрим пример:
Передача переменных по значению
<php // Присвоим значение 'Вася' переменной $name $name = 'Вася'; $ref_name = $name; // Теперь $ref_name равен $name // Изменим $ref_name $ref_name = "Меня зовут $ref_name"; echo $ref_name; // $ref_name изменилась echo $name; // $name осталась прежней ?>
Передача переменных по ссылке
<php // Присвоим значение 'Вася' переменной $name $name = 'Вася'; $ref_name = &$name; // Теперь $ref_name ссылается на $name // Изменим $ref_name $ref_name = "Меня зовут $ref_name"; echo $ref_name; echo $name; // $name изменилась одинаково с $ref_name ?>
Стоит отметить, что по ссылке можно передавать только переменные, т.е. следующий код приведёт к ошибке:
<php $ref_name = &('Вася'); // нельзя, т.к. значение 'Вася' не является переменной; ?>
Для работы с переменными есть в PHP особые функции:
- isset() - проверяет, была ли объявлена переменная и отличается ли её значение от NULL;
- empty() - аналог isset()
- unset() - встроенная функция языка, удаляющая значение переменной и удаляющая саму переменную из списка доступных переменных (уничтожающая переменную).
<php $name = 'Иван Иваныч'; if(isset($name)) { // Выводим сообщение с именем echo "Моё имя: $name"; // уничтожаем переменную unset($name); } else "Имя ещё не определено"; echo $name; // ничего не выведет, // т.к. значение переменной $name // ещё не определено // или переменная уже уничтожена ?>
Область видимости переменных
Очень важная характеристика переменной - её область видимости (область действия), т.е. описание того, из каких мест программы (скрипта) можно прочитать или изменить её значение. Следует всегда помнить, что переменная, объявленная внутри блока программы, видна только в пределах этого блока, а для того, чтобы обратиться к переменной, объявленной снаружи блока, необходимо её особым образом объявить.
Блоками программы в данном случае являются "скрипт", "функция" или "класс". Например:
<php $name = 'Вася'; // переменная $name объявлена в блоке "скрипт" // функция, добавляющая фамилию к имени function tryChengeName($family) { $fullName = $name . $family; echo 'Имя внутри функции: '.$fullName; } echo 'Имя ДО вызова функции: '.$name; // результат: "Имя ДО вызова функции: Вася" tryChengeName(' Иванов'); // результат: "" echo 'Имя ПОСЛЕ вызова функции: '.$name; // результат: "Имя ПОСЛЕ вызова функции: Вася" ?>
Вроде бы всё правильно, но - не работает. Почему? Потому что если явно не сказать, что переменная $name внутри функции - это в действительности глобальная переменная $name, то интерпретатор создать временную копию переменной с именем $name и пустым значением. А так как значение пустое (неопределённое), то и результат сложения строк будет неопределён (пуст).
Исправить положение очень легко, достаточно добавить всего одну строку (выделена жирным шрифтом):
<php $name = 'Вася'; // переменная $name объявлена в блоке "скрипт" // функция, добавляющая фамилию к имени function tryChengeName($family) { global $name; // явно указываем, что надо // использовать глобальную переменную. $fullName = $name . $family; echo 'Имя внутри функции: '.$fullName; } echo 'Имя ДО вызова функции: '.$name; // результат: "Имя ДО вызова функции: Вася" tryChengeName(' Иванов'); // результат: "Имя внутри функции: Вася Иванов" echo 'Имя ПОСЛЕ вызова функции: '.$name; // результат: "Имя ПОСЛЕ вызова функции: Вася Иванов" ?>
В данном примере переменная $name имеет область видимости, равную всему скрипту, а переменная $fullName, объявленная внутри функции, имеет область определения равную этой самой функции. Это значит, при выходе их функции переменная $fullName будет уничтожена, а все попытки прочитать её значение приведут к ошибке.
Примеры работы с классами мы рассмотрим в разделе "Классы и наследование".
Переменные переменные
Да-да, здесь нет ошибки, именно так (двумя словами) называются некоторые переменные в PHP. Смысл в том, что текстовая часть имени переменной (т.е. имя без знака доллара) может сама быть именем. Например:
<php // объявляем и инициализируем // переменную $varVar $varVar = 'Вася'; // объявляем и инициализируем // переменную $$varVar, т.е. $Вася $$varVar = 'Иванов'; echo "$varVar ${$varVar}"; // выведет Вася Иванов, ?>
Настоятельно не рекомендуется пользоваться подобными приёмами без острой необходимости. Код, напичканый такими трюками, очень сложно сопровождать. Особенно это важно при работе с данными, вводимыми пользователями. Главная причина сложностей - неявные зависимости. Например, что случится, если вместо имени 'Вася' написать что-то вроде "''""_;%//^q'"? Правильно! Скрипт в большинстве случаев не сможет выполниться! Можно, конечно, добавить кучу проверок на наличие "неправильных" символов, но проще вообще не пользоваться такими трюками.
Константы
Константа - это некая неизменная величина. Константа объявляется одновременно с именем и значением. Для объявления константы служит функция define(), а для определения наличия константы (т.е. была она определена или нет) - функция defined(). Имя константы строится по тем же правилам, что и имена переменных.
Примеры констант:
<php // Правильные имена define("DBServer", "localhost"); define("DBCatalog", "php_online"); define("DBUser", "root"); // неправильные имена define("2pass", "userpass"); if(defined("DBServer")) echo DBServer; else echo "DBServer not defined"; ?>
Отдельный вид констант PHP - так называемые "магические константы". Это системные константы, значение которых определяет и устанавливает интерпретатор. Таких констант немного:
- __LINE__ Содержит номер текущей строки в текущем файле.
- __FILE__ Содержит полное имя текущего файла
- __FUNCTION__ Содержит имя текущей функции.
- __CLASS__ Содержит имя текущего класса.
- __METHOD__ Содержит имя текущего метода текущего класса.
Эти константы очень удобны при отладке, но во всех других случаях их лучше не использовать, заменяя на вызовы соответствующих функций.