"Трагедия жизни в том, что мы слишком быстро стареем, а мудрыми становимся слишком поздно." Бенджамин Франклин
"Трагедия жизни в том, что мы слишком быстро стареем, а мудрыми становимся слишком поздно." Бенджамин Франклин
Join Us
В make.conf добавляем:
PHP_TARGETS="php7-3 8-1"
Флаги Use="...php threads" были добавлены ранее.
Наиболее важные USE-флаги пакета PHP, это apache2, cgi и fpm.
MySQL модуль устарел и удалён в PHP 7.0.0. Вместо него используется MySQLi или PDO_MySQL.
PHP позволяет создавать и работать с файлами изображений в различных форматах включая GIF, PNG, JPEG, WBMP, и XPM, выводить изображение в потоке непосредственно в браузер. Для этого необходимо скомпилировать PHP с графической библиотекой GD, содержащей функции для работы с изображениями.
USE-флаг truetype для добавления поддержки шрифтов FreeType и/или FreeType2.
Устанавливаем флаги:
vim /etc/portage/package.use
dev-lang/php cgi mysqli mysql gd truetype # mysql флаг добавляет поддержку базы данных mySQL
Устанавливаем PHP:
emerge --ask dev-lang/php
Для работы с GD могут потребоваться другие библиотеки, в зависимости от формата изображений, с которыми возникла необходимость работать.
Чтобы включить поддержку png требуется наличие библиотеки libpng, а она требует наличие zlib.
Поведение функций для работы с изображениями зависит от установок в /etc/php/apache2-php8.1/php.ini, /etc/php/cgi-php8.1/php.ini, /etc/php/cli-php8.1/php.ini:
gd.jpeg_ignore_warning "1"
Устанавливаем GD с USE-флагом truetype:
emerge --ask media-libs/gd
FreeType - это свободно доступная программная библиотека для отрисовка шрифтов:
emerge --ask media-libs/freetype
В файле /etc/conf.d/apache2 добавляем соответствующий модулль:
APACHE2_OPTS="... -D PHP"
Убеждаемся, что файл /etc/apache2/modules.d/70_mod_php.conf существует и содержит следующее:
<IfDefine PHP>
# Симлинк mod_php.so контролируется eselect-php.
# Тем не менее, имя модуля изменяется с php5_module на php7_module,
# поэтому мы не можем слепо загрузить все, как есть.
# Вместо этого мы позволяем eselect-php управлять небольшим
# конфигурационным файлом, который загрузит необходимые модули.
# Это относительно ServerRoot (смотрите httpd.conf).
Include "/var/lib/eselect-php/mod_php.conf"
# Сообщите apache, что mod_php должен обрабатывать файлы PHP.
# ЗАМЕТКА: Избегайте AddHandler/AddType в целях безопасности (bug
# #538822). Пожалуйста, прочитайте соответствующую новость!
<FilesMatch "\.(php|php[57]|phtml)$">
SetHandler application/x-httpd-php
</FilesMatch>
# PHP исходный код, который подразумевает отображение его как
# исходный код с подсветкой синтаксиса.
<FilesMatch "\.phps$">
SetHandler application/x-httpd-php-source
</FilesMatch>
DirectoryIndex index.php index.phtml
</IfDefine>
Если он не существует, создаём его.
Чтобы проверить, работает ли модуль PHP, создаём тестовую страницу:
vim /var/www/localhost/htdocs/index.php
<html>
<body>
<?php phpinfo(); ?>
</body>
</html>
Удаляем или переименовываем файл /var/www/localhost/htdocs/index.html и открываем тестовую страницу: localhost.
Должна отобразиться таблица с настройками PHP.
Чтобы изменить версию PHP, нужно вывести список доступных:
eselect php list apache2
[1] php7.1 *
[2] php7.3
[3] php8.1
Изменяем на необходимую версию:
eselect php set apache2 2
Включение PHP-FPM через mod_proxy_fcgi в Apache 2.4 и выше
Настраиваем директиву listen для использования сокета.
Создаём каталог для файла сокета:
mkdir /var/run/php-fpm
Затем создаём файл php-fpm.conf
vim /var/run/php-fpm/php-fpm.conf
следующей конфигурации:
; Set permissions for unix socket, if one is used. In Linux, read/write
; permissions must be set in order to allow connections from a web server. Many
; BSD-derived systems allow connections regardless of permissions.
; Default Values: user and group are set as the running user
; mode is set to 0666
listen.owner = nobody
listen.group = nobody
; listen.mode = 0666
; The address on which to accept FastCGI requests.
; Valid syntaxes are:
; 'ip.add.re.ss:port' - to listen on a TCP socket to a specific address on
; a specific port;
; 'port' - to listen on a TCP socket to all addresses on a
; specific port;
; '/path/to/unix/socket' - to listen on a unix socket.
; Note: This value is mandatory.
; listen = 127.0.0.1:9000
listen = /var/run/php-fpm/www.sock
Подключаем модули PHP и PROXY:
vim /etc/conf.d/apache2
APACHE2_OPTS="... -D PHP -D PROXY"
Значительным отличием PHP от какого-либо кода, выполняющегося на стороне клиента, например, JavaScript, является то, что PHP-скрипты выполняются на стороне сервера. Можно сконфигурировать свой сервер таким образом, чтобы HTML-файлы обрабатывались процессором PHP, так что клиенты даже не смогут узнать, получают ли они обычный HTML-файл или результат выполнения скрипта.
Проверять коды PHP можно в командной строке:
$ php файл.php
Обозначение PHP-кода:
<? ?>
<?php ?>
<script language="php"> </script>
Некоторые PHP-серверы настроены на использование только одного варианта из выше перечисленых тегов.
С помощью файла (в таком случае подключение можно осуществлять и на странице с *.html расширением):
<?php
include "main.php";
?>
Но для работы этого способа в файл .htaccess, который находится в корне сайта, в самый верх, необходимо добавить строки:
RemoveHandler .html .htm
AddType application/x-httpd-php .php .htm .html .phtml
Когда пользователь запрашивает страницу .html, её текст обрабатывается интерпретатором языка PHP.
Эта программа сканирует страницу, находит на ней все PHP-команды, выполняет их и помещает на их место полученный HTML-код.
Доступ к данным из HTML формы, осуществляется через:
echo $_POST['userName']; или
echo $_REQUEST['useNname'];
$_POST - Переменные HTTP POST.
Ассоциативный массив данных, переданных скрипту через HTTP методом POST при использовании application/x-www-form-urlencoded или multipart/form-data в заголовке Content-Type запроса HTTP.
$_REQUEST - Переменные HTTP-запроса.
Ассоциативный массив (array), который по умолчанию содержит данные переменных $_GET, $_POST и $_COOKIE.
Это 'суперглобальные' или автоматические глобальные переменные. Они доступны во всех контекстах скрипта. Нет необходимости выполнять global $variable; для доступа к ним внутри метода или функции.
На некоторых PHP серверах функция автоматического создания переменной из формы бывает выключена, но существует обходной вариант.
Если в форме присутствует поле с именем, например, userName, добавляем в начало программы, получающей значение из этого поля, следующий код:
$userName=$_REQUEST["userName"];
Повторяем это выражение для каждой переменной, значение которой необходимо извлеч из формы.
Имена всех переменных в PHP должны начинаться со знака $ - так интерпретатору значительно легче "понять" и отличить их, например, в строках.
Имена переменных чувствительны к регистру букв: например, $var - не то же самое, что $Var или $VAR.
Переменная - это область оперативной памяти, доступ к которой осуществляется по имени. Все данные, с которыми работает программа, хранятся в виде переменных (исключение - константа, которая, впрочем, может содержать только число или строку). При присвоении переменная копируется один в один, какую бы сложную структуру она ни имела.
В большинстве языков любая переменная созданная на основном уровне, доступна из любой функции.
На PHP придётся явно указывать, что глобальная переменная должна быть доступна и внутри функции (в одном операторе global можно указывать несколько переменных, разделяя их запятой). Если этого не сделать, то на уровне функции будет создана новая локальная переменная с таким же именем и без значения.
<?php
$a="I have a value";
$b="I have a value";
myFunction();
function myFunction() {
// сделать $a глобальной, а $b нет
global $a;
echo "inside the function,
\$a is '$a' and
\$b is '$b' and"; // если PHP встречает знак $ внутри текста, заключённого в кавычки, он по умолчанию считает, что имеет дело с переменной. Для того, чтобы сообщить интерпретатору о том, что на экране должен появиться данный знак, перед ним необходимо поставить обратную косую черту \.
}
?>
inside the function,
$a is 'I have a value' and
$b is '' and
В PHP, начиная с версии 4, существует понятие ссылок - жёстких и символических.
Ссылки в PHP - это средство доступа к содержимому одной переменной под разными именами. В PHP имя переменной и её содержимое - это разные вещи, поэтому одно содержимое может иметь разные имена. Ближайшая аналогия - имена файлов Unix и файлы - имена переменных являются элементами каталогов, а содержимое переменных это сами файлы. Ссылки в PHP - аналог жёстких ссылок (hardlinks) в файловых системах Unix.
Чтобы создать жёсткую ссылку, нужно использовать оператор & (амперсанд). Например:
$a=10;
$b = &$a; // теперь $b - то же самое, что и $a
$b=0; // на самом деле $a=0
echo "b=$b, a=$a"; // Выводит: "b=0, a=0"
Ссылаться можно не только на переменные, но и на элементы массива (этим жёсткие ссылки выгодно отличаются от символических). Например:
$A=array('a' => 'aaa', 'b' => 'bbb');
$b=&$A['b']; // теперь $b - то же, что и элемент с индексом 'b' массива
$b=0; // на самом деле $A['b']=0;
echo $A['b']; // Выводит 0
Элемент массива, для которого планируется создать символическую ссылку, может и не существовать. Как в следующем случае:
$A=array('a' => 'aaa', 'b' => 'bbb');
$b=&$A['c']; // теперь $b - то же, что и элемент с индексом 'c' массива
echo "Элемент с индексом 'c': (".$A['c'].")";
В результате выполнения рассмотренного скрипта, хотя ссылке $b и не было ничего присвоено, в массиве $A создастся новый элемент с ключом c и значением - пустой строкой (можно это определить по результату работы echo). То есть, жёсткая ссылка на самом деле не может ссылаться на несуществующий объект, а если делается такая попытка, то объект создаётся.
Если убрать строку, в которой создаётся жёсткая ссылка, то будет выведено сообщение о том, что элемент с ключом c не определён в массиве $A.
Жёсткие ссылки удобно применять при передаче параметров пользовательской функции и возврате значения из неё.
Символическая ссылка - это всего лишь строковая переменная, хранящая имя другой переменной (переменная переменная). Чтобы добраться до значения переменной, на которую ссылается символическая ссылка, необходимо применить дополнительный знак $ перед именем ссылки, например:
$a=10;
$b=20;
$c=30;
$p="a"; // или $p="b" или $p="c" (присваиваем $p имя другой переменной)
echo $$p; // выводит переменную, на которую ссылается $p, т. е. $a
$$p=100; // присваивает $a значение 100
Для того, чтобы использовать обычную строковую переменную как ссылку, нужно перед ней поставить ещё один символ $.Это говорит интерпретатору, что надо взять не значение самой $p, а значение переменной, имя которой хранится в переменной $p.
При удалении ссылки, просто разрывается связь имени и содержимого переменной. Это не означает, что содержимое переменной будет разрушено. Например:
<?php
$a = 1;
$b =& $a;
unset($a);
?>
Этот код не сбросит $b, а только $a.
Жёсткая ссылка - не абсолютно точный синоним объекта, на который она ссылается.
Жёсткая ссылка и переменная (объект), на которую она ссылается, совершенно равноправны, изменение одной влечёт изменение другой. Оператор Unset() разрывает связь между объектом и ссылкой, но объект удаляется только тогда, когда на него никто уже не ссылается.
Приведение типов в PHP, имя требуемого типа записывается в круглых скобках перед приводимой переменной:
<?php
$foo = 10; // $foo - это целое число
$bar = (boolean) $foo; // $bar - это булев тип
?>
Допускаются следующие приведения типов:
(int), (integer) - приведение к integer, int - это число из множества ℤ = {..., -2, -1, 0, 1, 2, ...};
(bool), (boolean) - приведение к boolean;
(float), (double), (real) - приведение к float;
(string) - приведение к string;
(array) - приведение к array;
(object) - приведение к object;
(unset) - приведение к NULL.
Операторы инкремента/декремента влияют только на числа и строки. Массивы, объекты, булевы значения и ресурсы не будут изменены.
Декремент NULL также не даст никакого эффекта, однако инкремент даст значение 1.
++$a Префиксный инкремент увеличивает $a на единицу и возвращает значение $a.
$a++ Постфиксный инкремент возвращает значение $a, а затем увеличивает $a на единицу.
--$a Префиксный декремент уменьшает $a на единицу и возвращает значение $a.
$a-- Постфиксный декремент возвращает значение $a, а затем уменьшает $a на единицу.
Префиксные операторы инкремента и декремента, которые указываются до переменной, возвращают значение переменной уже после изменения:
$a=10;
$b=--$a;
echo "a=$a, b=$b"; // Выводит a=9, b=9
Постфиксные операторы инкремента и декремента эти операторы увеличивают или уменьшают значение переменной, а в выражении возвращают значение переменной $a до изменения:
$a=10;
$b=$a++;
echo "a=$a, b=$b"; // Выводит a=11, b=10
PHP поддерживает оператор исполнения: обратные кавычки (``). Это не одиночные кавычки. PHP пытается выполнить строку, заключённую в обратные кавычки, как консольную команду, и возвращает полученный вывод (т.е. он не просто выдаётся на выходе а, например, может быть присвоен переменной). Использование обратных кавычек аналогично использованию функции shell_exec().
<?php
$output = `ls -al`;
echo "<pre>$output</pre>";
?>
PHP поддерживает оператор управления ошибками: знак @. В случае, если он предшествует какому-либо выражению в PHP-коде, любые сообщения об ошибках, генерируемые этим выражением, будут проигнорированы.
В случае, если установлена опция track_errors, все генерируемые сообщения об ошибках будут сохраняться в переменной $php_errormsg. Эта переменная будет перезаписываться при возникновении каждой новой ошибки, поэтому в случае необходимости проверять её нужно сразу же:
<php
// Преднамеренная ошибка при работе с файлами
$my_file = @file ('non_existent_file') or
die ("Failed opening file: error was '$php_errormsg'");
// работает для любых выражений, а не только для функций
$value = @$cache[$key];
// В случае если ключа $key нет, сообщение об ошибке не будет отображено
?>
Оператор @ работает только с выражениями. Есть простое правило: если произвольная языковая конструкция возвращает значение, значит можно использовать предшествующий ей оператор @. Например, можно использовать @ перед именем переменной, произвольной функцией или вызовом include(), константой и так далее. В то же время можно использовать этот оператор перед определением функции или класса, условными конструкциями, такими как if или foreach.
Оператор @ не подавляет вывод ошибок, возникающих на стадии синтаксического разбора скрипта.
Оператор @ подавляет вывод сообщений даже о критических ошибках прерывающих работу скрипта. Помимо всего прочего, это означает, что если использовался @ для подавления ошибок, возникающих при работе какой-либо функции, в случае если она недоступна или написана неправильно, дальнейшая работа скрипта будет остановлена без каких-либо уведомлений.
В версиях PHP 5.6 и выше список аргументов может содержать многоточие ..., чтобы показать, что функция принимает переменное количество аргументов. Аргументы в этом случае будут переданы в виде массива.
Пример использование ... для доступа к аргументам:
<?php
function sum(...$numbers) {
$acc = 0;
foreach ($numbers as $n) {
$acc += $n;
}
return $acc;
}
echo sum(1, 2, 3, 4);
?>
Результат выполнения данного примера: 10
Чтобы использовать одинарную кавычку внутри строки, как и во многих других языках, её необходимо предварить символом обратной косой черты (\), т. е. экранировать её.
Если интерпретатор встречает знак доллара ($), он захватывает так много символов, сколько возможно, чтобы сформировать правильное имя переменной. Если необходимо точно определить конец имени, необходимо заключить имя переменной в фигурные скобки.
<?php
$beer = 'Heineken';
echo "$beer's taste is great"; // работает, "'" это неверный символ для имени переменной
echo "He drank some $beers"; // не работает, 's' это верный символ для имени переменной
echo "He drank some ${beer}s"; // работает
echo "He drank some {$beer}s"; // работает
?>
Использование в PHP оператора "+" для конкатенации строк некорректно.
Первый - оператор конкатенации ('.'), который возвращает объединение левого и правого аргумента.
Второй - оператор присвоения с конкатенацией, который присоединяет правый аргумент к левому.
Пример:
<?php
$a = "Hello ";
$b = $a . "World!"; // $b содержит строку "Hello World!" - Это конкатенация
$a = "Hello ";
$a .= "World!"; // $a содержит строку "Hello World!" - Это присвоение с конкатенацией
?>
Для сравнения строк не рекомендуется использовать операторы сравнения == и !=, поскольку они требуют преобразования типов.
В PHP операнды сравниваются, как строки, только в том случае, если оба они - строки. В противном случае они сравниваются как числа. При этом любая строка, которую PHP не удаётся перевести в число (в том числе и пустая строка), будет восприниматься как 0.
Чтобы избежать путаницы и преобразования типов, рекомендуется пользоваться оператором эквивалентности при сравнении строк. Оператор эквивалентности позволяет всегда корректно сравнивать строки, поскольку сравнивает величины и по значению, и по типу:
<?php
$x="Строка";
$y="Строка";
$z="Строчка";
if ($x === $z) echo "<p>Строка X равна строке Z</p>";
if ($x === $y) echo "<p>Строка X равна строке Y</p>";
if ($x !== $z) echo "<p>Строка X НЕ равна строке Z</p>";
// Выводит:
// Строка X равна строке Y
// Строка X НЕ равна строке Z
?>
Когда PHP - процессор обнаруживший точку с запятой ";",он считает, что кода который должен быть выполнен, нет вообще.
Использование фигурных скобок показывает, что несколько строк кода должны восприниматься как одна структура и эта структура является частью текущей логической структуры.
Отличие массива от переменных, состоит в том, что он может иметь несколько значений.
Для разделения этих значений используется индекс, заключенный в квадратные скобки.
Каждый из элементов имеет одно и тоже имя, но собственный цифровой индекс, чтобы их можно было различить.
Во многих языках программирования необходимо явно описывать переменные массивы, но в PHP просто присваивается переменной значение с индексом в квадратных скобках и массив создан.
$camelPop[1]="Somalia";
$camelPop[2]="Sudan";
$camelPop[3]="Mauritania";
$camelPop[4]="Pakistan";
$camelPop[5]="India";
for ($i-1; $i <= 5; $i++){
echo "$i: $camelPop[$i]<br>";
}
Некоторые веб-серверы (такие, на которых опции сообщения об ошибках присвоено знечение E_ALL) могут выдать предупреждение. В этом случае можно явно создать пустой массив с помощью функции array(), описанной ниже, а затем присваивать ему значения.
Очень часто точно известно, какие именно значения необхолимо поместить в массив. В PHP можно использовать функцию array(), при этом индексы элементов массива создаются автоматически.
Знать, сколько именно содержит элементов массив, не обязательно. PHP содержит функцию count(), которая может определить их количество.
<?php
$camelPop =array("Somalia","Sudan","Mauritania","Pakistan","India");
for ($i=0; $i< count($camelPop); $i++){
echo "$i:$camelPop[$i]<br>";
}
?>
0:Somalia
1:Sudan
2:Mauritania
3:Pakistan
4:India
Большинство языков программирования, в том числе и PHP, начинают счёт не с единицы, а с нуля.
Цикл foreach: первый параметр конструкции foreach - это массив. Ключевое слово as указывает на имя переменной, в которой будет содержать каждое значение по очереди. Цикл foreach пройдёт через массив столько раз, сколько это необходимо.
На каждом витке цикла функция поместит в переменную текущий элемент массива.
$camelPop =array("Somalia","Sudan","Mauritania","Pakistan","India");
foreach ($camelPop as $value){
echo "$value<br>";
}
Основное отличие между циклами foreach и for - это отсутствие ключевой переменной (в примере $i).
Цикл foreach может быть полезен, когда необходимо пройтись через каждое значение массива.
Ассоциативный массив использует строковые индексы.
$stateCap["Alaska"]="Juneau";
$stateCap["Indiana"]="Indianapolis";
$stateCap["Michigan"]="Lansing";
Индексы должны быть заключены в кавычки.
Создание ассоциативных массивов требует другого синтаксиса, в отличие от обычных массивов. Когда создаётся обычный массив, функция array() требует данные, но не требует перечисления индексов.
В ассоциативном массиве необходимо предоставление как данных, так и индексов.
Формат для таких присвоений содержит оператор присвоения => , который указывает на то, что элемент содержит какое либо значение.
$stateCap=array("Alaska"=>"Juneau","Indiana"=>"Indianapolis","Michigan"=>"Lansing");
echo "Indiana: ";
echo $stateCap["Indiana"];
В цикле foreach для ассоциативных массивов используется немного другой синтаксис.
При работе с обычными массивами в цикле используется только одна переменная, так как индекс легко вычисляется.
В ассоциативных массивах каждый элемент в массиве имеет уникальный индекс и значение.
Ассоциативная форма цикла foreach учитывает это и содержит две переменные. В первой переменной содержится индекс, во второй - значение, соответствующее этому индексу.
$stateCap=array("Alaska"=>"Juneau","Indiana"=>"Indianapolis","Michigan"=>"Lansing");
foreach ($stateCap as $contry=>$capital){
echo "$contry:$capital<br>\n";
}
В отличие от обычных массивов, ассоциативный массив не даёт никаких гарантий относительно того, в каком порядке цикл foreach будет возвращать элементы массива.
Если обычные массивы похожи на список, ассоциативные массивы похожи на пары имён и значений, то многомерный тип массива похож на таблицу с данными.
Индианаполис | Нью Йорк | Токио | Лондон | |
---|---|---|---|---|
Индианаполис | 0 | 648 | 6476 | 4000 |
Нью Йорк | 648 | 0 | 6760 | 3470 |
Токио | 6476 | 6760 | 0 | 5956 |
Лондон | 4000 | 3470 | 5956 | 0 |
Для упрощения понимания в дальнейшем, присваиваем городам численные значения:
Индианаполис=0
Нью Йорк=1
Токио=2
Лондон=3
Определяем расстояния между городами (см. табл. выше):
$city=array (
"Indianapolis",
"New York",
"Tokyo",
"london"
);
$distance=array (
array(0,648,6476,4000),
array(648,0,6760,3470),
array(6476,6760,0,5956),
array(4000,3470,5956,0)
);
$result=$distance[$cityA] [$cityB];
echo "$city[$cityA] and $city[$cityB]";
echo "is $result miles";
Первый массив $city - массив строковых значений, он содержит список названий городов, численные значения которых соответствуют присвоеным выше.
Массив $distance содержит внутренние массивы.
Каждый из внутренних массивов соответствует расстоянию от определённого города. Например, поскольку Индианополис - это 0, первый (нулевой) внутренний масив содержит расстояние между Индианополисом и другими городами и т.д.
Чтобы найти информацию в таблице, необходимо знать строку и столбец. Двумерный массив требует двух индексов - один для строки и один для столбца.
Чтобы найти расстояние между Токио (город номер 2) и Нью Йорком (город номер 1), необходимо обратиться $distance[2] [1].
Это значение сохраняется в переменной $result.
Бывает необходимо работать с файлом как с массивом данных в памяти.
<?php
$fp = file("comments.txt");
$output = "";
foreach ($fp as $dl){
$dl=str_replace("r", "t",$dl);
$dl=str_replace("l", "w",$dl);
$output .=rtrim($dl, "<br>\n");}
echo $output;
?>
Команда file() открывает файл для чтения и возвращает массив, в котором каждому элементу соответствует одна строка файла.
Цикл foreach, в данном случае, используется для просмотра каждой строки и её изменения.
Внутри цикла foreach просто заменить, например, все буквы "r" и "l" на "t" и "w" с помощью функции str_replace(), она заменяет все вхождения строки поиска на строку замены в строке или массиве, в котором производится поиск и замена.
После этого полученная строка добавляется в переменную $output.
rtrim() удаляет пробелы (или другие символы) из конца строки.
Команда file() загружает весь файл в память. Использование её для очень больших файлов может сильно снизить производительность.
При использовании fgets() необходимо хранить в памяти только одну строку файла, поэтому этот метод можно использовать для работы с файлами любого размера.
Существуют обходные способы работы с файлами, которые не требуют создания указателя на файл. Команда readfile("comments.txt") принимает в качестве аргумента имя файла, запрашивает содержимое этого файла и отображает его на странице как простой HTML код.
PHP содержит несколько команд, которые помогают управлять директориями.
Ниже приведена программа, генерирующая список всех файлов gif и jpg, содержащихся в заданной директории.
Технология, используемая для отображения файлов изображения, может использоваться для получения определённых наборов файлов из любой директории.
<php
// сохраняем целевую директорию в переменной $dirName.
$dirName = "../htdocs";
$dp = opendir($dirName);
chdir($dirName);
// добавить все файлы, находящиеся в директории, в массив $theFiles
while ($currentFile !== false) {
$currentFile = readdir($dp);
$theFiles[ ] = $currentFile;}
// извлеч все файлы gif и jpg
$imageFiles = preg_grep("/gif$|jpg$/",$theFiles);
$output="";
foreach ($imageFiles as $currentFile){
$output .=<<<TOSHA
<img src = $currentFile
height=32 width=28>
TOSHA;}
// сохранить список в локальную файловую систему
$fp =fopen("imageIndex.html","w"); // 'w' открывает файл только для записи; помещает указатель в начало файла и обрезает файл до нулевой длины. Если файл не существует - пробует его создать.
fwrite ($fp,$output);
fclose($fp);
echo "<a href=imageIndex.html>image index</a>";
?>
chdir() изменяет текущий каталог PHP на указанный.
preg_grep() возвращает массив, состоящий из элементов входящего массива, которые соответствуют заданному шаблону. В данном случае выбираются все файлы, которые имеют расширение gif или jpg и копируются в другой массив, с названием $imageFiles.
Обобщенный синтаксис элементов многомерного простого массива:
$имя[индекс1][индекс2]..[индексN];
Пример простого многомерного массива:
<?php
// Многомерный простой массив:
$arr[0][0]="Овощи";
$arr[0][1]="Фрукты";
$arr[1][0]="Абрикос";
$arr[1][1]="Апельсин";
$arr[1][2]="Банан";
$arr[2][0]="Огурец";
$arr[2][1]="Помидор";
$arr[2][2]="Тыква";
// Выводим элементы массива:
echo "<h3>".$arr[0][0].":</h3>";
for ($q=0; $q<=2; $q++) {
echo $arr[2][$q]."<br>";
}
echo "<h3>".$arr[0][1].":</h3>";
for ($w=0; $w<=2; $w++) {
echo $arr[1][$w]."<br>";
}
?>
В PHP индексом массива может быть не только число, но и строка. Причём на такую строку не накладываются никакие ограничения: она может содержать пробелы, длина такой строки может быть любой.
Ассоциативные массивы особенно удобны в ситуациях, когда элементы массива удобнее связывать со словами, а не с числами.
Массивы, индексами которых являются строки, называются ассоциативными массивами.
Одномерные ассоциативные массивы содержат только один ключ (элемент), соответствующий конкретному индексу ассоциативного массива. Пример:
<?php
// Ассоциативный массив
$names["Иванов"]="Иван";
$names["Сидоров"]="Николай";
$names["Петров"]="Петр";
// В данном примере: фамилии - ключи ассоциативного массива,
// а имена - элементы массива names
?>
Доступ к элементам одномерных ассоциативных массивов осуществляется так же, как и к элементам обыкновенных массивов, и называется доступом по ключу:
echo $names["Иванов"];
Многомерные ассоциативные массивы могут содержать несколько ключей, соответствующих конкретному индексу ассоциативного массива.
Пример многомерного ассоциативного массива:
<?php
// Многомерный массив
$A["Ivanov"] = array("name"=>"Иванов И.И.", "age"=>"25", "email"=>"ivanov@mail.ru");
$A["Petrov"] = array("name"=>"Петров П.П.", "age"=>"34", "email"=>"petrov@mail.ru");
$A["Sidorov"] = array("name"=>"Сидоров С.С.", "age"=>"47", "email"=>"sidorov@mail.ru");
?>
Доступ к элементам многомерного ассоциативного массива осуществляется следующим образом:
echo $A["Ivanov"]["name"]; // Выводит Иванов И.И.
echo $A["Petrov"]["email"]; // Выводит petrov@mail.ru
Функция array() используется специально для создания массивов. При этом она позволяет создавать пустые массивы. Вот методы использования функции array():
<?php
// Создает пустой массив:
$arr = array();
// Создает список с тремя элементами. Индексы начинаются с нуля:
$arr2 = array("Иванов","Петров","Сидоров");
// Создает ассоциативный массив с тремя элементами:
$arr3 = array("Иванов"=>"Иван", "Петров"=>"Петр", "Сидоров"=>"Сидор");
// Создает многомерный ассоциативный массив:
$arr4 = array("name"=>"Иванов", "age"=>"24", "email"=>"ivanov@mail.ru");
$arr4 = array("name"=>"Петров", "age"=>"34", "email"=>"petrov@mail.ru");
$arr4 = array("name"=>"Сидоров", "age"=>"47", "email"=>"sidorov@mail.ru");
?>
Ассоциативные многомерные массивы можно создавать и классическим способом, хотя это не так удобно:
<?php
// Многомерный ассоциативный массив
$A["Ivanov"]["name"]="Иванов И.И.";
$A["Ivanov"]["age"]="25";
$A["Ivanov"]["email"]="ivanov@mail.ru";
$A["Petrov"]["name"]="Петров П.П.";
$A["Petrov"]["age"]="34";
$A["Petrov"]["email"]="petrov@mail.ru";
$A["Sidorov"]["name"]="Сидоров С.С.";
$A["Sidorov"]["age"]="47";
$A["Sidorov"]["email"]="sidorov@mail.ru";
// Получаем доступ к ключам многомерного ассоциативного массива
echo $A["Ivanov"]["name"]."<br>"; // Выводит Иванов И.И.
echo $A["Sidorov"]["age"]."<br>"; // Выводит 47
echo $A["Petrov"]["email"]."<br>"; // Выводит petrov@mail.ru
?>
Регулярные выражения, это формальный язык поиска и осуществления манипуляций с подстроками в тексте, основанный на использовании метасимволов. Для поиска используется строка-образец (англ. pattern, по-русски её часто называют «шаблоном», «маской»), состоящая из символов и метасимволов и задающая правило поиска.
Любой шаблон должен быть ограничен символами-ограничителями. В качестве таких символов можно использовать любой не буквенно-цифровой символ кроме '\'.
Не рекомендуется использовать в качестве ограничителей и другие специальные символы, в виду того, что их использование внутри шаблона станет неудобным.
Предпочтительнее всего использовать символ /, потому что он не выполняет никаких специальных функций.
Символ, используемый как ограничитель шаблона внутри шаблона должен экранироваться.
Пример: '/pattern/i' - соответствует строке, в которой есть слово pattern.
i - это модификатор, он означает регистронезависимое сравнение.
Спецсимволы:
\ - символ экранирования.
Пример: '/qwe\/rty/' - соответствует строке, в которой есть qwe/try. Символ / заэкранирован, после чего он перестал выполнять в данном месте своё специальное значение (он являлся ограничителем шаблона).
^ - символ начала данных.
$ - символ конца данных.
Пример: '/^pattern$/' - Соответствует строке, точно совпадающей с словом pattern. Т.е. с буквы p строка начинается и после n заканчивается.
. - любой символ, кроме перевода строки. Но есть модификатор, при использовании которого перевод строки тоже относится к "любым" символам.
Пример: '/pat.ern/' - Соответствует и строке, содержащей pattern, или patdern, или pat3ern...
[ ] - внутри этих скобок перечисляются символы, любой один символ из которых может стоять на данном месте. Это называется символьным классом. Спецсимволы, написанные в [ ] ведут себя немного по-другому.
Пример: '/pat[aoe]rn/' - под соответствие попадут только строки, содержащие patarn, patorn или patern.
| - Или.
() - подмаска.
? - одно или ноль вхождений предшествующего символа или подмаски.
* - любое количество вхождений предшествующего символа или подмаски. В том числе и ноль.
+ - одно или более вхождений.
Пример: '/as+(es|du)?.*r/' - Буква а, потом одна или больше букв s, после этого сочетание es или du может быть один раз, а может и ни разу, потом любое количество любых символов и буква r.
Ещё одно значения символа ?. В примере части '.*r' будет соответствовать, например, подстрока asdrfsrsfdr. До последней буквы r в неё попало ещё две. Это можно выключить. Т.е. шаблон станет соответствовать только подстроке asdr, до первого r. Для этого надо до того места поставить модификатор (?U). Это ещё одно применение символам ? и ().
{a,b} - количество вхождений предшествующего символа или подмаски от а до b. Если b не указан, считается, что верхней границы нет. Например, * - то же самое, что {0,}. ? - то же, что {0,1}. {5,7} - 5,6 или 7 повторений.
Спецсимволы внутри символьного класса:
^ - отрицание.
Пример: [^da] - соответствует любому символу кроме d и a.
Пример: [^^] - соответствует любому символу кроме ^.
Пример: [d^a] - соответствует любому символу из перечисленных трёх. [\^da] - то же самое.
В последнем примере, символ стоит не в начале перечисления и свою метафункцию теряет. И экранировать его тоже тут не надо.
- - внутри символьного класса означает символьный интервал.
Пример: [0-9a-e] - соответствует любому символу от 0 до 9 и от a до e. Если в символьном классе надо перечислить сам символ дефиса, то следует либо заэранировать его, либо разместить перед ].
Осторожно в символьном классе надо использовать символ \. Если его поставить перед ], она окажется заэкранирована. Также окажется заэкранированным любой символ, который может быть заэкранирован. Иначе символ \ является обычным символом.
Символ $ тоже является обычным символом внутри символьного класса. И скобки тоже.
Символ \. Одна из его функций - снятие специального значения с спецсимволов. А другая, наоборот придание специальных функций обычным символам.
\cx - ctrl + x. На месте x может быть любой символ.
\e - escape.
\f - разрыв страницы.
\n, \r, \t - перевод строки, возврат каретки и табуляция.
\d - любой символ, означающий десятичную цифру.
\D - любой символ, не означающий десятичную цифру.
\s - любой пробельный символ.
\S - не пробельный.
\w - любая цифра, буква или знак подчеркивания.
\W - любой символ, но не \w.
\b - граница слова. Можно использовать вместо \w\W или \W\w или ^\w или \w$
\B - не граница слова.
Две последние конструкции не соответствуют никаким реальным символам.
\xHH - символ с шестнадцатиричным кодом HH. x - это именно буква икс.
\DDD - символ с восьмиричным кодом DDD. Или ссылка на подмаску.
<?php
if (логическое выражение) оператор;
?>
Согласно выражениям PHP, конструкция if содержит логическое выражение. Если логическое выражение истинно (true), то оператор, следующий за конструкцией if будет исполнен, а если логическое выражение ложно (false), то следующий за if оператор исполнен не будет.
Часто необходим блок операторов, который будет выполняться при определённом условном критерии, тогда эти операторы необходимо поместить в фигурные скобки {...}:
<?php
if ($a > $b) {
echo "a больше b";
$b = $a;
}
?>
В случае, если условие конструкции if не выполнено, нельзя обойтись без конструкции else.
Синтаксис конструкции if-else такой:
if (логическое_выражение)
инструкция_1;
else
инструкция_2;
Если логическое_выражение истинно, то выполняется инструкция_1, а иначе — инструкция_2. Как и в любом другом языке, конструкция else может опускаться, в этом случае при получении должного значения просто ничего не делается.
Если инструкция_1 или инструкция_2 должны состоять из нескольких команд, то они, как всегда, заключаются в фигурные скобки. Например:
<?php
if ($a > $b) {
echo "a больше, чем b";
} else {
echo "a НЕ больше, чем b";
}
?>
Конструкция elseif, сочетание if и else. Аналогично else, она расширяет оператор if для выполнения различных выражений в случае, когда условие начального оператора if эквивалентно FALSE. Однако, в отличие от else, выполнение альтернативного выражения произойдёт только тогда, когда условие оператора elseif будет являться равным TRUE. К примеру, следующий код может выводить a больше, чем b, a равно b или a меньше, чем b:
<?php
if ($a > $b) {
echo "a больше, чем b";
} elseif ($a == $b) {
echo "a равен b";
} else {
echo "a меньше, чем b";
}
?>
Может быть несколько elseif в одном выражении if. Первое выражение elseif (если оно есть) равное TRUE будет выполнено.
В PHP также можно написать 'else if' (в два слова), и тогда поведение будет идентичным 'elseif' (в одно слово). Синтаксически значение немного отличается, но в конечном итоге оба выражения приведут к одному и тому же результату.
Выражение elseif выполнится, если предшествующее выражение if и предшествующие выражения elseif эквивалентны FALSE, а текущий elseif равен TRUE.
elseif и else if будут равнозначны только при использовании фигурных скобок, как в примерах выше. Если используются синтаксис с двоеточием для определения условий if/elseif, необходимо разделять else if на два слова, иначе это вызовет фатальную ошибку в PHP.
Часто вместо нескольких расположенных подряд инструкций if-else целесообразно воспользоваться специальной конструкцией выбора switch-case.
Данная конструкция предназначена для выбора действий, в зависимости от значения указанного выражения. Конструкция switch-case чем-то напоминает конструкцию if-else, который, по сути, является ее аналогом. Конструкцию выбора можно использовать, если предполагаемых вариантов много, например, более 5, и для каждого варианта нужно выполнить специфические действия. В таком случае, использование конструкции if-else становится действительно неудобным.
Синтаксис конструкции switch-case такой:
switch(выражение) {
case значение1: команды1; [break;]
case значение2: команды2; [break;]
. . .
case значениеN: командыN; [break;]
[default: команды_по_умолчанию; [break]]
}
Принцип работы конструкции switch-case такой:
Вычисляется значение выражения;
Просматривается набор значений. Пусть значение 1 равно значению выражения, вычисленного на первом шаге. Если не указана конструкция (оператор) break, то будут выполнены команды i, i+1, i+2, ..., N. В противном случае (есть break) будет выполнена только команда с номером i.
Если ни одно значение из набора не совпало со значением выражения, тогда выполняется блок default, если он указан.
Циклы позволяют повторять определённое (и даже неопределённое - когда работа цикла зависит от условия) количество раз различные операторы. Данные операторы называются телом цикла. Проход цикла называется итерацией.
Цикл с предусловием while работает по следующим принципам:
Вычисляется значение логического выражения.
Если значение истинно, выполняется тело цикла, в противном случае - переходим на следующий за циклом оператор.
Синтаксис цикла с предусловием:
while (логическое_выражение)
инструкция;
В данном случае телом цикла является инструкция. Обычно тело цикла состоит из большого числа операторов. Пример цикла с предусловием while:
<?php
$x=0;
while ($x++<10) echo $x;
// Выводит 12345678910
?>
Сначала проверяется условие, а только потом увеличивается значение переменной. Если поставить операцию инкремента перед переменной (++$x<10), то сначала будет выполнено увеличение переменной, а только затем - сравнение. В результате получим строку 123456789.
Цикл с постусловием do while.
В отличие от цикла while, этот цикл проверяет значение выражения не до, а после каждого прохода (итерации). Таким образом, тело цикла выполняется хотя бы один раз. Синтаксис цикла с постусловием такой:
do
{
тело_цикла;
}
while (логическое_выражение);
После очередной итерации проверяется, истинно ли логическое_выражение, и, если это так, управление передаётся вновь на начало цикла, в противном случае цикл обрывается.
Пример скрипта, показывающего работу цикла с постусловием do-while:
<?php
$x = 1;
do {
echo $x;
} while ($x++<10);
?>
Рассмотренный сценарий выводит: 12345678910
Цикл со счётчиком for используется для выполнения тела цикла определённое число раз. С помощью цикла for можно создавать конструкции, которые будут выполнять действия совсем не такие тривиальные, как простая переборка значения счётчика.
Синтаксис цикла for такой:
for (инициализирующие_команды; условие_цикла; команды_после_итерации) {тело_цикла;}
Цикл for начинает свою работу с выполнения инициализирующих_команд. Данные команды выполняются только один раз. После этого проверяется условие_цикла, если оно истинно (true), то выполняется тело_цикла. После того, как будет выполнен последний оператор тела, выполняются команды_после_итерации. Затем снова проверяется условие_цикла. Если оно истинно (true), выполняется тело_цикла и команды_после_итерации, и.т.д.
<?php
for ($x=0; $x<10; $x++) echo $x;
?>
Данный сценарий выводит: 0123456789
Есть вариант вывода строки 12345678910:
<?php
for ($x=0; $x++<10;) echo $x;
?>
В данном примере обеспечено увеличение счётчика при проверке логического выражения. В таком случае не нужны были команды, выполняющиеся после итерации.
Если необходимо указать несколько команд, их можно разделить запятыми, пример:
<?php
for ($x=0, $y=0; $x<10; $x++, $y++) echo $x;
// Выводит: 0123456789
?>
Еще один, более практичный пример использования нескольких команд в цикле for:
<?php
for($i=0,$j=0,$k="Точки"; $i<10; $j++,$i+=$j) {$k=$k."."; echo $k,';', $j,';', $i,';';}
// Выводит: Точки.;0;0;Точки..;1;1;Точки...;2;3;Точки....;3;6;
?>
Специальный тип цикла - foreach предназначен специально для перебора массивов.
Синтаксис цикла foreach выглядит следующим образом:
foreach (массив as $ключ=>$значение)
команды;
Здесь команды циклически выполняются для каждого элемента массива, при этом очередная пара ключ=>значение оказывается в переменных $ключ и $значение. Пример работы цикла foreach:
<?php
$names["Иванов"] = "Андрей";
$names["Петров"] = "Борис";
$names["Волков"] = "Сергей";
$names["Макаров"] = "Федор";
foreach ($names as $key => $value) {
echo "<b>$value $key</b>";
}
?>
Рассмотренный сценарий выводит:
Андрей Иванов
Борис Петров
Сергей Волков
Федор Макаров
У цикла foreach имеется и другая форма записи, которую следует применять, когда не интересует значение ключа очередного элемента. Выглядит она так:
foreach (массив as $значение)
команды;
В этом случае доступно лишь значение очередного элемента массива, но не его ключ. Это может быть полезно, например, для работы с массивами-списками:
<?php
$names[ ] = "Андрей";
$names[ ] = "Борис";
$names[ ] = "Сергей";
$names[ ] = "Федор";
foreach ($names as $value) {
echo "<b>$value</b>";
}
?>
Цикл foreach оперирует не исходным массивом, а его копией. Это означает, что любые изменения, которые вносятся в массив, не могут быть "видны" из тела цикла. Что позволяет, например, в качестве массива использовать не только переменную, но и результат работы какой-нибудь функции, возвращающей массив (в этом случае функция будет вызвана всего один раз - до начала цикла, а затем работа будет производиться с копией возвращённого значения).
Очень часто для того, чтобы упростить логику какого-нибудь сложного цикла, удобно иметь возможность его прервать в ходе очередной итерации (к примеру, при выполнении какого-нибудь особенного условия). Для этого и существует конструкция break, которая осуществляет немедленный выход из цикла. Она может задаваться с одним необязательным параметром - числом, которое указывает, из какого вложенного цикла должен быть произведён выход. По умолчанию используется 1, т. е. выход из текущего цикла, но иногда применяются и другие значения. Синтаксис конструкции break:
break; По умолчанию
break(номер_цикла); Для вложенных циклов (указывается номер прерываемого цикла). Примеры:
<?php
$x=0;
while ($x++<10) {
if ($x==3) break;
echo "<b>Итерация $x</b>";
}
// Когда $x равен 3, цикл прерывается
?>
Рассмотренный сценарий выводит:
Итерация 1
Итерация 2
Если необходимо прервать работу определённого (вложенного) цикла, то нужно передать конструкции break параметр - номер_цикла, например, break(1). Нумерация циклов выглядит следующим образом:
for (...) // Третий цикл
{
for (...) // Второй цикл
{
for (...) // Первый цикл
{
}
}
}
Конструкция continue так же, как и break, работает только "в паре" с циклическими конструкциями. Она немедленно завершает текущую итерацию цикла и переходит к новой (конечно, если выполняется условие цикла для цикла с предусловием). Точно так же, как и для break, для continue можно указать уровень вложенности цикла, который будет продолжен по возврату управления.
В основном continue позволяет сэкономить количество фигурных скобок в коде и увеличить его удобочитаемость. Это чаще всего бывает нужно в циклах-фильтрах, когда требуется перебрать некоторое количество объектов и выбрать из них только те, которые удовлетворяют определенным условиям. Пример использования конструкции continue:
<?php
$x=0;
while ($x++<5) {
if ($x==3) continue;
echo "<b>Итерация $x</b><br>";
}
// Цикл прервется только на третьей итерации
?>
Рассмотренный скрипт выводит:
Итерация 1
Итерация 2
Итерация 4
Итерация 5
При использовании операторов break и continue, первый из них прерывает работу всего цикла, а второй - только текущей итерации.
Функция называется рекурсивной, если она вызывает саму себя.
Пример функции с использованием рекурсии:
<?PHP
// $pre и $pre_pre - предыдущий и предпредыдущий элемент.
// $n номер элемента, который мы ищем, но реально смысл в этой переменной несколько другой.
// Она хранит в себе количество элементов, которое осталось посчитать.
// Считать сумму начинаем с 3го элемента.
function fib($n, $pre = 1, $pre_pre = 0)
{
if ($n == 1) return 1;
if ($n < 1) return false;
if ($n == 2) // начинали с 3го, поэтому выходим, когда осталось посчитать два.
return $pre;
return fib($n - 1, $pre + $pre_pre, $pre);
}
echo fib(5);
?>
Конструкция return возвращает значения, преимущественно из пользовательских функций, как параметры функционального запроса. При вызове return исполнение пользовательской функции прерывается, а конструкция return возвращает определённые значения.
Если конструкция return будет вызвана из глобальной области определения (вне пользовательских функций), то скрипт также завершит свою работу, а return также возвратит определённые значения.
Возвращаемые значения могут быть любого типа, в том числе это могут быть списки и объекты. Возврат приводит к завершению выполнения функции и передаче управления обратно к той строке кода, в которой данная функция была вызвана.
Пример использования конструкции return для возврата значений типа integer:
<?php
function retfunct()
{
return 7;
}
echo retfunct(); // выводит '7'
?>
Пример возврата конструкцией return массивов:
<?php
function numbers()
{
return array (0, 1, 2);
}
list ($zero, $one, $two) = numbers();
echo $zero;
echo $one;
echo $two;
// Выводит '012'
?>
Для того, чтобы функция возвращала результат по ссылке, необходимо использовать оператор & и при описании функции, и при присвоении переменной возвращаемого значения:
<?php
function &returns_reference()
{
return $someref;
}
$newref =& returns_reference();
?>
Конструкции включений позволяют собирать PHP программу (скрипт) из нескольких отдельных файлов.
Конструкция require позволяет включать файлы в сценарий PHP до исполнения сценария PHP. Общий синтаксис require такой:
require имя_файла;
При запуске (именно при запуске, а не при исполнении!) программы интерпретатор просто заменит инструкцию на содержимое файла имя_файла (этот файл может также содержать сценарий на PHP, обрамленный, как обычно, тэгами <? и ?>). Причём сделает он это непосредственно перед запуском программы (в отличие от include). Это бывает довольно удобно для включения в вывод сценария различных шаблонных страниц HTML-кодом. Пример:
Файл header.html:
<html>
<head><title>It is a title</title></head>
<body bgcolor=green>
Файл footer.html:
© Linuxtosha Company, 2021.
</body>
</html>
Файл script.php:
<?php
require "header.html";
// Сценарий выводит само тело документа
require "footer.html";
?>
Таким образом, конструкция require позволяет собирать сценарии PHP из нескольких отдельных файлов, которые могут быть как html-страницами, так и php-скриптами.
Конструкция require поддерживает включения удалённых файлов (начиная с версии PHP 4.3.0). Например:
<?php
// Следующий пример не работает, поскольку пытается включить локальный файл
require 'file.php?foo=1&bar=2';
// Следующий пример работает
require 'http://www.example.com/file.php?foo=1&bar=2';
?>
Конструкция require позволяет включать удаленные файлы, если такая возможность включена в конфигурационном файле PHP.
Конструкция include также предназначена для включения файлов в код сценария PHP.
В отличие от конструкции require конструкция include позволяет включать файлы в код PHP скрипта во время выполнения сценария. Синтаксис конструкции include выглядит следующим образом:
include имя_файла;
Принципиальная разница между конструкциями require и include на конкретном примере:
Создадим 10 файлов с именами 1.txt, 2.txt и так далее до 10.txt, содержимое этих файлов - просто десятичные цифры 1, 2 ...… 10 (по одной цифре в каждом файле). Создадим такой сценарий PHP:
<?php
// Создаем цикл, в теле которого конструкция include
for($i=1; $i<=10; $i++) {
include "$i.txt";
}
// Включили десять файлов: 1.txt, 2.txt, 3.txt ... 10.txt
// Результат - вывод 12345678910
?>
В результате получим вывод, состоящий из 10 цифр: "12345678910". Из этого можно сделать вывод, что каждый из файлов был включён по одному разу прямо во время выполнения цикла! Если поставить вместо include require, то сценарий сгенерирует критическую ошибку (fatal error).
PHP преобразует сценарий во внутреннее представление, анализируя строки сценария по очереди, пока не доходит до конструкции include. Дойдя до include, PHP прекращает транслировать сценарий и переключается на указанный в include файл. Таким образом из-за подобного поведения транслятора, быстродействие сценария снижается, особенно при большом количестве включаемых с помощью include файлов. С require таких проблем нет, поскольку файлы с помощью require включаются до выполнения сценария, то есть на момент трансляции файл уже включён в сценарий.
Таким образом, целесообразнее использовать конструкцию require там, где не требуется динамическое включение файлов в сценарий, а конструкцию include использовать только с целью динамического включения файлов в код PHP скрипта.
Конструкция include поддерживает включения удалённых файлов (начиная с версии PHP 4.3.0). Например:
<?php
// Следующий пример не работает, поскольку пытается включить локальный файл
include 'file.php?foo=1&bar=2';
// Следующий пример работает
include 'http://www.example.com/file.php?foo=1&bar=2';
?>
Конструкция include позволяет включать удалённые файлы, если такая возможность включена в конфигурационном файле PHP.
В больших PHP сценариях инструкции require и include применяются очень часто. Поэтому становится довольно сложно контролировать, как бы случайно не включить один и тот же файл несколько раз, что чаще всего приводит к ошибке, которую сложно обнаружить.
В PHP предусмотрено решение данной проблемы. Используя конструкции однократного включения require_once и include_once, можно быть уверенным, что один файл не будет включен дважды. Работают конструкции однократного включения require_once и include_once так же, как и require и include соответственно. Разница в их работе лишь в том, что перед включением файла интерпрететор проверяет, включён ли указанный файл ранее или нет. Если да, то файл не будет включён вновь.
Конструкции однократных включений также require_once и include_ince также позволяют включать удалённые файлы, если такая возможность включена в конфигурационном файле PHP.
PHP позволяет работать с объектами URL, как с обычными файлами. Упаковщики, доступные по умолчанию, служат для работы с удалёнными файлами с использованием протокола ftp или http.
Если "URL fopen-оболочки" включены в PHP (как в конфигурации по умолчанию), можно специфицировать файл, подключаемый с использованием URL (через HTTP), вместо локального пути. Если целевой сервер интерпретирует целевой файл как PHP-код, переменные могут передаваться в подключаемый файл с использованием URL-строки запроса, как в HTTP GET. Строго говоря, это не то же самое, что подключение файла и наследование им области видимости переменных родительского файла; ведь скрипт работает на удалённом сервере, а результат затем подключается в локальный скрипт.
Для того, чтобы удалённое включение файлов было доступно, необходимо в конфигурационном файле (php.ini) установить allow_url_fopen=1.
PHP предлагает альтернативный синтаксис для некоторых его управляющих структур, а именно: if, while, for, foreach и switch. В каждом случае основной формой альтернативного синтаксиса является изменение открывающей фигурной скобки на двоеточие (:), а закрывающей скобки на endif;, endwhile;, endfor;, endforeach; или endswitch; соответственно:
<?php if ($a == 5): ?>
a равно 5
<?php endif; ?>
В приведённом выше примере, блок HTML "a равно 5" вложен внутрь структуры if, написанной с альтернативным синтаксисом. Блок HTML будет показан только если переменная $a равна 5.
Альтернативный синтаксис также применяется и к else и elseif. Ниже приведена структура if с elseif и else в альтернативном формате:
<?php
if ($a == 5):
echo "a равно 5";
echo "...";
elseif ($a == 6):
echo "a равно 6";
echo "!!!";
else:
echo "a не равно ни 5 ни 6";
endif;
?>
Смешивание синтаксиса в одном и том же блоке управления не поддерживается.
Функция может принимать информацию в виде списка аргументов, который является списком разделённых запятыми выражений. Аргументы вычисляются слева направо.
PHP поддерживает передачу аргументов по значению (по умолчанию), передачу аргументов по ссылке, и значения по умолчанию. Списки аргументов переменной длины также поддерживаются, см. также описания функций func_num_args(), func_get_arg() и func_get_args() для более детальной информации.
Пример передача массива в функцию:
<?php
function takes_array($input)
{
echo "$input[0] + $input[1] = ", $input[0]+$input[1];
}
?>
HTML-формы (POST и GET)
Когда происходит отправка данных формы PHP-скрипту, информация из этой формы автоматически становится доступной ему. Существует несколько способов получения этой информации.
Пример простая HTML-форма:
<form action="foo.php" method="post">
Имя: <input type="text" name="username" /><br />
Email: <input type="text" name="email" /><br />
<input type="submit" name="submit" value="Отправь меня!" />
</form>
С версии PHP 5.4.0, есть только два способа получить доступ к данным из форм HTML.
Пример доступ к данным из простой HTML-формы, отправленной через POST:
<?php
echo $_POST['username'];
echo $_REQUEST['username'];
?>
GET-форма используется аналогично, за исключением того, что все переменные и их значения передаются прямо через адрес, например, https://www.php.net/manual/ru/language.variables.external.php.
Способ посылки параметров сценарию (когда данные помещаются в командную строку URL) называется методом GET.
Устанавливает соединение с Web-сервером по адресу сервер:порт и посылает ему что-то вроде следующего:
GET somestring HTTP/1.0\n
...другая информация...
\n\n
Здесь \n означает символ перевода строки, а \n\n - два обязательных символа новой строки, которые являются маркером окончания запроса (точнее, окончания заголовков запроса). Пока не пошлём этот маркер, сервер не будет обрабатывать запрос.
После GET-строки могут следовать и другие строки с информацией, разделённые символом перевода строки. Их обычно формирует браузер. Такие строки называются заголовками (headers), и их может быть сколько угодно. Протокол HTTP как раз и задаёт правила формирования и интерпретации этих заголовков. Он представляет собой ни что иное, как просто набор заголовков, которыми обмениваются сервер и браузер.
Не все заголовки обрабатываются сервером - некоторые просто пересылаются запускаемому сценарию с помощью переменных окружения.
Переменные окружения представляют собой именованные значения параметров, которые операционная система (точнее, процесс-родитель) передаёт запущенной программе. Программа может с помощью специальных функций получить значение любой установленной переменной окружения, указав её имя. Именно так и должен поступать CGI-сценарий, когда захочет узнать значение того или иного заголовка запроса.
PHP поддерживает загрузку файлов методом HTTP PUT, который используется в некоторых клиентах для загрузки файлов на сервер. Запросы PUT намного проще, чем загрузка файла с использованием POST-запросами и выглядят примерно так:
PUT /path/filename.html HTTP/1.1
Такой вызов означает, что удалённый клиент хотел бы сохранить файл под именем /path/filename.html в дереве каталогов веб-сервера.
Очевидно, что возможность клиента автоматически перезаписывать файлы веб-сервера при помощи Apache или PHP не является хорошим решением. Поэтому для того, чтобы обрабатывать такие запросы, необходимо указать веб-серверу PHP-скрипт, к которому есть доверие на их обработку. В веб-сервере Apache это можно сделать, используя директиву Script. Как правило, эта директива расположена внутри блока <Directory> или же внутри блока <VirtualHost>. Сама запись выглядит следующим образом:
Script PUT /put.php
Это указывает веб-серверу Apache на необходимость перенаправлять все PUT-запросы, контекст которых совпадает с контекстом, в котором разместили эту строку, в файл put.php. Предполагается, что файлы с расширением .php обрабатываются, как PHP-скрипты, и что сам PHP установлен и работает. Ресурсом назначения для всех PUT-запросов на этот скрипт должен быть сам скрипт, а не имя файла, которое должен иметь загружаемый файл.
Внутри файла put.php можно поместить что-нибудь похожее на следующий пример. Он скопирует содержимое загруженного файла в файл myputfile.ext на сервер. Возможно, понадобится осуществить несколько проверок и/или аутентифицировать пользователя перед выполнением копирования этого файла.
Пример сохранение файлов, отправленных через HTTP PUT:
<?php
/* PUT данные приходят в потоке ввода stdin */
$putdata = fopen("php://input", "r");
/* Открываем файл на запись */
$fp = fopen("myputfile.ext", "w");
/* Читаем 1 KB данных за один раз и пишем в файл */
while ($data = fread($putdata, 1024))
fwrite($fp, $data);
/* Закрываем потоки */
fclose($fp);
fclose($putdata);
?>
Непосредственно перед запуском сценария сервер передаёт ему некие переменные окружения с информацией. В определённых переменных содержатся некоторые заголовки, но, не все (получить все заголовки нельзя). Переменные окружения в языке PHP можно использовать как самые обыкновенные переменные.
Переменные окружения делятся на четыре большие группы:
Формируемые сервером переменные;
Специальные переменные сервера Apache;
Переменные HTTP-полей запроса;
Переменные SSL-соединения (защищённого соединения).
Заголовки HTTP используются для "общения" браузера и web-сервера, например, когда браузер запрашивает какой-либо документ, он посылает заголовок GET, а когда сервер возвращает тип документа, то он делает это ни как-нибудь, а в заголовке Content-type.
В PHP есть встроенные функции для работы с заголовками HTTP.
Для передачи заголовков HTTP предназначена функция header():
<?php
header("Content-type: text/plain");
?>
Всего определено 5 категорий кодов ответа HTTP. Каждая из этих категорий может содержать 100 кодов возврата.
Коды диапазона 100...199 являются информационными. С их помощью возвращается различная информация, относящаяся к запросу.
Диапазон 200...299 является диапазоном успешных операций. Коды, относящиеся к этому диапазону, сообщают об удачном завершении той или иной операции. К этому диапазону относятся также коды, сообщающие, что запрашиваемый файл пуст (no content), и сообщающие, что запрос был принят.
Диапазон кодов ответа 300...399 являются кодами перенаправления (redirect).
Коды диапазона 400...499 являются ошибками клиента. Например, пользователь может запросить несуществующий документ. К этому же диапазону относятся и ошибки "Forbidden" и "Unauthorized". И первая, и вторая сообщают, что у клиента нет доступа к определённому ресурсу. В первом случае доступ просто запрещён, а во втором случае клиент не является авторизированным.
Коды ответа 500...599 являются кодами ошибок сервера. Данные ошибки возникают при внутренней ошибке сервера или же при неправильном его конфигурировании. Во втором случае сервер просто не может правильно возвратить ответ на запрос. Этот тип ошибок встречается обычно, когда ошибку совершает сценарий (скрипт), расположенный на сервере.
Николай: Люди тратили уйму своего времени и труда, чтобы создать этот софт и дарят его Вам. Найдите, пожалуйста, немного времени, чтобы прочитать документацию и научиться это использовать!
Николай: Не понравился сайт, хотите научить меня администрировать? Пожалуйста, с удовольствием буду учиться. Отзывы в Вашем распоряжении!
Николай: Я знаю, у Вас уйма вопросов! На многие из них можете получить ответы прямо сейчас.