В этом уроке будет рассмотрено довольно много основных положений. Разобраться во всем этом несложно, но я рекомендую проработать материал как можно тщательнее, поскольку он служит основой для понимания всего остального.
Содержание урока
Комментарии
Существует два способа добавления комментариев к коду PHP. Первый, предусматривающий размещение в начале строки двух прямых слешей, превращает в комментарий отдельную строку:
// Это комментарий
Он хорошо подходит для временного исключения из программы строки кода, являющейся источником ошибок. Например, такой способ комментирования можно применить для того, чтобы скрыть строку кода до тех пор, пока в ней не возникнет необходимость:
// echo "X equals $x";
Такой комментарий можно также вставить сразу же после строки кода, чтобы описать ее действие:
$x += 10; // Увеличение значения $x на 10
Когда понадобится комментарий, состоящий из нескольких строк, нужно воспользоваться вторым способом комментирования, который показан ниже:
/* Это область многострочного комментария, которая не будет подвергаться интерпретации */
Для открытия и закрытия комментария можно воспользоваться парами символов /*
и */
практически в любом произвольно выбранном месте кода. Если не все, то большинство программистов используют эту конструкцию для временного превращения в комментарий целого неработоспособного раздела кода или такого раздела, который по тем или иным причинам нежелательно интерпретировать.
Типичная ошибка — применение пар символов
/*
и*/
для того, чтобы закомментировать большой фрагмент кода, уже содержащий закомментированную область, в которой используются эти же пары символов. Комментарии не могут быть вложенными друг в друга, поскольку PHP-интерпретатор не поймет, где заканчивается комментарий, и выведет на экран сообщение об ошибке. Но если вы используете редактор программ или интегрированную среду разработки с подсветкой синтаксиса, то ошибку такого рода нетрудно будет заметить.
Основной синтаксис
PHP — очень простой язык, уходящий своими корнями в язык Cએ и Perlએ, но все же больше похожий на Javaએ. Он очень гибок, но существует несколько правил, относящихся к его синтаксису и структуре, которые следует изучить.
Точка с запятой
В предыдущих примерах можно было заметить, что команды PHP завершаются точкой с запятой:
$x += 10;
Возможно, чаще всего причиной ошибок, с которыми приходится сталкиваться при работе с PHP, становится забывчивость. Если не поставить эту точку с запятой, PHP вынужден будет рассматривать в качестве одной сразу несколько инструкций, при этом он не сможет разобраться в ситуации и выдаст ошибку синтаксического разбора — Parse error
.
Символ $
Символ $
используется в разных языках программирования в различных целях. Например, в языке BASIC символ $
применялся в качестве завершения имен переменных, чтобы показать, что они относятся к строкам. А в PHP символ $
должен ставиться перед именами всех переменных. Это нужно для того, чтобы PHP‑парсер работал быстрее, сразу же понимая, что имеет дело с переменной. К какому бы типу ни относились переменные — к числам, строкам или массивам, все они должны выглядеть так, как показано в ниже:
<?php $mycounter = 1; $mystring = "Hello"; $myarray = array("One", "Two", "Three"); ?>
Вот, собственно, и весь синтаксис, который нужно усвоить. В отличие от языков, в которых отношение к способам отступа текста программы и размещения кода очень строгое (например, от Python), PHP дает полную свободу использования (или игнорирования) любых отступов и любого количества пробелов по вашему усмотрению. В действительности же разумное использование того, что называется свободным пространством, обычно поощряется (наряду с всесторонним комментированием), поскольку помогает разобраться в собственном коде, когда к нему приходится возвращаться по прошествии некоторого времени. Это помогает и другим программистам, вынужденным поддерживать ваш код.
Переменные
Понять, что такое переменные PHP, поможет простая метафора. Думайте о них как о небольших (или больших) спичечных коробках! Именно как о спичечных коробках, которые вы раскрасили и на которых написали некие имена.
Строковые переменные
Представьте, что у вас есть коробок, на котором написано слово username (имя пользователя). Затем вы пишете на клочке бумаги Fred Smith и кладете эту бумажку в коробок. Этот процесс похож на присваивание переменной строкового значения:
$username = "Fred Smith";
Кавычки служат признаком того, что Fred Smith
является строкой символов. Каждую строку нужно заключать либо в двойные, либо в одинарные кавычки (апострофы). Между этими двумя видами кавычек есть весьма существенное различие, которое будет рассмотрено далее. Когда хочется посмотреть, что находится внутри коробка, вы его открываете, вынимаете бумажку и читаете, что на ней написано. В PHP подобное действие выглядит следующим образом:
echo $username;
Можно также присвоить содержимое другой переменной (сделать ксерокопию бумажки и поместить ее в другой коробок):
$current_user = $username;
Если вы стремитесь самостоятельно освоить работу с PHP, то можете попробовать вводить примеры, приводимые в этом уроке, в интегрированную среду разработки (согласно рекомендациям, которые были даны ранее, чтобы тут же посмотреть на результаты, или же можете ввести код примера в текстовом редакторе и сохранить этот код в каталоге исходного источника документов вашего сервера под именем test1.php.
<?php // test1.php $username = "Fred Smith"; echo $username; echo "
"; $current_user = $username; echo $current_user; ?>
Теперь эту программу можно запустить, введя в адресную строку браузера следующий адрес:
http://localhost/test1.php
Результатом запуска этого кода будет двойное появление имени Fred Smith
, первое — в результате выполнения команды echo $username
, а второе — в результате выполнения команды echo $current_user
.
Числовые переменные
Переменные могут содержать не только строки, но и числа. Если вернуться к аналогии со спичечным коробком, сохранение в переменной $count
числа 17
будет эквивалентно помещению, скажем, 17
бусин в коробок, на котором написано слово count
:
$count = 17;
Можно также использовать числа с плавающей точкой (содержащие десятичную точку); синтаксис остается прежним:
$count = 17.5;
Чтобы узнать о содержимом коробка, его нужно просто открыть и посчитать бусины. В PHP можно присвоить значение переменной $count
другой переменной или вывести его с помощью браузера на экран, воспользовавшись командой echo
.
Массивы
Массивы можно представить в виде нескольких склеенных вместе спичечных коробков. Например, нам нужно сохранить имена пяти футболистов одной команды в массиве $team
. Для этого мы склеим вместе боковыми сторонами пять коробков, запишем имена всех игроков на отдельных клочках бумаги и положим каждый клочок в свой коробок.
Вдоль всей верхней стороны склеенных вместе коробков напишем слово team
(см. рисунок ниже). В PHP эквивалентом этому действию будет следующий код:
$team = array('Bill', 'Mary', 'Mike', 'Chris', 'Anne');
Этот синтаксис несколько сложнее рассмотренных ранее инструкций. Код создания массива представляет собой следующую конструкцию:
array();
с пятью строками внутри круглых скобок. Каждая строка заключена в одинарные кавычки. Когда потребуется узнать, кто является игроком номер 4
, можно воспользоваться следующей командой:
echo $team[3]; // Эта команда отображает имя Chris
Использование в предыдущем примере числа 3
, а не 4
обусловлено тем, что первый элемент PHP‑массива является, как правило, нулевым, поэтому номера игроков распределяются в интервале от 0
до 4
.
Двумерные массивы
Диапазон использования массивов очень широк. Например, вместо выстраивания одномерных рядов коробков из них можно построить двумерную матрицу, а массивы могут иметь три и более измерения. Чтобы привести пример двумерного массива, представим, что нужно отслеживать ход игры в крестики-нолики, для чего требуется структура данных, состоящая из девяти клеток, сгруппированных в квадрат 3 × 3. Чтобы представить это в виде спичечных коробков, вообразите себе девять коробков, склеенных в матрицу, состоящую из трех строк и трех столбцов.
Теперь для каждого хода можно класть в нужные коробки клочки бумаги с крестиком или ноликом. Чтобы сделать это в коде PHP, необходимо создать массив, содержащий три других массива, как в примере 3.5, в котором массив создается для отображения уже ведущейся игры. Пример 3.5. Определение двумерного массива
<?php $oxo = array(array('x', ' ', 'o'), array('o', 'o', 'x'), array('x', 'o', ' ' )); ?>
Мы сделали еще один шаг к усложнению, но смысл его нетрудно понять, если усвоен основной синтаксис массива. Здесь три конструкции array() вложены во внешнюю по отношению к ним конструкцию array().
Для возвращения в дальнейшем третьего элемента во второй строке этого массива можно воспользоваться следующей PHP-командой, которая отобразит символ «x»:
echo $oxo[1][2];
Не забывайте о том, что отсчет индексов массива (указателей на элементы внутри массива) начинается с нуля, а не с единицы, поэтому в предыдущей команде индекс [1] ссылается на второй из трех массивов, а индекс [2] — на третью позицию внутри этого массива. Эта команда вернет содержимое третьего слева и второго сверху коробка.
Как уже упоминалось, поддерживаются даже массивы с большей размерностью, получаемые путем простого создания большего количества вложенных друг в друга массивов. Но в данной книге массивы с размерностью больше двух рассматриваться не будут. Подробнее о массивах мы поговорим позже.
Правила присваивания имен переменным
При создании PHP-переменных следует придерживаться четырех правил.
- Имена переменных должны начинаться с буквы или с символа
_
(подчеркивания). - Имена переменных могут содержать только символы:
a–z, A–Z, 0–9
и_
(подчеркивание). - Имена переменных не должны включать в себя пробелы. Если имя переменной нужно составить более чем из одного слова, то в качестве разделителя следует использовать символ подчеркивания (например,
$user_name
). - Имена переменных чувствительны к регистру символов. Переменная
$High_Score
отличается от переменной$high_score
.
Чтобы позволить использование ASCII-символов, включающих диакритические знаки, PHP также поддерживает в именах переменных байты от
127
и до255
. Но пока ваш код не будет поддерживаться только теми программистами, которые знакомы с такими символами, от их применения лучше отказаться, поскольку программисты, использующие английские раскладки клавиатуры, будут испытывать трудности при доступе к таким символам.
Операторы
Операторы — это математические, строковые, логические команды и команды сравнения, такие как «плюс», «минус», «умножить» и «разделить». Код PHP во многом похож на обычные арифметические записи. Например, в результате работы следующего оператора выводится число 8
:
echo 6 + 2;
Перед тем как приступить к изучению возможностей PHP, следует уделить немного внимания рассмотрению предоставляющих эти возможности различных операторов.
Арифметические операторы
Арифметические операторы проделывают вполне ожидаемую работу. Они применяются для выполнения математических операций. Их можно использовать для проведения четырех основных операций (сложения, вычитания, умножения и деления), а также для нахождения модуля (остатка от деления) и увеличения или уменьшения значения на единицу (см. таблицу).
Таблица. Арифметические операторы
Операторы присваивания
Эти операторы используются для присваивания значений переменным. К ним относится самый простой оператор =
, а также операторы +=
, –=
и т. д. (см. таблицу). Оператор +=
вместо полного замещения находящегося слева значения добавляет к нему значение, которое находится справа от него. Итак, если переменная $count
имела начальное значение 5
, то оператор:
$count += 1;
устанавливает значение $count
равным 6
точно так же, как более привычный оператор присваивания:
$count = $count + 1;
Таблица. Операторы присваивания
У строк есть собственный оператор, точка (.
), который более подробно будет рассмотрен в разделе Объединение строк.
Операторы сравнения
Как правило, операторы сравнения используются внутри таких конструкций, как инструкция if
, в которых требуется сравнивать значения двух элементов. Например, если необходимо узнать, не достигло ли значение переменной, подвергающееся приращению, какого-то конкретного значения или не превышает ли значение другой переменной установленного значения и т. д..
Таблица. Операторы сравнения
Учтите, что операторы = и == предназначены для разных действий. Если первый является оператором присваивания, то второй — оператором сравнения. Иногда в спешке даже более опытные программисты могут вместо одного из них поставить другой, поэтому будьте внимательны, используя эти операторы.
Логические операторы
Если логические операторы вам раньше не встречались, то поначалу они могут показаться чем-то необычным. Нужно представить, что вы делаете логические заключения на простом разговорном языке. Например, можно сказать самому себе: «Если время уже больше 12, но меньше 14 часов, значит, нужно пообедать». В PHP код для такого высказывания может выглядеть следующим образом:
if ($hour > 12 && $hour < 14) dolunch();
Здесь набор инструкций для самого обеда помещен в функцию по имени dolunch, которую позже нужно будет создать. В этой инструкции отсутствует элемент then
(тогда), поскольку его присутствие само собой разумеется. Как видно из предыдущего примера, логический оператор обычно используется для объединения результатов работы двух операторов сравнения, показанных в предыдущем разделе. Результат работы одного логического оператора может служить входным значением для другого логического оператора («Если время уже больше 12, но меньше 14 часов или же если в комнате пахнет жареным и тарелки уже стоят на столе...»). Как правило, если какое-то действие имеет истинное или ложное значение — TRUE
или FALSE
, оно может служить входным значением для логического оператора, который берет два истинных или ложных входных значения и выдает в качестве результата истинное или ложное значение. Логические операторы показаны в таблице.
Таблица. Логические операторы
Заметьте, что оператор &&
обычно взаимозаменяем с оператором and
; то же самое справедливо и для операторов ||
и or
. Но у операторов and
и or более низкий приоритет, поэтому в некоторых случаях, для того чтобы принудительно расставить приоритеты, могут понадобиться дополнительные круглые скобки. В то же время бывают случаи, когда применимы только операторы and
или or
, как в следующем предложении, использующем оператор or
:
mysql_select_db($database) or die("Невозможно выбрать базу данных");
Наиболее непривычным из этих операторов является xor
, предназначенный для операции исключающего ИЛИ, который возвращает истинное значение TRUE
, если любое из входных значений истинно, и возвращает ложное значение FALSE
, если оба они имеют значение TRUE
или FALSE
. Чтобы понять его работу, представьте, что хотите изобрести чистящее средство для дома. Как аммиак (ammonia), так и хлорка (bleach) обладают хорошими чистящими свойствами, поэтому нужно, чтобы ваше средство содержало одно из этих веществ. Но оба они не могут в нем присутствовать, поскольку их сочетание опасно. В PHP это можно представить в следующем виде:
$ingredient = $ammonia xor $bleach;
В представленном фрагменте, если любая из двух переменных, $ammonia
или $bleach
, имеет значение TRUE
, то значение переменной $ingredient
также будет установлено в TRUE
. Но если обе они имеют значение TRUE
или значение FALSE
, то значение переменной $ingredient
будет установлено в FALSE
.
Присваивание значений переменным
Синтаксис присваивания значения переменной всегда имеет вид переменная = значение
. Для передачи значения другой переменной он имеет немного иной вид другая_переменная = переменная
.
Есть еще несколько дополнительных операторов присваивания, которые могут оказаться полезными. Например, нам уже встречался оператор:
$x += 10;
Он предписывает PHP‑парсеру добавить значение, расположенное справа от него (в данном случае это значение равно 10
), к значению переменной $x
. Подобным образом можно вычесть значение:
$y -= 10;
Увеличение и уменьшение значения переменной на единицу Добавление или вычитание единицы — настолько часто встречающаяся операция, что PHP предоставляет для этого специальные операторы. Вместо операторов
+=
и -=
можно воспользоваться одним из следующих операторов:
++$x; --$y;
В сочетании с проверкой (инструкцией if
) можно воспользоваться таким кодом:
if (++$x == 10) echo $x;
Этот код предписывает PHP сначала увеличить значение переменной $x
на единицу, а затем проверить, не имеет ли она значение 10
; если переменная имеет такое значение, его следует вывести на экран. Можно также потребовать от PHP увеличить значение переменной на единицу (или, как в следующем примере, уменьшить на единицу) после того, как ее значение будет проверено:
if ($y-- == 0) echo $y;
что дает несколько иной результат. Предположим, что первоначальное значение переменной $y
до выполнения оператора было равно нулю. Операция сравнения вернет результат TRUE
, но после того, как она будет проведена, переменной $y
будет присвоено значение –1
. Тогда что же отобразит инструкция echo
: 0
или –1
? Попробуйте догадаться, а потом, чтобы подтвердить свою догадку, испытайте работу инструкции в PHP⏹процессоре. Поскольку такая комбинация операторов может вас запутать, ее можно применять только в качестве обучающего примера, но ни в коем случае не рассматривать в качестве приемлемого стиля программирования.
Короче говоря, когда именно увеличено или уменьшено на единицу значение переменной, до или после проверки, зависит от того, где помещен оператор инкремента или декремента — перед именем переменной или после него. Кстати, правильный ответ на предыдущий вопрос таков: инструкция echo
отобразит результат –1
, потому что значение переменной $y
было уменьшено на единицу сразу же после того, как к ней получила доступ инструкция if
, и до того, как к ней получила доступ инструкция echo
.
Объединение строк
При объединении строк, когда к одной строке символов добавляется другая строка, используется символ точки (.
). Самый простой способ объединения строк выглядит следующим образом:
echo "У вас " . $msgs . " сообщений.";
Если предположить, что переменной $msgs присвоено значение 5, то эта строка кода выведет следующую информацию:
У вас 5 сообщений.
Так же как с помощью оператора +=
можно добавить значение к числовой переменной, с помощью оператора .=
можно добавить одну строку к другой:
$bulletin .= $newsflash;
В данном случае, если в переменной $bulletin
содержится сводка новостей, а в переменной $newsflash
— экстренное сообщение, команда добавляет это сообщение к сводке новостей, и теперь переменная $bulletin
включает в себя обе строки текста.
Типы строк
В PHP поддерживаются два типа строк, которые обозначаются типом используемых кавычек. Если требуется присвоить переменной значение текстовой строки, сохраняя ее точное содержимое, нужно воспользоваться одинарными кавычками (апострофами):
$info = 'Предваряйте имена переменных символом $, как в данном примере: $variable';
В данном случае переменной $info
присваивается каждый символ, находящийся внутри строки в одинарных кавычках. Если воспользоваться двойными кавычками, то PHP попытается вычислить $variable
и получить значение переменной. В то же время, если требуется включить в состав строки значение переменной, используется строка, заключенная в двойные кавычки:
echo "На этой неделе ваш профиль просмотрело $count человек ";
Из этого следует, что данный синтаксис предлагает более простую форму объединения, в которой для добавления одной строки к другой не нужно использовать символ точки или закрывать и снова открывать кавычки. Этот прием называется подстановкой переменной. Можно заметить, что в некоторых приложениях он используется довольно часто, а в других не применяется вообще.
Изменение предназначения символов
Иногда в строке должны содержаться символы, которые имеют специальное предназначение и могут быть неправильно интерпретированы. Например, следующая строка кода не будет работать, потому что вторая кавычка (апостроф), встреченная в слове spelling's, укажет PHP‑парсеру на то, что достигнут конец строки. Следовательно, вся остальная часть строки будет отвергнута как ошибочная:
$text = 'My spelling's atroshus'; // Ошибочный синтаксис
Для исправления ошибки нужно непосредственно перед вызывающим неоднозначное толкование символом кавычки добавить обратный слеш (\
), чтобы заставить PHP рассматривать этот символ буквально и не подвергать его интерпретации:
$text = 'My spelling\'s still atroshus';
Этот прием можно применить практически во всех ситуациях, где в противном случае PHP вернул бы ошибку, пытаясь интерпретировать символ. Например, следующая строка, заключенная в двойные кавычки, будет присвоена переменной без ошибок:
$text = "She wrote upon it, \"Return to sender\".";
Кроме того, для вставки в строку различных специальных символов, например табуляции, новой строки и возврата каретки, могут применяться управляющие символы: \t
, \n
и \r
соответственно. Вот пример, в котором символы табуляции используются для разметки заголовка (они включены в строку исключительно для иллюстрации применения символа обратного слеша, поскольку существуют более подходящие способы разметки веб-страниц):
$heading = "Дата\tИмя\tПлатеж";
Эти специальные символы, предваряемые символами обратного слеша, работают только в строках, заключенных в двойные кавычки. Если заключить предыдущую строку в одинарные кавычки, то вместо символов табуляции в ней будут отображены нелепые последовательности символов \t
. Внутри строк, заключенных в одинарные кавычки, в качестве символов с измененным предназначением распознаются только измененный апостроф (\'
) и сам измененный обратный слеш (\\
).
Многострочные команды
Иногда нужно вывести из PHP большой объем текста, а использование нескольких инструкций echo
(или print
) заняло бы много времени и было бы неразумным. PHP предлагает два удобных средства, предназначенных для того, чтобы справиться с подобной ситуацией. Первое из них состоит в заключении в кавычки нескольких строк. Переменным также можно присвоить значения способом, показанным в примерах ниже.
<?php $author = "Steve Ballmer"; echo "Developers, Developers, developers, developers, developers,developers, developers, developers, developers! - $author."; ?>
<?php $author = "Bill Gates"; $text = "Measuring programming progress by lines of code is like measuring aircraft building progress by weight. - $author."; ?>
В PHP можно также воспользоваться многострочной последовательностью, используя оператор <<<
, который обычно называют here-document («здесь документ») или heredoc. Он представляет собой способ указания строкового литерала, сохраняющего в тексте обрывы строк и другие пустые пространства (включая отступы). Его использование показано в примере, где еще один вариант инструкции echo
, использующей сразу несколько строк
<?php $author = "Brian W. Kernighan"; echo <<<_END Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it. - $author. _END; ?>
Этот код предписывает PHP вывести все, что находится между двумя тегами _END
, как будто все это является строкой, заключенной в двойные кавычки (за исключением того, что изменять предназначение кавычек в heredoc не нужно). Это означает, что разработчику можно, например, написать целый раздел HTML‑кода прямо в коде PHP, а затем заменить конкретные динамические части переменными PHP. Важно запомнить, что закрывающий тег _END;
должен появляться строго в начале новой строки и быть единственным содержимым этой строки — к ней не разрешается добавлять даже комментарии (нельзя ставить даже одиночный пробел). Как только многострочный блок закрыт, можно снова воспользоваться тем же самым именем тега.
Запомните: используя heredocಉконструкцию
<<<_END..._END;
, вы не должны добавлять символы\n
, чтобы отправить команду на перевод строки, достаточно просто нажать клавишу Enter и приступить к набору новой строки. В отличие от других строк, заключенных в одинарные или двойные кавычки, внутри конструкции heredoc можно по своему усмотрению совершенно свободно пользоваться всеми одинарными или двойными кавычками, не изменяя их первоначального предназначения с помощью обратного слеша (\
).
В примере, как использовать этот же синтаксис для присваивания переменной многострочного значения.
<?php $author = "Scott Adams"; $out = <<<_END Normal people believe that if it ain't broke, don't fix it. Engineers believe that if it ain't broke, it doesn't have enough features yet. - $author. _END; echo $out; ?>
После этого переменная $out
будет наполнена содержимым, размещенным между двумя тегами. Если не присваивать, а добавлять значение, то для добавления строки к значению переменной $out
вместо оператора =
можно воспользоваться оператором .=
. Будьте внимательны, не ставьте точку с запятой сразу же за первым тегом _END
, поскольку она прервет многострочный блок еще до его начала и вызовет сообщение об ошибке синтаксического разбора — Parse error
. Точку с запятой нужно ставить только после закрывающего тега _END
, хотя внутри блока можно свободно пользоваться точкой с запятой как обычным текстовым символом. Кстати, тег _END
— лишь один из многих, я выбрал его для этих примеров, поскольку его использование где-нибудь еще в коде PHP маловероятно, и поэтому он уникален. Вы можете использовать по собственному усмотрению любой тег, например _SECTION1
или _OUTPUT
и т.д. И еще, чтобы отличать подобные теги от переменных или функций, обычно в начале их имени ставят знак подчеркивания; но если не хотите, можете им не пользоваться.
Многострочную разметку текста можно рассматривать как удобное средство, упрощающее чтение вашего кода PHP, поскольку, как только текст отображается на веб-странице, вступают в силу правила форматирования HTML и пустые пространства скрываются (но имя переменной $author
по-прежнему заменяется ее значением в соответствии с правилами вставки значений переменных).
Допустим, если загрузить эти примеры многострочного вывода в браузер, они не будут отображены в виде нескольких строк, потому что все браузеры рассматривают символы новой строки просто как пробелы. Но если воспользоваться свойством браузера, позволяющим просматривать исходный код, обнаружится, что все символы новой строки правильно расставлены и вывод появляется на нескольких строках.
Типы переменных
PHP относится к очень слабо типизированным языкам. Это значит, что переменные не требуют объявления перед своим использованием и что PHP всегда преобразует переменные в тот тип, который требуется для их окружения на момент доступа к ним. Например, можно создать число, состоящее из нескольких цифр, и извлечь из него n-ю цифру, просто предположив, что это число является строкой. В следующем фрагменте кода перемножаются числа 12 345
и 67 890
и возвращается результат 838 102 050
, который затем помещается в переменную $number
.
<?php $number = 12345 * 67890; echo substr($number, 3, 1); ?>
Когда присваивается значение, $number
является числовой переменной. Но во второй строке кода вызов значения этой переменной помещен в PHP-функцию substr
, которая должна вернуть из переменной $number
один символ, стоящий на четвертой позиции (не забывайте, что в отсчет позиции начинается с нуля). Для выполнения этой задачи PHP превращает $number
в строку, состоящую из девяти символов, чтобы функция substr
могла получить к ней доступ и вернуть символ, в данном случае 1
. То же самое происходит при необходимости превратить строку в число и т.д. А в следующем примере переменной $pi
присвоено строковое значение, которое затем в третьей строке кода автоматически превращается в число с плавающей точкой, чтобы стать частью уравнения по вычислению площади круга, которое выводит значение 78,539 817 5
.
<?php $pi = "3.1415927"; $radius = 5; echo $pi * ($radius * $radius); ?>
На практике все это означает, что вам не стоит слишком волноваться за типы переменных. Им следует просто присвоить значения, имеющие для вас смысл, и PHP при необходимости их преобразует. Затем, если понадобится извлечь значение, их нужно просто запросить, например, с помощью инструкции echo
.
Константы
Константы, как и переменные, хранят информацию для последующего доступа, за исключением того, что они оправдывают свое название констант (постоянных). Иными словами, после определения констант их значения устанавливаются для всей остальной программы и не могут быть изменены. К примеру, константа может использоваться для хранения местоположения корневого каталога вашего сервера (папки, содержащей основные файлы вашего сайта). Определить такую константу можно следующим образом:
define("ROOT_LOCATION", "/usr/local/www/");
Затем для чтения содержимого константы нужно просто сослаться на нее как на обычную переменную (но не предваряя ее имя знаком доллара):
$directory = ROOT_LOCATION;
Теперь, как только понадобится запустить ваш PHP-код на другом сервере с другой конфигурацией папок, придется изменить только одну строку кода.
Важно помнить о двух основных особенностях констант: перед их именами не нужно ставить символ
$
(как перед именами обычных переменных) и их можно определить только с помощью функцииdefine
.
По общепринятому соглашению считается правилом хорошего тона использовать в именах констант буквы только верхнего регистра, особенно если ваш код будет также читать кто-нибудь другой.
Предопределенные константы
PHP поставляется в виде готового продукта, с десятками предопределенных констант, которые редко используют такие новички в программировании на PHP, как вы. Тем не менее существуют константы, известные как волшебные, которые могут оказаться для вас полезными с самого начала. У имен волшебных констант в начале и в конце всегда стоят два символа подчеркивания, чтобы нельзя было случайно назвать одну из собственных констант уже занятым под эти константы именем. Подробности о волшебных константах приведены в таблице "Волшебные константы PHP". Понятия, упомянутые в таблице, будут раскрыты в следующих главах.
Таблица. Волшебные константы PHP
Эти константы полезны при отладке, когда нужно вставить строку кода, чтобы понять, до какого места дошло выполнение программы:
echo "Это строка " . __LINE__ . " в файле " . __FILE__;
Эта команда выведет в браузер текущую строку программы с указанием текущего файла, исполняемого в данный момент (включая путь к нему).
Различие между командами echo и print
Нам уже встречались разнообразные способы использования команды echo
для вывода текста с сервера в браузер. В одних случаях выводится строковый литерал, в других сначала происходило объединение строк или вычисление значений переменных. Был также показан вывод, распространяющийся на несколько строк. Но команде echo
есть альтернатива, которой также можно воспользоваться: команда print
. Эти две команды очень похожи друг на друга, но print
— конструкция, похожая на функцию, воспринимающую единственный параметр и имеющую возвращаемое значение (которое всегда равно 1
), а echo
— в чистом виде конструкция языка PHP.
В общем, команда echo
работает при выводе обычного текста быстрее print
, поскольку она не устанавливает возвращаемое значение. С другой стороны, поскольку она не является функцией, ее, в отличие от print
, нельзя использовать как часть более сложного выражения. В следующем примере для вывода информации о том, является значение переменной истинным (TRUE
) или ложным (FALSE
), используется функция print
, но сделать то же самое с помощью команды echo
не представляется возможным, поскольку она выведет на экран сообщение об ошибке синтаксического разбора — Parse error
:
$b ? print "TRUE" : print "FALSE";
Использование вопросительного знака — самый простой способ задать вопрос о том, какое значение имеет переменная $b
, истинное или ложное. Команда, которая располагается слева от двоеточия, выполняется в том случае, если $b
имеет истинное значение, а команда, которая располагается справа, выполняется, если $b
имеет ложное значение. Тем не менее в приводимых здесь примерах чаще всего используется команда echo
, и я рекомендую применять именно ее до тех пор, пока вам при PHP‑разработке реально не потребуется задействовать функцию print
.
Функции
Функции используются для выделения блоков кода, выполняющих конкретную задачу. Например, если вам часто приходится искать какие-то данные и выводить их в определенном формате, то вполне разумно будет обратиться к функции. Код, выполняющий эту задачу, может занимать всего три строки, но, пока вы не воспользуетесь функцией, необходимость вставлять этот код в программу десятки раз делает ее неоправданно большой и сложной. А если вы чуть позже захотите изменить формат вывода данных, помещение кода в функцию будет означать, что вам придется внести изменения только в одном месте программы. Помещение кода в функцию не только сокращает размер исходного кода и делает его более удобным для чтения, но и дает дополнительные функциональные возможности (эта игра слов носит преднамеренный характер), поскольку функциям могут передаваться параметры, которые вносят изменения в характер их работы. Функции также могут возвращать значения вызывающему их коду. Чтобы создать функцию, нужно ее объявить, как показано в примере.
<?php function longdate($timestamp) { return date("l F jS Y", $timestamp); } ?>
Эта функция использует в качестве входных данных отметку времени системы UNIX (целое число, отображающее дату и время на основе количества секунд, прошедших с нуля часов 1 января 1970 года), а затем вызывает PHP-функцию date с нужным форматом строки, чтобы вернуть дату в формате «Вторник май 2 2017». Между стоящими после имени функции круглыми скобками может размещаться любое количество параметров, но для этой функции выбран прием только одного параметра. Весь код, который выполняется при последующем вызове функции, заключается в фигурные скобки. Чтобы с помощью этой функции вывести сегодняшнюю дату, нужно поместить в свой код следующий вызов:
echo longdate(time());
В этом вызове для извлечения текущей отметки времени UNIX и передачи ее только что созданной функции longdate, которая затем возвращает для отображения соответствующую строку команде echo, используется встроенная PHP-функция time. Если требуется вывести дату семнадцатидневной давности, нужно сделать следующий вызов:
echo longdate(time() - 17 * 24 * 60 * 60);
в котором функции longdate
передается текущая отметка времени UNIX, уменьшенная на количество секунд, которое прошло за 17 дней (17 дней, 24 ч, 60 мин, 60 с). Функции могут также воспринимать несколько параметров и возвращать несколько результатов, используя технологию, которая будет рассмотрена в следующих главах.
Область видимости переменной
Если программа очень длинная, то с подбором подходящих имен переменных могут возникнуть трудности, но, программируя на PHP, можно определить область видимости переменной. Иными словами, можно, к примеру, указать, что переменная $temp будет использоваться только внутри конкретной функции, чтобы забыть о том, что она после возврата из кода функции применяется где-нибудь еще. Фактически именно такой в PHP является по умолчанию область видимости переменных. В качестве альтернативы можно проинформировать PHP о том, что переменная имеет глобальную область видимости и доступ к ней может быть осуществлен из любого места программы.
Локальные переменные
Локальные переменные создаются внутри функции, и к ним имеется доступ только из кода этой функции. Обычно это временные переменные, которые используются до выхода из функции для хранения частично обработанных результатов. Одним из наборов локальных переменных является перечень аргументов функции. В предыдущем разделе была определена функция, воспринимающая параметр по имени $timestamp
. Значение этого параметра действительно только в теле функции, за пределами этой функции его значение нельзя ни получить, ни установить. Чтобы привести еще один пример локальной переменной, рассмотрим функцию longdate
еще раз в немного измененном варианте.
<?php function longdate($timestamp) { $temp = date("l F jS Y", $timestamp); return "Дата: $temp"; } ?>
В этом примере значение, возвращенное функцией date
, присваивается временной переменной $temp
, которая затем вставляется в строку, возвращаемую определяемой функцией. Как только будет осуществлен выход из функции, значение переменной $temp
удаляется, как будто она вообще никогда не использовалась. Теперь, чтобы посмотреть на области видимости переменных в действии, изучим похожий код, показанный в примере. Здесь переменная $temp
была создана еще до вызова функции longdate
.
Неудачная попытка получить доступ к переменной $temp в функции longdate
<?php $temp = "Дата: "; echo longdate(time()); function longdate($timestamp) { return $temp . date("l F jS Y", $timestamp); } ?>
Но поскольку переменная $temp
не была создана внутри функции longdate
, а также не была передана ей в качестве параметра, функция longdate
не может получить к ней доступ. Поэтому этот фрагмент кода выведет только дату без предшествующего ей текста. На самом деле сначала будет отображено сообщение об ошибке, предупреждающее об использовании неопределенной переменной (Notice: Undefined variable: temp
). Причина в том, что по умолчанию переменные, созданные внутри функции, являются локальными для этой функции, а переменные, созданные за пределами любой функции, могут быть доступны только из того кода, который не входит в код ни одной из функций. В примерах ниже показано несколько способов исправления кода, приведенного в примере выше. Решить проблему можно путем переноса ссылки на переменную $temp
в ее локальную область видимости
<?php $temp = "Дата: "; echo $temp . longdate(time()); function longdate($timestamp) { return date("l F jS Y", $timestamp); } ?>
Здесь ссылка на $temp
перемещена за пределы функции. Эта ссылка появляется в той же области видимости, в которой была определена переменная. Альтернативное решение: передача $temp
в качестве аргумента
<?php $temp = "Дата: "; echo longdate($temp, time()); function longdate($text, $timestamp) { return $text . date("l F jS Y", $timestamp); } ?>
Здесь принято другое решение: передать значение переменной $temp
функции longdate
в качестве дополнительного аргумента. Функция longdate считывает это значение во временную переменную, которую она создает под именем $text
, и выводит желаемый результат.
Программисты часто допускают ошибку, забывая об области видимости переменных, поэтому, если не помнить принципы ее работы, это поможет в отладке некоторых весьма не очевидных ошибок программного кода. Достаточно сказать, что, если вы не объявили переменную каким нибудь особым образом, ее область видимости ограничена локальным пространством: либо в пределах кода текущей функции, либо в пределах кода, не принадлежащего никаким функциям, в зависимости от того, где эта переменная была впервые создана или где к ней впервые был получен доступ, внутри функции или за ее пределами.
Глобальные переменные
Бывают случаи, когда требуется переменная, имеющая глобальную область видимости, поскольку нужно, чтобы к ней имелся доступ из всего кода программы. К тому же некоторые данные могут быть настолько объемными и сложными, что их не захочется передавать функциям в качестве аргументов. Чтобы объявить переменную, имеющую глобальную область видимости, используется ключевое слово global
. Предположим, что существует некий способ входа пользователей на ваш сайт и нужно, чтобы весь код программы знал, с кем он имеет дело — с зарегистрированным пользователем или с гостем. Один из способов решения этой задачи заключается в создании глобальной переменной $is_logged_in
:
global $is_logged_in;
Теперь вашей функции входа в систему нужно лишь при удачной попытке входа на сайт присвоить этой переменной значение 1
, а при неудачной попытке — значение 0
. Поскольку переменная обладает глобальной областью видимости, доступ к ней может быть получен из любой строки кода вашей программы.
Но пользоваться глобальными переменными нужно с оглядкой. Рекомендую создавать их только в том случае, если без них совершенно невозможно добиться нужного результата. Вообще-то программы, разбитые на небольшие фрагменты и отдельные данные, содержат меньше ошибок и проще в обслуживании. Если ваша программа состоит из нескольких тысяч строк кода (а когда-нибудь такое случится) и оказалось, что где-то глобальная переменная имеет неверное значение, то сколько времени уйдет на поиски кода, который присваивает ей это значение? Кроме того, если используется слишком много глобальных переменных, возникает риск воспользоваться одним из их имен еще раз в локальном пространстве или по крайней мере полагать, что такая переменная применяется локально, хотя на самом деле она уже была объявлена в качестве глобальной. Из таких ситуаций и возникают разные непонятные ошибки.
Иногда я придерживаюсь соглашения о написании имен всех глобальных переменных в верхнем регистре (что совпадает с рекомендациями о написании в этом же регистре имен констант), чтобы можно было с первого взгляда определить область видимости переменной.
Статические переменные
В пункте «Локальные переменные» выше было упомянуто, что значение переменной стирается сразу же после выхода из функции. Если функция вызывается многократно, она начинает свою работу со свежей копией переменной и ее прежние установки не имеют никакого значения. Интересно, а что, если внутри функции есть такая локальная переменная, к которой не должно быть доступа из других частей программы, но значение которой желательно сохранять до следующего вызова функции? Зачем? Возможно, потому, что нужен некий счетчик, чтобы следить за количеством вызовов функции. Решение, показанное ниже заключается в объявлении статической переменной.
<?php function test() { static $count = 0; echo $count; $count++; } ?>
В этом примере в самой первой строке функции создается статическая переменная по имени $count
, которой присваивается нулевое начальное значение. В следующей строке выводится значение переменной, а в последней строке это значение увеличивается на единицу. При следующем вызове функции, поскольку переменная $count
уже была объявлена, первая строка функции пропускается и до нового увеличения значения
переменной $count
отображается ее предыдущее значение.
Планируя использование статических переменных, следует учесть, что при их определении присвоить им результат какого-нибудь выражения невозможно. Они могут инициализироваться только предопределенными значениями:
<?php static $int = 0; // Допустимо static $int = 1+2; // Недопустимо (вызовет ошибку синтаксического разбора (Parse error)) static $int = sqrt(144); // Недопустимо ?>
Суперглобальные переменные
Начиная с версии PHP 4.1.0, стали доступны некоторые предопределенные переменные. Они известны как суперглобальные переменные. Смысл этого названия заключается в том, что они предоставляются средой окружения PHP и имеют глобальную область видимости внутри программы, то есть доступны абсолютно из любого ее места.
В этих суперглобальных переменных содержится масса полезной информации о текущей работающей программе и ее окружении (таблице "Суперглобальные переменные PHP"). Такие переменные имеют структуру ассоциативных массивов, которые будут рассмотрены в главе 6.
Таблица. Суперглобальные переменные PHP
В именах всех суперглобальных переменных (за исключением $GLOBALS
) присутствует один знак подчеркивания и используются только заглавные буквы, поэтому, чтобы избежать путаницы, не следует присваивать своим переменным имена, оформленные в таком же стиле. Для иллюстрации порядка применения суперглобальных переменных рассмотрим часть той информации, которая может быть использована сайтами. Среди многой другой интересной информации, предоставляемой суперглобальными переменными, есть и URL‑адрес той страницы, с которой пользователь был перенаправлен на текущую веб-страницу. Эта информация может быть получена следующим образом:
$came_from = $_SERVER['HTTP_REFERRER'];
Как видите, ничего сложного. Если же пользователь зашел непосредственно на вашу страницу, к примеру набрав ее URL‑адрес непосредственно в браузере, переменной $came_from
будет присвоена пустая строка.
Суперглобальные переменные и проблемы безопасности
Обратите внимание, что суперглобальные переменные часто используются злоумышленниками, пытающимися отыскать средства для атаки и вмешательства в работу вашего сайта. Они загружают в $_POST
, $_GET
или в другие суперглобальные переменные вредоносный код, например команды UNIX или MySQL, которые, если вы по незнанию к ним обратитесь, могут разрушить или отобразить незащищенные данные. Именно поэтому перед применением суперглобальных переменных их всегда следует подвергать предварительной обработке. Для этого можно воспользоваться PHP‑функцией htmlentities
. Она занимается преобразованием всех символов в элементы HTML. Например, символы «меньше» и «больше» (<
и >
) превращаются в строки < и >, то же самое делается для перевода в безопасное состояние всех кавычек, обратных слешей и т. д. Поэтому более подходящий способ доступа к $_SERVER
(и другим суперглобальным переменным) выглядит следующим образом:
$came_from = htmlentities($_SERVER['HTTP_REFERRER']);
Использование для санации функции
htmlentities
считается важной практикой не только в отношении суперглобальных переменных, но и при любых обстоятельствах, в которых данные, исходящие от пользователя или поступающие из сторонних источников, обрабатываются для получения выходных данных.
В этом уроке были заложены надежные основы, необходимые для работы с PHP. Далее мы приступим к практическому использованию изученного материала для построения выражений и управления ходом программы, иными словами, перейдем к реальному программированию. Но перед новым уроком я рекомендую проверить свои знания, ответив на приведенные вопросы, чтобы убедиться в том, что вы полностью усвоили этот урок.