Московский Государственный Технический Университет

имени Н.Э.Баумана

Кафедра САПР


PHP после C/C++

Федорук В.Г.
Содержание

PHP (PHP Hypertext Processor) - язык программирования, используемый, главным образом, для динамической генерации HTML-страниц на стороне web-сервера. Хотя существует возможность автономного использования PHP-интерпретатора (PHP-машины) для выполнения несложных программ общего назначения. Однако, с момента своего появления (1994г.) PHP развивался с однозначной ориентацией на разработку www-систем, интегрируя в себе все современные Internet (и не только) технологии.

Среда программирования и исполнения PHP представляет собой свободно распространяемое в исходных текстах ПО, хотя и существует коммерческая компания Zend Technologies, взявшая на себя обязанности по сопровождению и расширению PHP.

Для интеграции PHP-машины в web-сервер (речь здесь и далее идет только об Apache) существует два пути.

Основные отличия PHP от C, C++ и Java:

Пример динамической HTML-страницы.


<HTML>
<HEAD>
<TITLE>Простой пример</TITLE>
</HEAD>
<?php
    if (strstr ($HTTP_USER_AGENT, "MSIE") ) {
?>
У Вас могут быть <B>большие</B> проблемы
<?php
      }
     else {
?>
 Вы избежали больших проблем
<?php
      };
     echo "<BR>";
?>

Здесь $HTTP_USER_AGENT - одна из многих доступных предопределенных переменных, "MSIE" - строка символов, strstr - одна из многих функций для работы со строками.

<?php ... ?> - HTML-теги, ограничивающие PHP-код (существуют и другие способы маркировки включаемого PHP-текста, но этот наиболее предпочтительный).

Синтаксис языка PHP

Языковые конструкции PHP имеют в своей основе синтаксис языка C, что облегчает освоение нового для нас языка.

Комментарии

PHP поддерживает 3 вида комментариев:

Переменные

В отличие от типизированных языков (C, C++, Java) тип переменной в PHP не фиксируется (вспоминаем Prolog, Lisp) - в ходе выполнения программы одна и та же переменная может принимать значения разных типов.

Имя переменной в PHP состоит из символа $ и идентификатора. Идентификатор начинается с буквы или символа подчеркивания, далее - произвольное количество букв, цифр и знаков подчеркивания. Заметим, что в именах переменных допустимо использование символов кириллицы.

Обычная переменная "порождается" в момент ее первого использования (как правило, присвоения ей какого-либо значения) и существует до конца выполнения программы/функции. При необходимости переменная может быть удалена оператором unset(). [???]

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

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

Простые типы данных

К простым в PHP относятся следующие 4 типа данных:

Логические переменные

Переменные этого типа могут принимать только 2 значения: FALSE и TRUE (регистр символов роли не играет).

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

Все прочие значения трактуются как TRUE. Для явного приведения к логическому типу используются конструкции (boolean) и (bool). Однако в большинстве случаев этого не требуется, т.к., если оператор, функция или управляющая конструкция языка требует аргумент логического типа, то конвертирование в этот тип производится автоматически.

Целые числа

Целые числа - величины знаковые, диапазон их допустимых значений зависит (как и в C) от архитектуры вычмслительных средств (типично, это 4 байта). При выходе за диапазон представления число автоматически преобразуется в действительное. Используются следующие правила приведения к целочисленному типу.

Для проверки типа значения переменной на целочисленность используется функция is_long(). Для явного приведения значения к данному типу используются конструкции (int) и (integer).

Действительные числа

Представление чисел с плавающей запятой зависит от используемой вычислительной архитектуры, но, как правило, это 64-битный формат IEEE 754. Проверить, содержит ли переменная действительное значение, можно с помощью функции is_double(). Для приведения к действительному типу используются конструкции (double), (float) и (real).

При вычислении выражений, содержащих действительные и целые числа, результатом будет действительное число.

Строки

В PHP (как и в C/C++) строки - это последовательности байт. Как правило, строки состоят из визуализируемых алфавитно-цифровых символов.

В литеральном представлении строки заключаются в двойные или одинарные (апострофы) кавычки. Если строка ограничена двойными кавычками, то в ней производится подстановка значений переменных на места их имен. В состав таких строк могут быть включены произвольные байты с помощью следующих esc-последовательностей: \n, \r, \t, \\, \", \', \$, \[0-7]{3}, \[0-9A-Fa-f]{2}.

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

Существует и третий способ задания строк, заимствованный из оболочек UNIX (там он называется втроенным документом). Этот способ особенно удобен для представления "длинных" текстов. Этот способ подразумевает использование следующей конструкции:


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

$var = "очень";
$var = "$var - $var";
$var = <<<EOD
Это $var
"длинная"
строка
EOD

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

Для исключения возможных колизий при включении переменных в строки возможно использование приема, также заимствованного из оболочек UNIX, - заключение идентификаторов переменных в фигурные скобки, например, ${var}. PHP предлагает и более "хитрую" конструкцию {$var}, тонкости которой здесь обсуждаться не будут.

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


$var = 1 + "3.14";	// действит. число 4,14
$var = 1 + "PI";	// целое число 1
$var = 1 + "3 поросенка" + "12 негритят";	// целое число 16
$var = 1 + "3.14 поросенка" + "12 негритят";	// действит. число 16,14
$var = 1 + "PI поросенка" + "1.2e1 негритят";	// действит. число 13,0

Проверить, содержит ли переменная строковое значение, можно с помощью функции is_string(). Для приведения к строковому типу используется конструкция (string).

Операторы

В PHP реализованы все операторы языка C и добавлено несколько новых.

Операторы сравнения === (идентично) и !== (не идентично) сравнивают не только значения переменных/литералов, приводя их к единому типу, но и сравнивают типы переменных, например:


1 == "1";	// Результат TRUE
1 === "1";	// Результат FALSE
1 !== "1";	// Результат TRUE

Операторы . и .= осуществляют конкатенацию (слияние) строк, например:


$a = "CAD";
$b = "CAM";
$a .= "/".$b;	// Результат - "CAD/CAM"

PHP содержит один единственный оператор @ , предназначенный для обработки ошибочных ситуаций. Если оператор @ прописан в начале некоторого выражения, то любое сообщение об ошибке, генерируемое этим выражением, подавляется. Однако, если в PHP-машине включен механизм регистрации ошибок, то сообщение о последней ошибке можно извлечь из глобальной переменной $php_errormsg.

PHP заимствовал в оболочках UNIX и конструкцию `команда-ОС`. Встретив такую конструкцию PHP-машина пытается выполнить соответствующую команду операционной системы, заместив стандартным выводом команды саму конструкцию, например:


$abc = `ls -l`;
echo "<PRE>$abc</PRE>"; 

Переменные

Константы

Но начнем с констант. Константы в PHP именуются только идентификаторами (без лидирующего символа $). Программист создает константы, используя функцию define(), например


 define ("CONST", "\"три\"");
 echo "На экзаменах я всегда получаю ".CONST."<BR>";

PHP предоставляет большое количество предопределенных констант, некоторые из которых описаны ниже.

Переменные как имена переменных

Поскольку язык PHP - язык интерпретируемый, то нет ничего удивительного в том, что имена переменных может формироваться в PHP-программах динамически, например:


 $cad = "cae";
 $$cad = "cam";		// Аналогично $cae = "cam";
 echo "$cad/$$cad";	// Результат - "cae/cam"

Для исключения возможной неоднозначности в трактовке имен используются фигурные скобки, например, ${$cad}.

Ссылки

В отличие от языка C в PHP нет указателей и, следовательно, нет арифметики указателей. Но в PHP есть ссылки на переменные, используемые для реализации синонимов при обращении к переменным, что полезно для исключения копирования больших объемов данных (в первую очередь, при вызове функций и получении из них результатов). Ссылки организуются оператором &, как показано в примере:


$a = "Я в единственном экземпляре<BR>";
$b = $c = &$a;
echo $a;	// Строка "Я в единственном экземпляре"
echo $b;	// будет выведена
echo $c;	// 3 раза

Ставший ненужным синоним можно можно уничтожить, удалив переменную, используя функцию unset(), например:


unset ($b);
unset ($c);

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

Предопределенные переменные

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


<?php
  phpinfo();
?>

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

Переменные окружения

Эти предопределенные переменные попросту импортируются из ОС (в их состав входят $HOME, $USER, $LANG и т.д.).

Переменные PHP-машины

Следующие предопределенные переменные обеспечиваются PHP-машиной.

Переменные сервера Apache

Ниже описываются некоторые переменые, обеспечиваемые HTTP-сервером Apache.

Переменные HTML-формы

При вызове HTML-страницы, содержащей PHP-программу, для обработки экранной формы все переменные этой формы автоматически становятся доступными программе. При этом, если включен режим track_vars, эти переменные будут будут размещаться в ассоциативных массивах $HTTP_POST_VARS, $HTTP_GET_VARS, $HTTP_POST_FILES.

Например, при использовании формы


<FORM ACTION="form_proc.php" METHOD="POST">
    Ваше имя: <INPUT TYPE="text" NAME="username"><BR>
    <INPUT TYPE="submit">
 </FORM>
в программе form_proc.php значение текстового поля будет доступно как элемент ассоциативного массива $HTTP_POST_VARS["username"]. Если же дополнительно включен режим register_globals, то это же значение можно получить, используя глобальную переменную $username.

Для графических элементов формы дополнительно можно получить координаты точки "нажатия" внутри изображения, используя переменные $имя-элемента_x и $имя-элемента_y. Допустимо также родственные элементы формы группировать в переменную-массив.

Управляющие структуры

В PHP реализованы все управляющие структуры языка C (if, for, while, do..while, switch). При этом структура if расширена конструкцией elseif, как это показано ниже:


if ($a == $b) {
  echo "равно";
  }
 elseif ($a > $b) {
  echo "больше";
  }
 else {
  echo "меньше";
  };

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

Оператор require()

Оператор require() заставляет PHP-машину однократно включить в программу содержимое указанного файла на место оператора (что очень похоже на директиву #include языка C). При этом на время включения файла PHP-машина переходит в режим HTML. Поэтому при необходимости включить PHP-код, его во включаемом файле необходимо отметить тегами <?php ... ?>.

PHP-код включаемого файла (если он там есть) наследует область видимости переменных, определенную в точке выполнения оператора require(). Если в качестве аргумента оператора указывается URL файла, содержащего PHP-код, то появляется возможность передать во включаемый файл переменные методом GET (в этом случае включаемый код фактически выполняется на удаленном сервере, а в вызывающую программу возвращается результат).

Оператор require_once() гарантирует, что каждый включаемый файл окажется во включающей программе только в одном экземпляре, что позволяет избежать переопределений констант и функций. А такая ситуация возможна, когда файл a.inc включается в файл b.inc, а оба эти файла включаются в программу c.php.

Оператор include()

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


$rc = include("func.inc");
или даже

$rc = include("HTTP://someserver/func.php?a=1&b=1");

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

Массивы

Массивы в PHP ассоциативны - доступ к их элементам осуществляется по ключу, а не по индексу, как это имеет место в C. Это, конечно, медленнее, но не на очень много, поскольку используется хэш-механизм. Зато появляется возможность организации на базе массивов таких структур данных, как стек, очередьm список, словарь и т.п. А поскольку элементы массива могут принимать значения любого типа, то с их помощью можно организовывать многомерные массивы, деревья и т.д.

Создание массива

Для создания массива используется конструкция языка PHP array(), имеющая следующий вид:


array array([[ключ =>] значение ,...])
, где значение - любой допустимый в PHP объект, а необязательный ключ - натуральное число или строка.

array() без аргументов создает пустой массив. Массивы в PHP не обязаны быть однородными. Если при создании нового элемента массива ключ не указан, то он автоматически принимает значение на 1 больше уже существующего в массиве целочисленного ключа. Если в массиве целочисленных ключей еще нет, то новый ключ получит значение 0. При создании нового элемента с ключом, дублирующим уже существующий в массиве, новое значение заменит старое значение элемента массива.

Пример создания массива.


vect = array("one"=>1, 2, 3, "four"=>4, 1=>"five");

В результате будет создан следующий массив:


 ["one"] => 1
        [0] => 2
        [1] => "five"
["four"] => 4

Изменение массива

Для модификации элементов массива (или его создания, если массив еще не существует) используется привычная конструкция


имя_массива[ключ] = значение

Создание массива $vect из предыдущего примера можно реализовать следующей последовательностью команд:


$vect["one"] = 1;
$vect[] = 2;
$vect[] = 3;
$vect["four"] = 4;
$vect[1] = "five";

Для удаления элемента массива достаточно присвоить ему значение NULL или выполнить функцию unset(). [???]

Проверить, является ли значением некоторой переменной массив, можно с помощью функции is_array().

Итерирование по массиву

Для получения последовательного доступа ко всем элементам массива используется управляющая конструкция foreach (для каждого), имеющая следующий вид:


foreach (array_выражение as [$ключ =>] $значение) { блок_кода }

Здесь array_выражение - выражение, имеющее своим результатом массив; $значение - имя переменной, получающей значение очередного элемента этого массива; $ключ - имя переменной, получающей значение ключа для очередного элемента массива.

Функции для работы с массивами

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

Массивы как стеки и очереди

Четыре основные функции для организации этих структур данных представлены ниже.

Пары функций array_push()/array_pop() и array_unshift()/array_shift() обеспечивают функциональность структуры данных "стек".

Пары функций array_push()/array_shift() и array_unshift()/array_pop() обеспечивают функциональность структуры данных "очередь".

Сортировка массивов

Здесь рассматриваются только 5 из многих функций сортировки.

Функции пользователя

Для определения функции в PHP используется следующая конструкция:


function fname ($arg1[, ..., $argN]) {
	тело функции
	[return $retval;]
	};
Здесь fname - уникальное имя функции, конструируемое по правилам построения идентификаторов языка PHP. Отметим, что переопределение функций в PHP недопустимо.

$arg1, ..., $argN - переменные-аргументы функции. PHP допускает переменное количество аргументов функций, а также автоматическую подстановку значений "по умолчанию".

Если не указано иначе, передача параметров в функции осуществляется "по значению". Это означает, что перед обращением к телу функции создаются копии всех аргументов функции. Именно с этими копиями имеет дело код функции.

Для передачи какого-либо аргумента функции "по ссылке" в определении функции перед именем этого аргумента необходимо разместить символ &.

Для возврата значения-результата из функции используется оператор


return $retval;

Для организации возврата результата из функции "по ссылке" в ее определении перед именем функции должен распологаться символ &. Этот же символ должен предшествовать имени функции при ее вызове в операторе присваивания.

PHP в отлтчие от C/C++ не требует предварительного объявления функции перед ее использованием, достаточно того, что PHP-интерпретатор "натолкнулся" на определение функции в любом месте программы (даже текстуально после обращения к ней).

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

Для задания умолчательных значений аргументов функций используется конструкция


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

function exam ($name, $rez='"два"') {
  echo "Студент $name на экзамене получил оценку $rez<BR>\n";
  };

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


function f1() {
  echo "Я функция f1 без аргументов.<BR>\n";
  };
function f2($arg) {
  echo "Я функция f2 с аргументом $arg.<BR>\n";
  };
$func = "f1";
$func();
$func = "f2";
$func("abc");

Основное назначение данного механизма - организация callback-функций (используемых, например, при сортировке массивов по алгоритму пользователя).

Для работы со списками аргументов функций переменной длины PHP предлагает следующие три функции:

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

Объектная модель

Для определения класса в PHP используется следующая конструкция:


class cname [extends pname] {
	определение переменных
		и
	методов (функций-членов) класса
	};
, где cname - имя определяемого класса, конструируемое по правилам построения идентификаторов PHP. pname - имя родительского класса (если таковой имеется у вновь определяемого класса).

Из синтаксиса определения класса ясно, что PHP множественного наследования не допускает.

Определение переменной осуществляется конструкцией вида


var $name [= выражение];
, где $name - имя переменной, а выражение - обязательно константное выражение, значением которого инициализируется переменная при создании объекта класса.

Все переменные, определенные в классе, являются переменными экземпляра, переменных класса в PHP нет.

Для создания объекта (экземпляра класса), как обычно, используется оператор new.

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

Ниже дан фрагмент PHP-программы, определяющий класс Circle (класс окружностей).


class Circle {
	var $x;
	var $y;
	var $r = 1.0;
	function Circle ($x, $y, $r = 2.0) {
		$this->x = $x;
		$this->y = $y;
		$this->r = $r;
		};
	function area () {
		return 3.14159*$this->r*$this->r;
		};
	};

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


$this->идентификатор
, где идентификатор - идентификатор переменной (имя переменной без лидирующего символа &).

Для доступа к членам экземпляра класса используется конструкция вида


$var->item_name
, где $var - имя переменной-объекта (экземпляра класса), а item_name - имя члена (переменной или функции) класса, например:

$c1 = new Circle;
$c1->r = 12.5;
$s = $c1->area();
echo "Площадь окружности радиусом $c1->r равна $s <BR>\n";

Для доступа к функции-члену класса без создания экземпляра класса используется следующая конструкция:


cname::fname(...);
, где cname - имя класса, fname - имя функции-члена класса.

В ситуации, когда функция класса-потомка должна обратиться к одноименной функции класса-предка, используется префикс parent::.