Скрипт язык PHP/FI

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

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

Синтаксис

Каждая команда PHP начинается с тэга <? и оконивается >. Или, команды могут быть сгруппированы внутри одной пары <? > и отделяться друг от друга символом ; .

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

	<?$a = 5>
	<?echo $a>

Это можно записать, также в виде:

	<; $a = 5; echo $a >

Или даже:

	<
	$a = 5;
	echo $a;
	>

Лишние символы пробела, табуляции и новой строки игнорируются. Это предложение должно использовать, чтобы форматировать блоки программы PHP, чтобы сделать их более удобочитаемыми. Регистр написания имеет значение для имен переменных, но не для имен к функций. Позже в этой документации, при обзоре функций , регистр используется только для того, чтобы сделать имена функций более читабельными. В фактической программе Вы можете использовать любой регистр, который пожелаете. Комментарии поддерживаются. Комментарии записываются точно так же как комментарии в Языке C. /* начинает комментарий, и */ заканчивает комментарий. Комментарии могут быть помещены в любом месте внутри блока <? ... >.

Переменные

Поддерживаются три типа переменных . Длинные целые (long int) , двойной точности с плавающей запятой (double) и символьные строки (strings). Тип переменных обнаруживается автоматически. Например:

	<?$a = 5>

Заставляет $a стать переменной типа INTEGER.

	<?$a = 5.0>

Заставляет $a стать переменной типа DOUBLE.

	<?$a = "5">

Заставляет $a стать переменной типа STRING.

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

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

	<?
	$a[0] = 5;
	$a["hello"] = 6;
	echo $a[0];
	echo $a["hello"];
	>

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

	$a = 1;

Это тоже самое что:

	$a[0] = 1;

PHP/FI также поддерживает не-индексированные массивы. Не-индексированный массив генерирует собственный индекс, по мере добавления элементов к нему. Например:

	$a[] = "Hello";
	$a[] = "There";

Первому элементу, вставляемому в не-индексированный массив, всегда присваивается индекс 0, второму 1 индекс, и т.д. Следовательно вышеупомянутые элементы могут быть распечатаны с помощью:

	echo $a[0];
	echo $a[1];

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

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

	$a = $b + $c;

Может вести себя двояко. Если $b это число, то числовое значение $c добавляется к $b, и сумма сохраняется в $a. В этом случае тип $c не важен. Операция управляется типом первой переменной. Если $b строка, то значение строки $c сонкатенируется с $b, и результирующая строка помещается в $a. Это также приводит к некоторым недоразумениям. Вам нужно прочесть раздел по перегруженным операторам, чтобы получить лучше понимание этого факта.

Ассоциативные массивы

В предыдущем разделе мы познакомились с ассоциативными массивами. Ассоциативный массив - это массив, в котором индекс не обязательно должен быть последовательным рядом числовых значений. Индексом массива может быть любое число или строка. PHP/FI обеспечивает набор функций, чтобы манипулирования этими ассоциативными массивами. Это: Next(), Prev(), Reset(), End(), и Key().

Ссылки на переменные

Иногда удобно иметь способ ссылаться на имена переменных . То есть имя переменной может установливаться и использоваться динамически. Нормальной переменной присваивается значение оператором типа:

	$a = "hello";

При использовании ссылки на переменную берется значение переменной и обрабатывается как имя переменной. В вышеупомянутом примере, hello, может использоваться как имя переменной, используя два знака $. То есть.

	$$a = "world";

На этот момент определены две переменных и сохранены в дереве символов PHP/FI:

	Имя переменной	Содержимое переменной
	a	hello
	hello      	hello world

Следовательно, оператор:

	echo "$a $$a";

Произведет точно такой же вывод как и:

echo "$a $hello";

То есть. Они выведут строку: hello world

Конструкции Языка

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

  • if(условие)
  • else
  • elseif(условие)
  • endif
  • switch(выражение)
  • case выражение
  • default
  • break
  • endswitch
  • while
  • endwhile
  • include
  • exit
Синтаксис условных выражений подобен синтаксису в языке C. == проверка на равенство.!= означает не равно. Также поддерживаются: >, <, >=, <=. Условное И - &&, условное ИЛИ - ||.

Примеры:

	<?
	if($a==5 &&  $b!=0 );
	$c = 100 + $a / $b;
	endif;
	>

Этот пример может быть записан в стандартном синтаксисе C:

	<?
	if($a==5 && $b!=0) {
	$c = 100 + $a / $b;
	}
>

Нет никакого различия между двумя синтаксисами. Мне лично больше нравится использовать endif, endswitch и endwhile, так что я точно знаю, какую конструкцию я заканчиваю. Однако, эти конструкции окончания могут быть всегда заменены на закрывающую фигурную скобку.

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

	<?if($a==5 &&  $b!=0)>
		<b>Normal html text</b>
	<?endif>

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

	<?if($a==5 &&  $b!=0) {>
	<b>Normal html text</b>
	<? } >

Обе версии верны, и они будут делать одно и тоже.

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

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

	<?
	Function Test (
	  echo "This is a test\n";
	);
	>

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

	<?
	  Test();
	>

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

	<?
	  Function Sum $a,$b,$c (
	  return($a+$b+$c);
	);

	echo Sum($a,$b,$c);
	>

Оператор return используется для возврата значения из функции. Только одиночное значение может быть передано, используя этот механизм, однако, если должно передаваться большее количество значений между функцией и основным кодом, то для этой цели могут быть использованы глобальные переменные. Это приводит нас к разделу по области видимости переменных.

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

Область видимости переменной это контекст, внутри которого она определена. Главным образом все переменные PHP/FI имеют только одину область. Однако, внутри определяемых пользователем функций действует локальная для функции область видимости. Любая переменная, используемая внутри функции по умолчанию ограничена локальной областью видимости. Например:

	$a=1; /* глобальная переменная */
	Function Test (
	   echo $a;/* ссылка на локальную переменную */
	);
	Test();

Эта программа ничего не выведет, так как оператор echo работает с локальной версией переменной $a , и ей не было присвоено значение внутри этой области видимости. Вы можете обратить внимание, что это немного отличается от языка C, где глобальные переменные автоматически доступны функциям, если только специально не отменяются локальным определением. Это может вызвать некоторые проблемы, в случае когда люди могут неосторожно изменять глобальную переменную. В PHP/FI глобальная переменная должна быть объявлена глобальной внутри функции, если предполагается что она будет использоваться в этой функции. Пример:

	$a=1;
	$b=2;
	Function Sum $first,$second (
	   global $a,$b;

	   $b = $a + $b;
	);
	Sum();
	echo $b;

Эта прграмма выведет "3". После объявления $a и $b глобальными внутри функции, все ссылки к любой из них будут относится к их глобальной версии. Нет никакого ограничения на число глобальных переменных, которые могут использоваться функцией. Однако, переменная должна существовать в глобальной области видимости до вызова функции. Нельзя создать новые глобальные переменные изнутри функции.

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

	Function Test (
	  $a=0;
	  echo $a;
	  $a++;
	);

Эта функция совершенно бесполезна, так как, каждый раз при вызове, она устанавливает $a в 0 и печатает "0". Оператор $a++, который увеличивает переменную, не дает никакого результата, так как, как только проиходит выход из функции переменная $a исчезает. Чтобы сделать полезную функцию подсчета, которая не будет терять значения текущего счетчика, переменная $a объявляется статической:

	Function Test (
	  static $a=0;
	  echo $a;
	  $a++;
	);

Теперь, каждый раз при вызове функции Test(), она будет печатать значение $a и затем увеличивать его.

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

	Function Test (
	  static $count=0;

	  $count++;
	  echo $count;
	  if($count < 10 {
	    Test();
	  }
	);

Математические Выражения

PHP поддерживает полный набор математических операций, в выражениях. Учитывается порядок операций. Следующие операторы допустимы:

	<? $a = 2 + 1 > Сложение
	<? $a = 2 - 1 > Bычитание
	<? $a = 2 * 1 > Умножение
	<? $a = 2 / 1 > Деление
	<? $a = 2 % 1 > Деление по модулю

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

	<?$a = (2"+1")*3+6/3>

Поддерживаются C-подобные операторы увеличения += и уменьшения -= . То есть.

	<? $a += $b>

Это эквивалентно:

	<? $a = $a + $b>

Поддерживаются C-подобные поразрядные операторы =& и |=. То есть.

	<? $a &== 4>

Это эквивалентно:

<? $a = $a &  4>

Циклы While

Вы можете зацикливать управление внутри программы PHP, используя конструкцию while(); endwhile;.

	<?
	  $a=0;
	  while($a <100) {
		$a++;
		echo $list[$a];
	  }
	>

Вышеупомянутый пример показывает использование цикла while, чтобы отобразить содержимое массива. ПРЕДУПРЕЖДЕНИЕ, хотя язык PHP поддерживает операторы типа ++ и -- для увеличения или уменьшения переменной, они не обрабатываются точно так же как в языке C . В PHP нет концепции пре- и пост- инкрементирования как это есть в С. Как объяснянолось в разделе Конструкции Языка, выше, тоже может быть получено и с циклом while(); endwhile;.

Конструкция Switch

PHP поддерживает switch конструкцию очень похожую на эквивалентную в C.

<? $a=0; switch($a) { case 1; echo "a is 1"; break; case "hello"; echo "a is hello"; break; default; echo "a is unknown"; break; } >

Выше - пример конструкции switch. Она подобна последовательности конструкций if/elseif/else, но более легко читаема. Единственое различие между конструкцией switch PHP и подобным ему в C - это, что в конце каждой строки используется точка с запятой. Нет никаких двоеточий. Как объяснялось в раздел Конструкции Языка, выше, тот же самое может быть получено с switch(); endswitch;.

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

Безопасные Переменные - Победа над взломами метода GET

В предыдущих разделах говорилось относительно методво GET и POST и переменных. Если Вы задумаетесь об этом, Вы можете увидеть проблемы защиты. Например, если я на web странице получаю некоторые данные из базы данных и передаю эти данные дальше в переменной с именем "data" через форму методом POST. В следующей странице я могу обращаться к этой переменной и что-то с ней делать. Однако, если кто-либо обратится к этой второй странице непосредственно и поместит "?data=something" прямо после URL, то переменная устанавливается методом GET, они действительно обошли оригинальную форму POST.

PHP предоставляет функцию SecureVar(), которая используется для того, чтобы отметить имена переменных как безопасные. Эти безопасные переменные могут быть установлены только непосредственно в программе PHP, либо получены из формы методом POST. Они не могут быть установлены с использованием механизма определения переменной методом GET. Из нашего сценария выше, если мы поместим строку:

	<?SecureVar("data")>

Где-нибудь в начале нашей второй страницы, то прием с методом GET не cработает. Переменная "data", появилась бы пустой, если бы не была получена непосредственно из формы методом POST на первой странице.

SecureVar() фактически принимает в качестве аргумента регулярное выражение, так что можно задавать образцы имен переменных, которые должны обработываться этим безопасным способом. Например,

	<?SecureVar(".*data.*")>
Отметит любую переменную со словом "data" где-нибудь в имени, как являющуюся безопасной.

Пожалуйста обратите внимание, что формам метода POST не свойственно безопасность. Люди могут подражать передаче любых данных методом POST просто выполнив команду telnet на HTTP порт вашей системы. Вы должны принять соответствующие меры защиты, чтобы такую возможность, если есть заинтересованность фактической защите.

Перегруженные Операторы и работа с типами данных

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

Проблема состоит в том, что PHP понимает 3 типа переменных. Integer, Double и String. Когда переменной впервые присваивается значение, PHP автоматически оперделяет тип этой переменной.

То есть.

	$a = 1; 	Тип будет integer
	$b = 1.5; 	Тип будет double
	$c = "1";	Тип будет string

Теперь, что произойдет, если Вы сделаете что-нибудь вроде:

	$d = $a + $c;

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

	$d = 2 	Тип integer

Следовательно:

$d = $c + $a

Результаты в:

	$d = "11"	Тип - string

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

Решение состоит в механизм простого приведения типа .

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

	$a = 1;

Внутри в таблице идентификаторов я сохраняю 3 версии.

	Integer:  1  <--- flag
	Double: 1.0
	String: "1"

Функция SetType() может перемещать флажок, указывающий тип переменной.

	SetType($a,"double");

Это вынудит рассматривать $a, как double в дальнейшем.

Функция GetType() возвращает тип.

GetType($a) вернет, в этом случае, "double" .

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

	IntVal($a)	вернет  1
	DoubleVal($a)	вернет   1.0
	StrVal($a)	вернет   "1"

Перегруженный оператор не изменяет характер переменных PHP, но дает Вам некоторые инструментальные средства, для лучшей работы с ними. PHP - не нечто, что напоминало бы не вполне развитый Perl. PHP должен быть малым и быстрым. Perl имеет дело ловушкой перегруженных операторов, заставляя оператор вроде '+' работать только с числами. Если Вы суммировать строки, нужно использовать оператор '.'. Как только появляются отдельные операторы для каждого типа, это делает язык намного более сложным. То есть. Вы не можете использовать '==' для строк, Вам придется использовать 'eq'. Я не вижу смысла, особенно для чего-то вроде PHP, где большинство скриптов будут довольно простыми и в большинстве случаев, написанными непрограммистами, которые хотят язык с базовым логичным синтаксисом, который не требует больших навыков.

Подавление Ошибок при обращении к функциям

Иногда бывает желательно игнорировать фатальные ошибки, о которых могут сообщать специфические функции PHP. Например, Вы захотите игнорировать ошибки от вызова dbmopen() и просто проверять возвращаемое значение обращения, без того, чтобы сообщение об ошибке появлялось на экране web. Это может быть сделано, помещая символ "@" перед именем функции. То есть.

	$err_code = @dbmopen($filename,"w");

Реальное сообщение об ошибке, которое должно было бы быть выведено, может быть проверено во внутренней переменной PHP, $phperrmsg.

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

	SetErrorReporting(0);

Это выключает все сообщения об ошибках. Им можно затем разрешить снова с помощью вызова:

	SetErrorReporting(1);