PHP: различия между версиями

Содержимое удалено Содержимое добавлено
вопрос
Метки: замена blanking
Отмена правки 145764, сделанной John Veniza (обсуждение) rvv
Метка: отмена
Строка 1:
{{wikipedia}}
саси
'''PHP''' (произносится ''пи-эйч-пи́'') — [[w:скриптовый язык|скриптовый язык]] программирования, созданный для генерации [[w:HTML|HTML]]-страниц на [[w:веб-сервер|веб-сервере]] и работы с [[w:база данных|базами данных]]. На сегодняшний момент поддерживается подавляющим большинством представителей [[w:хостинг|хостингов]]. Входит в [[w:LAMP|«LAMP»]] — «стандартный» набор для создания [[w:сайт|веб-сайтов]].
 
== Комментарии ==
'''PHP''' предоставляет несколько методов для вставки комментариев. Проще всего пользоваться двойной косой чертой (//), после чего '''PHP'''-машина игнорирует всё, что расположено до конца строки. Также можно пользоваться многострочными комментариями в стиле "C" / [[C++|"С++"]] (/*…*/). Для однострочных комментариев можно ещё пользоваться символом решётки (#) (комментарий сценарных языков операционной системы [[UNIX|"UNIX"]]).
 
<source lang="php">
<?php
print '<p>Hello</p>'; // Комментарий
print '<p>Hello</p>'; # Комментарий
/* Комментарий
... и это тоже комментарии
*/
 
// Комментарии очень удобны в тех случаях,
// когда необходимо исключить часть кода
// для отладки программы; например:
 
$uname = $_POST['uname'];
 
// $uname = preg_replace('#[^a-zA-Z0-9\_\-\.]#', '', $uname);
// Закомментировали часть кода,
// так как не выводится желаемый результат;
// возможно, дело в этой строке:
echo $uname;
 
# Изначально, комментарии создавались для того,
// чтобы, не нарушая работы программы,
// добавить описание к той или иной строке;
// например:
 
echo getUsersOnline(2, 1, 4);
/* Аргументы функции:
0 - номер открытого соединения с базой данных;
1 - режим ответа ("0" - массив / "1" - строка);
2 - кол-во минут, прошедших с момента
последней активности пользователя (необязательный)
*/
?>
</source>
 
Следует помнить о том, что стили комментариев '''PHP''' действуют только внутри ограничителей '''PHP'''. Если '''PHP''' встретит эти символы комментариев вне ограничителей, то они, как и любой текст, будут помещены на HTML-страницу. Например:
 
<source lang="php">
<?php
print '<p>Hello</p>'; //Нормальный комментарий.
?>
</source>
<source lang="html5">
// А вот этот комментарий отобразится браузером.
<!-- Комментарий HTML. Будет виден в исходном коде HTML, но не в браузере. -->
</source>
 
== Переменные ==
В '''РНР''' — переменные начинаются со знака доллара ($). За этим знаком может следовать любое количество буквенно-цифровых символов и символов подчёркивания, но первый символ не может быть цифрой. Следует также помнить, что имена переменных в '''РНР''' чувствительны к регистру, в отличие от ключевых слов.
 
При объявлении переменных — в '''РНР''' не требуется явно указывать тип переменной; при этом, одна и та же переменная может иметь, на протяжении программы, разные типы.
 
Переменная инициализируется в момент присвоения ей значения — и существует до тех пор, пока выполняется программа (в случае ''web''-страницы — пока не завершён запрос) или она не будет удалена функцией <code>unset()</code>.
 
=== Функции вывода ===
В '''PHP''' существует несколько способов вывести что-либо в [[w:Веб-страница|веб-страницу]]:
{| class="wikitable"
!Средство
!Результат
|-
|Операторы <code>echo</code> и <code>print</code>
|Выводят значение аргумента, одним и тем же образом.
 
Различие: <code>print</code> — всегда возвращает "1"; <code>echo</code> — ничего не возвращает.
|-
|Функция <code>print_r()</code>
|Позволяет корректно выводить массивы.
|-
|Функция <code>var_dump()</code>
|Выводит переменную вместе с типом. Очень удобный инструмент для отладки.
|}
 
==== Вывод различных функций ====
{| class="wikitable"
! Аргумент
! <code>echo</code>
! <code>print_r()</code>
! <code>var_dump()</code>
|-
| <code>1</code>
| <code>1</code>
| <code>1</code>
| <code>int(1)</code>
|-
| <code>1.1</code>
| <code>1.1</code>
| <code>1.1</code>
| <code>double(1.1)</code>
|-
| <code>false</code>
| style="background-color: lightred" | &nbsp;
| style="background-color: lightred" | &nbsp;
| <code>bool(false)</code>
|-
| <code>array( 1, 2, 3 )</code>
| <code>Array</code>
| <code>Array
(
[0] => 1
[1] => 2
[2] => 3
)
</code>
| <code>array(3) {
[0]=>
int(1)
[1]=>
int(2)
[2]=>
int(3)
}</code>
|-
| <code>"Test"</code>
| <code>Test</code>
| <code>Test</code>
| <code>string(4) "Test"</code>
|}
 
=== Типы данных в РНР ===
Как уже было сказано, '''PHP''' предоставляет определённую гибкость в отношении типов переменных, — то есть, с одной и той же переменной, на протяжении программы можно работать ''и как со строкой, и как с числом.'' Однако несмотря на это, в '''РНР''' существует набор основных типов данных, которые могут явно указываться при работе с переменными:
{| class="wikitable"
!Обозначение
!Тип данных
|-
|integer
|Целое число.
|-
|string
|Строка символов.
|-
|boolean
|Двоичное данное (либо «Истина», либо «Ложь»).
|-
|double
|Десятичное число; 1—2 значащих разряда в дробной части.
|-
|float
|Десятичное число с плавающей точкой. Более 2 значащих разрядов в дробной части.
|-
|[[PHP/Массивы|array]]
|Массив объектов.
|-
|object
|Объект.
|-
|NULL
|Пустой тип.
|-
|Resource
|Ресурс.
|}
Есть функция <code>gettype()</code>, возвращающая тип, который '''РНР''' назначил переменной:
<source lang="php">
<?php
$var1 = '5';
$var2 = 5;
echo gettype($var1) # Будет возвращено: "string".
. '<br>' # Операция "." используется для склеивания строк.
. gettype($var2); # Будет возвращено: "integer".
?>
</source>
 
Существует также функция <code>settype()</code>, которая явно устанавливает тип:
 
<source lang="php">
<?php
$var = '5';
echo gettype($var); # Будет возвращено: "string".
settype($var, 'integer');
echo '<br />' . gettype($var); # Будет возвращено: "integer".
?>
</source>
 
Кроме функции <code>settype()</code>, преобразование типов в '''РНР''' можно осуществлять при помощи операторов преобразования типов. Преобразование типов осуществляется путём указания перед переменной её нового типа, взятого в скобки:<source lang="php">
$var = (integer)$var;
</source>
 
Соответственно, выполнение следующего кода приведёт к тому, что '''РНР''' вернёт «''integer»'':
<source lang="php">
<?php
$var = '5'; # Изначально, создаётся переменная типа "string" (строковая).
$var = (integer)$var; # Преобразуем её тип в "integer" (целочисленный).
echo gettype($var); # Отображаем окончательный тип переменной: "integer".
?>
</source>
 
=== Внешние переменные ===
После того, как запрос клиента проанализирован веб-сервером и передан '''РНР'''-интерпретатору — последний устанавливает ряд переменных, которые содержат данные запроса и доступны всё время его выполнения.
 
Сначала '''PHP''' инициализирует массивы <code>$_ENV</code> (содержащий переменные среды-окружения; англ. ''environment'') и <code>$_SERVER</code><ref>. На самом деле, порядок инициализации суперглобальных массивов зависит от настроек в файле ''php.ini''</ref>. Ассоциативный массив <code>$_SERVER</code> содержит следующие ключи (индексы массива):
{| class="wikitable"
!Ключ (индекс ячейки массива)
!Полный путь к ячейке массива
!Содержимое ячейки массива
|-
|<code>HTTP_USER_AGENT</code>
|<code>$_SERVER['HTTP_USER_AGENT']</code>
|Сведения о браузере клиента.
|-
|<code>HTTP_ACCEPT</code>
|<code>$_SERVER['HTTP_ACCEPT']</code>
|Принимаемые MIME-типы. Может служить для определения возможностей браузера.
|-
|<code>PHP_SELF</code>
|<code>$_SERVER['PHP_SELF']</code>
|Путь к файлу, содержащему выполняющийся скрипт, относительно корневого каталога (папки) сервера. Пример: <code>/w/index.php</code>.
|}
 
Затем '''РНР''' заполняет переменную <code>$_GET[]</code>, являющуюся ассоциативным массивом, которая создаётся при анализе строки запроса. Строка запроса хранится в элементе массива <code>$_SERVER['QUERY_STRING']</code> и представляет собой информацию, следующую за символом «?» в запрошенном URL. '''РНР''' разбивает строку запроса по символам «&»<ref>Символ разделения также может меняться в файле ''php.ini''. Часто используется символ «;».</ref> на отдельные элементы, а затем ищет в каждом из этих элементов знак «=». Если знак «=» найден, то создаётся переменная с именем из символов, стоящих слева от знака равенства. Рассмотрим следующую форму:
<source lang="html5">
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>
Введите данные.
</title>
</head>
<body>
<form action="http://localhost/PHP/test.php" method="get">
<p>
HDD:
</p>
<input type="text" name="HDD" />
<br />
<p>
CD-ROM:
</p>
<input type="text" name="CD-ROM" />
<br />
<input type="submit" value="Отправить" />
</form>
</body>
</html>
</source>
 
Если Вы сохраните этот фрагмент кода в виде HTML-файла и откроете его в веб-браузере, то увидите форму ввода. Если в строке «HDD» набрать какой-либо текст (к примеру, ''«''Maxtor»), и также в строке «CD-ROM» (например, «Nec»), то по нажатию на '''«Отправить»''' будет составлен запрос:
 
<code>[http://localhost/PHP/test.php?HDD=Maxtor&CDROM=Nec http://localhost/PHP/test.php?HDD=Maxtor&CD-ROM=Nec]</code> — и при этом '''РНР''' создаст следующие элементы массива с соответствующими индексами (ключами): <code>$_GET['HDD'] = 'Maxtor'</code> и <code>$_GET['CDROM'] = 'Nec'</code>. Вы можете работать с ними (т.е. с этими переменными) из Вашего скрипта (у нас — "test.php") как с обычными переменными; в нашем случае — они просто выводятся на экран:
 
<source lang="php">
<?php
echo "<p>HDD is " . $_GET['HDD'] . "</p>";
echo "<p>CDROM is " . $_GET['CDROM'] . "</p>";
?>
</source>
 
Если запрос страницы выполняется при помощи метода <code>POST</code>, то появляется группа ''POST''-переменных, которые интерпретируются так же и помещаются в массив <code>$_POST[]</code>.
 
== Константы ==
Константы объявляются в '''РНР''' при помощи функции <code>define()</code>:
<source lang="php">
define('CONSTANT', value)
</source>
 
Первый параметр этой функции — имя константы, второй — её значение. При использовании константы, на неё ссылаются по имени:
<source lang="php">
<?php
define('CONSTANT1', 15);
define('CONSTANT2', "\x20"); //Шестнадцатеричный код символа пробела
define('CONSTANT3', 'Hello');
echo CONSTANT1;
echo CONSTANT2;
echo CONSTANT3;
?>
</source>
 
По традиции — имена констант пишут буквами верхнего регистра. И хотя это только традиция, мы рекомендуем Вам следовать ей, поскольку «плохие» программисты получаются в том числе и из тех, кто не следовал хорошим традициям. Существует функция <code>defined()</code>, которая проверяет, определена ли константа:
 
<source lang="php">
<?php
define('CONSTANT', 'Hello');
if(defined('CONSTANT')) echo '<p>CONSTANT is defined</p>';
?>
</source>
 
== Операторы ==
=== Математические операторы ===
В '''PHP''', — как и в любом другом языке программирования, — есть базовый набор математических операторов:
{| class="wikitable"
!Оператор
!Операция
!Примечания
|-
|<code>-</code>
|Смена знака числа.
|
|-
|<code>-</code>
|Вычитание.
|
|-
|<code>+</code>
|Сложение.
|
|-
|<code>*</code>
|Умножение.
|
|-
|<code>/</code>
|Деление.
|Всегда возвращает тип <code>float</code>, вне зависимости от результата.
|-
|<code>%</code>
|Деление по модулю.
|Возвращает остаток от деления.
|}
 
=== Инкремент и декремент ===
*Возвращают старое значение $a:
**<code>$a++</code> — увеличить $a на 1;
**<code>$a--</code> — уменьшить $a на 1.
*Возвращают новое значение $a:
**<code>++$a</code> — увеличить $a на 1;
**<code>--$a</code> — уменьшить $a на 1.
 
=== Операторы сравнения ===
Существуют следующие операторы сравнения:
{|
|'''Оператор'''
|'''Проверка'''
|'''Условие истинности''' (возвращается <code>true</code>)
|-
| <code>$a == $b</code>
|Равно
| '''$a''' равно '''$b'''.
|-
| <code>$a === $b</code>
|Идентично
| '''$a''' равно '''$b''' и они одного и того же типа.
|-
| <code>$a != $b</code> или <code>$a <> $b</code>
|Не равно
| '''$a''' не равно '''$b'''.
|-
| <code>$a > $b</code>
|Строго больше
| '''$a''' строго больше '''$b'''.
|-
| <code>$a < $b</code>
|Строго меньше
| '''$a''' строго меньше '''$b'''.
|-
| <code>$a >= $b</code>
|Больше или равно
| '''$a''' или больше, или равно '''$b'''.
|-
| <code>$a <= $b</code>
|Меньше или равно
| '''$a''' или меньше, или равно '''$b'''.
|}
 
=== Операторы присвоения ===
Для присвоения переменной нового значения — используется оператор «<code>=</code>»:
<source lang="php">
$a = $b + $c - 127;
</source>
Также существуют сокращённые операторы присвоения: <code>+=</code>, <code>-=</code>, <code>.=</code>, <code>/=</code>, <code>*=</code>, <code>%=</code>. Пример:
<source lang="php">
$a = $a + 1;
#равносильно
$a += 1;
</source>
 
=== Поразрядные операторы ===
Эта группа операторов работает с битовыми представлениями значений целочисленных операндов. В основном, эти операторы применяются для создания набора булевых флагов:
{| class="wikitable"
|'''Оператор'''
|'''Операция'''
|-
| <code>&</code> || Поразрядная конъюнкция (AND).
|-
| <code><nowiki>|</nowiki></code> || Поразрядная дизъюнкция (OR).
|-
| <code>^</code> || Поразрядное исключающее ИЛИ (XOR).
|-
| <code>~</code> || Поразрядное отрицание (NOT).
|-
| <code><nowiki><<</nowiki></code> || Битовое представления значения левого целочисленного операнда сдвигается влево, на количество разрядов, равное значению правого целочисленного операнда.
|-
| <code><nowiki>>></nowiki></code> || Битовое представление значения левого целочисленного операнда сдвигается вправо, на количество разрядов, равное значению правого целочисленного операнда.
|}
 
<source lang="php">
<?php
echo (4<<2); //16
echo "<br />";
echo (5>>1); //2
echo "<br />";
echo (6&5); //4
echo "<br />";
echo (6|5); //7
echo "<br />";
echo (6^5); //3
?>
</source>
 
=== Операторы ветвления алгоритмов (if… elseif… else…) ===
Оператор <code>if</code> позволяет выполнять определённый код только при выполнении определённого условия:
<source lang="php">
<?php
$a = 1;
$b = null;
$c = 2 * 3;
$d = true;
if($a) echo "if(\$a);<br />";
if($b) echo "if(\$b);<br />";
if($c) echo "if(\$c);<br />";
if(!$d) echo "if(!\$d);<br />";
if($a < $c) echo "\$a < \$c;<br />";
?>
</source>
 
Этот код выводит следующие строки:
<pre>if($a);
if($c);
$a < $c;
</pre>
 
Чтобы выполнять код, только если условие не выполнилось — можно использовать блок <code>else</code>:
<source lang="php">
<?php
if(isset($_GET['test'])) echo 'Query contains "test" parameter';
else echo 'Query doesn\'t contain "test" parameter';
?>
</source>
 
Можно использовать инструкцию <code>elseif</code> (англ. «иначе, если»):
<source lang="php">
<?php
if($_GET['test'] == "foo") echo 'test = "foo"';
elseif(isset( $_GET['test'])) echo 'Query contains "test" parameter, but it isn\'t "foo"';
else echo 'Query doesn\'t contain "test" parameter';
?>
</source>
 
=== Переключатель (switch) ===
<source lang="php">
<?php
$a = "A";
switch($a)
{
case 'A':
echo 'Переменная имеет значение "А"';
break;
case 'B':
echo 'Переменная имеет значение "B"';
break;
default: echo 'Ответ не найден';
}
?>
</source>
Вышенаписанный пример выведет: «Переменная имеет значение „A“» — и то же выведет следующий пример:
<source lang="php">
<?php
$a = "A";
if($a == "A") echo "Переменная имеет значение \"A\"";
elseif($a == "B") echo "Переменная имеет значение \"B\"";
else echo "Ответ не найден";
?>
</source>
 
=== Операторы цикла ===
Операторы цикла задают многократное исполнение операторов в теле цикла. В '''PHP''' определены 4 разных оператора цикла:
*Цикл с предусловием: <code>while(condition) { statements; }</code>
*Цикл с постусловием: <code>do { statements; } while(condition);</code>
*Итерационный цикл: <code>for(expression1; expression2; expression3) { statements; }</code>
*Итерационный цикл <code>foreach</code> (т.е. перебор элементов массива): <code>foreach(array as [$key =>] $value) { statements; }</code>
 
Если 3 первых оператора цикла берут своё начало от "[[C++|С]]"-подобных языков, то последний оператор позаимствован у языка "[[Perl]]".
 
==== while ====
Оператор <code>while</code> называется оператором цикла с предусловием. При входе в цикл вычисляется выражение условия, и, если его значение отлично от нуля, выполняется тело цикла. Затем — вычисления выражения условия и операторов тела цикла выполняется до тех пор, пока значение выражения условия не станет равным нулю. Оператором <code>while</code> удобно пользоваться для просмотра всевозможных последовательностей, если в конце них находится заранее известный символ. (Это очень удобно в "[[C++]]", — к примеру, для определения длины строки, — поскольку в "[[C++|С++]]", по определению, строка есть последовательность символов типа "char", заканчивающаяся нулевым символом: <code>\0</code>).
 
Пример простейшего цикла <code>while</code>:
<source lang="php">
<?php
$var = 5;
$i = 0;
while(++$i <= $var) echo $i . '<br />';
?>
</source>
 
Этот код выдает в окне браузера цифры от одного до пяти.
 
Для выхода из цикла — применяется оператор <code>break</code>. При обнаружении этого оператора, все итерации прекращаются. Пример: при выполнении нижеприведённого цикла, — несмотря на то, что переменная <code>$var = 7</code>, — в окне браузера появятся цифры «1»—«5», исключая «6» и «7»:
<source lang="php">
<?php
$var = 7;
$i = 0;
while(++$i <= $var)
{
echo $i . '<br />';
if($i == 5) break;
}
?>
</source>
 
Чтобы перейти в следующую итерацию — применяется <code>continue</code>:
<source lang="php">
<?php
$var = 7;
$i = 0;
while (++$i <= $var)
{
if($i == 5) continue;
echo $i . '<br />';
}
?>
</source>
 
В этом примере выводятся цифры «1»—«7», за исключением «5».
 
Заметим, что если Вы расположите условный оператор после операторов <code>echo</code> — код будет ошибочным (т.к. выведутся все цифры, включая «5»), поскольку проверка условия выхода из итерации будет происходить уже после полного выполнения этой итерации.
 
Бесконечный цикл реализуется при помощи оператора <code>while</code> следующим образом:
<source lang="php">
while(true)
{
...
}
</source>
 
''Примечание:'' В '''PHP''', стандартное время исполнения скрипта — 30 секунд (эту настройку можно изменить в файле "php.ini"); по его прошествии с начала выполнения скрипта, действие скрипта будет прервано. Таким образом, наибольшее время выполнения «бесконечного» цикла (без изменения настроек) — полминуты.
 
==== do… while… ====
Этот оператор называется оператором цикла с пост-условием. При входе в цикл, в любом случае выполняется тело цикла (то есть цикл ''всегда'' будет выполнен хотя бы один раз); затем — вычисляется условие, и если оно не равно «0», то вновь выполняется тело цикла и проверка условия. В нижеследующем примере — «нуль» всегда будет добавлен в список, независимо от условия <code>(++$i <= $var)</code>:
<source lang="php">
<?php
$var = 5;
$i = 0;
do
{
echo $i . '<br />';
}
while(++$i <= $var);
?>
</source>
 
Результат:
<source lang="html5">
0<br />1<br />2<br />3<br />4<br />5<br />
</source>
 
Цикл с постусловием бывает полезен при обработке некоторых последовательностей — когда обработку нужно заканчивать не «до», а «после» появления концевого признака.
 
Бесконечный цикл реализуется так:
<source lang="php">
do
{
...
}
while(true);
</source>
 
==== for ====
Как уже говорилось, итерационный цикл имеет следующий формат:
 
<source lang="php">
for(expression1; expression2; expression3) {
statements;
}
</source>
 
Здесь <code>expression1</code> (инициализация цикла) — последовательность определений и выражений, разделяемая запятыми. Все выражения, входящие в инициализацию, вычисляются только один раз, при входе в цикл. Как правило, здесь устанавливаются начальные значения счётчиков и параметров цикла. Смысл выражения-условия <code>expression2</code> — такой же как и у циклов с предусловиями; при отсутствии выражения-условия предполагается, что его значение всегда истинно. Выражения <code>expression3</code> вычисляются в конце каждой итерации после выполнения тела цикла.
 
В следующем скрипте, мы по традиции выведем числа от «0» до «5»:
<source lang="php">
<?php
$var = 5;
for($i = 0; $i <= $var; $i++)
{
echo $i . '<br />';
}
?>
</source>
 
Результат аналогичен показанному для «do… while…».
 
==== foreach ====
Оператор цикла <code>foreach</code> предназначен для работы с элементами массива. Следующий код превратит все элементы массива в единицы:
<source lang="php">
<?php
$arr = array(1, 2, 3, 4);
$i = 0;
foreach ($arr as &$a)
{
$a -= $i++;
}
?>
</source>
 
Также предусмотрена возможность работы с ассоциативными массивами. При обработке следующего кода, в переменной <code>$name</code> будет храниться ассоциативный индекс элемента, а в переменной <code>$value</code> — его значение. Проще говоря, <code>($arr[$name] == $value)</code>.
<source lang="php">
<?php
...
foreach ($arr as $name => $value) {
//тело цикла
}
?>
</source>
 
=== Тернарный оператор «?:» ===
Тернарный оператор «'''?:'''» — это вид условного оператора. В случае с записью вида <code>Выражение «1» ? Выражение «2» : Выражение «3»</code> — он проверяет Выражение «1», и если оно верно, то тернарный оператор возвращает значение Выражения «2»; иначе — Выражения «3».
<source lang="php">
<?php
$a = true;
$b = false;
$c = 11;
$d = 10;
$f = $a ? $c : $d; # Переменной $f присвоится значение переменной $c,
# т. к. значение выражения $a истинно.
$g = $b ? $c : $d; # Здесь наоборот: $g будет присвоено значение $d,
# т. к. значение выражения $b ложно.
$h = (!empty($n)) ? $n : $c + $d; # Сперва проверится существование
# переменной $n. Т. к. она не существует,
# переменной $h присвоится
# сумма $c и $d, т. е. "21".
?>
</source>
 
== Строковые функции PHP ==
Несмотря на то, что эта глава написана скорее в духе справочника — материал, изложенный в ней, достаточно серьёзен, хотя и не самый сложный для понимания. Умение грамотно работать со строками очень важно для программиста. Строковых функций в '''PHP''' немало, причем многие из них, так или иначе, просто дублируют друг друга. Однако, приёмы работы с основными блоками функций (функции поиска и замены в тексте, функции удаления пробельных символом (trim-функции), функции форматного вывода) надо представлять очень чётко.
 
''Вообще говоря, по определению, строка — это последовательность символов типа '''char''', которая заканчивается нулевым символом. Поэтому можно, конечно, радоваться тому, что при работе со строками, нам не приходится жонглировать указателями в стиле "C"/"[[C++]]", однако не стоит забывать о том, что цена этому удобству — быстродействие. Поэтому некоторые приводимые здесь функции мы будем обсуждать в том числе и с точки зрения их быстродействия.''
 
=== Функция "htmlspecialchars" ===
<code>string htmlspecialchars(string $str)</code>
 
Эта функция преобразовывает некоторые специальные символы [[HTML]] в другой формат. При этом они будут отображаться без учёта их специального назначения.
 
'''Пример'''
 
Корректное формирование и вывод гиперссылки, содержащей определённые параметры:
<source lang="php">
$link_search_subject = "Экранирование";
$link_label = "Поиск по слову " . "$link_search_subject";
 
echo
'<a href=' . htmlspecialchars("http://ru.wikibooks.org/wiki/Служебная:Search?search=".urlencode($link_search_subject)
."&go=".urlencode("Перейти")).'">'.htmlspecialchars($link_label).
'</a>';
</source>
 
Заметьте, что следующий (ниже представленный) код содержит грубое нарушение, так как формирует гиперссылку с атрибутом, содержащим незаконченную (не закрытую) ссылку на сущность (&…;) :
 
<source lang="php">
$link_search_subject = "Экранирование";
 
echo
'<a href="http://ru.wikibooks.org/wiki/Служебная:Search?search='.urlencode($link_search_subject)
.'&go='.urlencode("Перейти").'">'. // НАРУШЕНИЕ!!
"Поиск по слову Экранирование".
'</a>';
</source>
 
Это довольно часто встречаемая ошибка.
 
=== Функции поиска в тексте ===
 
==== substr() ====
Функция '''<code>substr()</code>''' возвращает часть строки. Например:
<source lang="php">
echo substr('Simple text', 3, 7);
</source>
 
Где «3» — точка отсчёта, а «7» — длина изымаемой строки. Если же требуется вести отсчёт от конца строки — используйте отрицательное значение.
 
'''Пример'''
 
Эта функция разобьёт число по трём разрядам:
<source lang="php">
<?php
function my_int($value)
{
$len = strlen($value);
if ($len <= 3) return $value;
else return my_int(substr($value, 0, $len-3)) . ' ' . substr($value, $len-3, 3);
}
echo my_int(12345678); //=> 12 345 678
</source>
 
Для работы с разными кодировками используется функция:
 
<code>string mb_substr ( string $str , int $start [, int $length [, string $encoding ]] )</code>
 
==== strpos() ====
<code>int strpos (string haystack, string needle [, int offset])</code>
 
Возвращает позицию первого вхождения подстроки <code>needle</code> (в переводе с английского — «иголка») в строку <code>haystack</code> (в переводе с английского, как вы уже догадались, — «стог сена»). Необязательный аргумент <code>offset</code> позволяет указать, с какого по счёту символа строки <code>haystack</code> начинать поиск.
 
Если подстрока <code>needle</code> не найдена — <code>strpos()</code> возвращает '''<code>FALSE</code>'''.
 
'''Пример:'''
 
Эта функция определяет модель браузера:
<source lang="php">
<?php
function get_current_browser() {
$browser = strtoupper($_SERVER['HTTP_USER_AGENT']);
if(strpos($browser, 'MSIE') !== false) $browser = 'Internet Explorer';
elseif(strpos($browser, 'FIREFOX') !== false) $browser = 'Firefox';
elseif(strpos($browser, 'KONQUEROR') !== false) $browser = 'Konqueror';
elseif(strpos($browser, 'LYNX') !== false) $browser = 'Lynx';
else { $browser = $_SERVER['HTTP_USER_AGENT'];}
return $browser;
}
get_current_browser();
?>
</source>
 
==== strrpos() ====
Возвращает позицию последнего вхождения символа:
 
<code>int strrpos (string haystack, string needle [, int offset])</code>
 
Возвращает позицию последнего вхождения <code>needle</code> в строку <code>haystack</code>. В «'''PHP 4»''' используется только первый символ строки <code>needle</code>.
 
Начиная с «'''PHP 5»''' необязательный аргумент <code>offset</code> позволяет указать, с какого по счету символа строки <code>haystack</code> начинать поиск. Отрицательное значение предписывает прекратить поиск при достижении определенной позиции до конца строки.
 
Если подстрока <code>needle</code> не найдена — возвращает <code>FALSE</code>.
 
'''Пример:'''
 
Эта функция достаёт из [[w:URL|URL]] имя файла ('''только пример;''' в жизни, можно использовать функцию <code>basename()</code>):
<source lang="php">
function getfname($url)
{
$filename = ''; // Переменная для хранения результата обработки.
// Ведём поиск первого слеша,
// отделяющего путь к файлу
// от имени домена:
$pos = strrpos($url, '/', 8); // Начинаем с 8 символа (после "http://").
if ($pos === false) {
return false; // Ошибка: неподходящий URL (нет слеша).
} else {
$filename = substr($url, $pos + 1); // Выделяем часть URL после слеша.
}
return $filename; // Возвращаем: или результат обработки, или ''.
}
</source>
 
==== strstr(), stristr() ====
 
<code>string strstr (string $haystack, string $needle [, bool $before_needle = false ])</code>
 
Возвращает подстроку строки <code>haystack</code>: начиная с индекса ''первого'' вхождения подстроки <code>needle</code> — до конца строки. Функция <code>stristr()</code> выполняет ту же функцию, но не чувствительна к регистру.
 
'''Пример:'''
<source lang="php">
<?php
print strstr('www.wikibooks.org', '.'); // Результат: ".wikibooks.org".
?>
</source>
 
Для работы с разными кодировками используются функции:
 
<code>string mb_strstr (string $haystack , string $needle [, bool $before_needle = false [, string $encoding ]])</code>
 
<code>string mb_stristr (string $haystack , string $needle [, bool $before_needle = false [, string $encoding ]])</code>
 
где параметр <code>encoding</code> — название используемой кодировки символов (например «'''UTF-8»'''); если этот параметр опущен — используется внутренняя кодировка.
 
==== strchr() ====
 
Эта функция является псевдонимом функции <code>strstr()</code>.
 
==== strrchr() ====
 
<code>string strrchr (string $haystack, char $needle)</code>
 
Возвращает подстроку строки <code>haystack</code>: начиная с ''последнего'' вхождения <code>needle</code> — до конца строки.
 
Если подстрока <code>needle</code> не найдена — возвращает <code>FALSE</code>.
 
Если <code>needle</code> состоит более чем из одного символа — используется только первый символ.
 
Если <code>needle</code> не является строкой — он приводится к целому и трактуется как код символа.
 
'''Пример:'''
<source lang="php">
<?php
print = strrchr('www.wikibooks.org', '.'); // Результат: ".org".
?>
</source>
 
==== substr_count() ====
 
<code>int substr_count (string $haystack, string $needle)</code>
 
Возвращает число вхождений подстроки <code>needle</code> в строку <code>haystack</code>.
 
Можно использовать или текст в кавычках (или апострофах), или переменные.
 
'''Пример:'''
<source lang="php">
<?php
print substr_count('www.wikibooks.org', 'o'); // Результат: "3".
?>
</source>
 
==== strspn() ====
Находит длину начального сегмента маски.
 
<code>int strspn (string $str1, string $str2)</code>
 
Возвращает длину начального сегмента <code>$str1</code>, состоящего полностью из символов строки <code>$str2</code>.
 
'''Пример:'''
<source lang="php">
<?php
return strspn("42 is the answer; what is the question?",
"1234567890");
// Результат: "2".
// (Т. к. в начале первой строки-аргумента
// самым длинным сегментом,
// состоящим только из символов, содержащихся во втором аргументе,
// является сегмент "42", -- длиной в 2 символа.)
?>
</source>
 
==== strcspn() ====
Обратная к функции <code>strspn()</code>.
 
Определяет отсутствие начальных символов в строке.
 
Возвращает длину начального фрагмента строки <code>$str1</code>, состоящего полностью '''не''' из символов, которые есть в строке <code>$str2</code>.
 
== Система пользователей ==
В этой статье будет описаны алгоритмы системы пользователей и их коды на языке '''PHP'''.
 
=== Регистрация ===
Алгоритм регистрации — самый простой из тех, что мы будем здесь использовать. Серверу предстоит записать:
# Введённые пользователем данные;
# Результат хеш-функции от пароля.
<source lang="html5">
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>
Регистрация
</title>
</head>
<body>
</source>
<source lang="php">
<?php
// Register
// Подключение к "MySQL"-серверу
// (с выводом ошибки в случае неудачи):
mysql_connect("localhost", "root", "") or die(mysql_error);
// Подключение к базе данных "deskside"
// (с выводом ошибки в случае неудачи):
mysql_select_db("deskside") or die(mysql_error);
// Запрос на получение списка всех пользователей из таблицы "users",
// упорядоченного по возрастанию значений поля "id":
$find_id_sql = mysql_query("SELECT * FROM users ORDER BY id ASC");
$find_id_row = mysql_num_rows($find_id_sql);
// Получение списка пользователей из таблицы "users",
// чьи логины совпадают со значением, полученным в "POST"-запросе:
$find_names = mysql_query("SELECT * FROM users "
."WHERE login='"
.$_POST['login']."'");
$find_row = mysql_num_rows($find_names);
$id_counter = 1;
 
// Вычисление последнего ID:
while ($find_id_row = mysql_fetch_assoc($find_id_sql)){
$id_counter += 1;
}
$user_already = false; // Булевская переменная для сохранения результатов
// проверки: есть ли уже такой пользователь,
// с данным "login".
if ($_POST['register']) // Если дан запрос именно что на регистрацию.
{
while($find_row == mysql_fetch_assoc($find_names))
{
// Поиск пользователя с данным "login".
if ($find_row['login'] == $_POST['login']){ // Если нашёлся...
$user_already = true; // ...то отмечаем это как результат
break; // ...и выходим из цикла.
}
}
// Если пользователь с таким "login" уже есть.
if($user_already){ // Уведомляем отправителя запроса об этом.
echo "
<p>
Такой пользователь уже есть. <br />
<a href=\"http://localhost/register.htm\">
Пройти регистрацию заново...
</a>
</p>
";
}
else
{
// Если пользователя с таким "login" всё-таки нет,
// то регистрируем данный "login" для нового пользователя.
// Проверка совпадения паролей:
if ($_POST['password'] == $_POST['second_password'])
{
// Если совпали:
// 1. Хэширование пароля для базы данных.
$md5_password = md5($_POST['password']);
// 2. Запрос "MySQL"-серверу на сохранение регистрационных данных
// в соответствующую таблицу ("users"):
mysql_query("INSERT INTO users "
."(`id`, `login`, `password`, `e-mail`, `name`) "
."VALUES ('"
.$id_counter
."', '"
.$_POST['login']
."', '"
.$md5_password
."', '"
.$_POST['e-mail']
."', '"
.$_POST['name']
."')");
// 3. Уведомляем отправителя запроса:
echo "Регистрация проведена успешно.";
}
else
{
echo "
<p>
Ошибка регистрации: пароли не совпадают! <br />
<a href=\"http://localhost/register.htm\">
Пройти регистрацию заново...
</a>
</p>
";
 
}
}
}
if ($_POST['register'])
{
// Если пользователь уже нажал кнопку "РЕГИСТРАЦИЯ",
// то зачем ему заново показывать форму?!
}
else
{
// Если он уже кликнул, то мы не показываем форму,
// а выводим либо сообщение о подтверждении, либо об ошибке:
echo '
<form method=\"post\">
<p>
Логин: <input type=\"text\" name=\"login\" />
</p>
<p>
Пароль: <input type=\"password\" name=\"password\">
</p>
<p>
Пароль ещё раз: <input type=\"password\" name=\"second_password\" />
</p>
<p>
E-mail: <input type=\"email\" name=\"e-mail\" />
</p>
<p>
Ваше имя: <input type=\"text\" name=\"name\" />
</p>
<input type=\"submit\" name=\"register\" value=\"Зарегистрироваться\">
</form>
';
}
?>
</source>
<source lang="html5">
</body>
</html>
</source>
 
=== Авторизация пользователя ===
[[Файл:Алгоритм_входа_пользователя.png|thumbnail|180px|Алгоритм авторизации пользователя]]
Вход пользователя будет производиться по следующему алгоритму:
#Пользователь заполняет форму: «Логин», «Пароль»;
#Данные запоминаются в переменной '''$_POST''', после чего будут обрабатываться на сессии<ref>Преимущество сессий в том, что обычный пользователь даже не заметит, как его перенаправили на другую страницу, а значит будет сложнее взломать PHP код. На странице входа отображается только перенаправление на session.php и форма входа. Если конечно не посмотрит внимательно на HTML код, но это ему ничего не даст, по скольку он не сможет взять из файла session.php сам PHP код</ref>;
#Уже в сессии хешируется введённый пользователем пароль, алгоритмом [[w:MD5|MD5]];
#Подключение к базе данных «SQL» и импорт данных со строки пользователя ''admin'' (допустим, пользователь ввёл имя пользователя ''admin''). Затем запись всей строки в массив '''$table''' — такой вариант поможет сократить много нервов и строк;
#Сравнение зашифрованного пароля, который в базе данных, — с зашифрованным, введённым пользователем;
#Если пароли совпадают, записываются «COOKIE» с информацией о авторизации пользователя. ("user_enter" & "user_login");
#Закрытие сессии методом перенаправления на другую страницу. - ''header (Location: ...);''
===== '''Форма входа''' =====
<source lang="php">
<?php
session_start();
# Этот шаблон можно вставлять в любую часть сайта;
# он будет работать в любом случае.
?>
</source>
<source lang="html5">
<form action="session.php" method="POST">
<p>
Логин: <input type="text" name="login" />
</p>
<p>
Пароль: <input type="password" name="password" />
</p>
<input type="submit" value="Вход" />
</form>
</source>
 
====='''Сессия (session.php)'''=====
<source lang="php">
<?php
 
// Заметьте: Нет команд "echo" --
// эту команду можно использовать
// только после того, как отправились все "куки".
//
// P.S.: Если на странице используются "куки" --
// лучше не использовать кодировку "UTF-8".
 
session_start();
// Если пользователь кликнул "Выход":
if ($_POST['exit']){
// ...то чистим "куки"
// о его авторизации и логине:
unset($_COOKIE['user_enter']);
unset($_COOKIE['user_login']);
}
 
// Подключение к "MySQL"-серверу:
// localhost - стандартный адрес сервера баз данных,
// если тот запущен на локальном компьютере;
// root - логин для пользователя "MySQL";
// 1234 - пароль для пользователя "MySQL".
mysql_connect("localhost", "root", "1234") or die(mysql_error);
 
// Подключение к базе данных:
mysql_select_db("base") or die(mysql_error); // где "base" - имя базы данных.
 
$check_password = mysql_query("SELECT * FROM `base`.`users`"
."WHERE (login='"
.$_POST['login']
."')"); // "SQL"-запрос для проверки пароля.
$row_check_password = mysql_num_rows($check_password);
 
// Получение данных о пользователе:
while($row_check_password = mysql_fetch_assoc($check_password)){
// ID пользователя:
$table['id'] = $row_check_password['id'];
// Логин пользователя:
$table['login'] = $row_check_password['login'];
// Пароль (в зашифрованном виде) пользователя:
$table['password'] = $row_check_password['password'];
// Имя блога пользователя:
$table['blog_name'] = $row_check_password['blog_name'];
}
 
// Проверка паролей:
if ($_POST['enter']){
// Хеширование пользовательского пароля:
$md5_password = md5($_POST['password']);
// Если хеш пароля, введённого пользователем, и логин
// совпадают с хешем пароля и с логином из базы данных:
if ($md5_password == $table['password']
&& $_POST['login'] == $table['login']){
// Пользователь вошёл в систему:
setcookie("user_enter", true); // "Кука": пользователь авторизировался.
setcookie("user_login", $_POST['login']); // "Кука": логин.
setcookie("user_blog", $table['blog_name']); // "Кука": имя блога.
}else{
// Пароль не подтвердился:
setcookie("user_login", "no_enter"); // "Кука": Логин "не вошёл".
setcookie("user_enter", false); // "Кука": Пользователь не вошёл.
}
}
 
// Перенаправление на главную страницу:
header('Location: http://deskside/main.php?page=home');
?>
</source>
 
=== Вывод данных пользователя ===
Для вывода данных пользователя будут использоваться куки, но поскольку они могут содержать только латинские буквы и цифры — они будут использоваться только как идентификатор имени пользователя и подтверждения его авторизации.
 
Пользователю нужно выводить максимум информации о его ошибках. Если Ваш проект будет очень большим и пользователь при входе будет вводить не только логин и пароль, а ещё 20 полей — то пользователю будет не очень удобно, при опечатке, смотреть на такое сообщение: <blockquote>Возможно, Вы ошиблись при заполнении данных... Попробуйте ещё раз.</blockquote>Ему будет гораздо приятнее, если ему выведут сообщение с возможным полем опечатки и самой опечаткой. Но в нашем варианте, будет рассматриваться только вариант с логином и паролем.
 
Естественно, невозможно использовать один и тот же текст для вывода разной информации. Всего их три:
* Если пользователь авторизировался;
* Если пароли не совпадают;
* Если пользователь ещё не авторизировался и хочет ввести свои данные.
Проще всего будет просто выводить шаблон на страницу ('''$login_form''').<br />
====='''Пользователь авторизировался'''=====
<source lang="php">
if ($_COOKIE['user_enter']){
 
$login_form ='
<form method="post">
Вы вошли как <b>'.$login.'</b> <br>
<br>
<a href="http://deskside/main.php?page=register">Регистрация</a> <br>
<a href="http://deskside/main.php?page=profile">Профиль</a> <br>
<input type="submit" name="exit" value="Выход">
</form>
';
 
}
</source>
 
====='''Пароли не совпали'''=====
<source lang="php">
if($_COOKIE['user_login'] == "no_enter"
And $_COOKIE['user_enter'] == false){
 
$login_form = '
<form method="post">
Ошибка: Пароль неправильный! <br>
<hr>
<b><input type="submit" name="exit" value="Ввести снова"></b> <br>
<a href="http://deskside/main.php?page=register">Регистрация</a>
</form>
';
}
</source>
 
====='''Форма авторизации'''=====
<source lang="php">
$login_form = '
<table>
<tr>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>&nbsp;</td>
<td class="style10">
<form action="session.php" method="POST">
Логин: <br>
<input type="text" name="login"> <br>
Пароль: <br>
<input type="password" name="password"> <br>
<hr>
<input type="submit" name="enter" value="Войти"> <br>
<br>
<a href="http://deskside/main.php?page=register">Регистрация</a>
</form>
</td>
<td>&nbsp;</td>
</tr>
<td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</td>
</table>
';
</source>
 
== Примечания ==
{{примечания}}
 
== Ссылки ==
* [http://docs.php.net/manual/ru/ Руководство по PHP] (включая FAQ)
* [http://www.php.net/docs.php Documentation]
* [http://php.net/manual/en/index.php PHP Manual] (оригинал, англ.)
* [http://www.php-s.ru/self-teacher/ Самоучитель (учебник) по PHP]
 
{{BookCat}}
 
{{Темы|Языки программирования}}
 
{{По алфавиту}}
 
[[Категория:Веб-разработка]]