Основы программирования на языке PHP
1. Особенности серверного программирования на языке PHP
Язык PHP был разработан в 1994–1995 годах Расмусом Лэрдорфом, датским программистом. Изначально это был набор скриптов (сценариев) на языке программирования Perl под названием «PHP – Tools for Personal Home Page», который собирал статистику посещения веб-страницы. На сегодняшний день большинство страниц в сети Интернет снабжены подобными счетчиками.
Скрипт имел открытый исходный код и в целом простую и понятную идею, которая понравилась другим разработчикам. Вскоре скрипты были переписаны на языке Си и были названы «Personal Homepages Tools». Новая реализация языка уже могла взаимодействовать с базами данных и с помощью него можно было создавать простые динамические веб-страницы, что послужило еще одним стимулом к развитию Интернета.
Надо отметить, что язык разметки гипертекста HTML, с помощью которого создаются веб-страницы, требует знания основных тегов, кропотливости в формировании веб-страницы. В середине 90-х годов прошлого века веб страницы в Интернете создавались программистами и большинство пользователей, если и имело доступ к сети, могли лишь просматривать страницы.
Ценность идеи Р. Лэрдорфа состоит в том, что он создал достаточно простой инструмент для разработчиков, с помощью которого можно было создавать динамические веб-страницы, содержимое которых хранится в базе данных, а задачей PHP является извлечение этой информации из базы данных, обрамление тегами HTML для разметки веб-страницы. Таким образом, с помощью PHP можно было разработать удобный интерфейс для обычных людей, не знакомых с программированием, но владеющими пользовательскими навыками, чтобы уже пользователи могли формировать контент веб-страниц. Делалось это с помощью привычных нам полей форм: простое текстовое поле, многострочное поле, поле для ввода пароля, чекбоксы и др. Очень быстро PHP набирал популярность среди разработчиков в силу своей простоты, Си-ориентированного синтаксиса, все возрастающей поддержки многочисленных баз данных.
Создание языка PHP, при всех его несовершенствах, послужило взрывному развитию Интернета, достаточно сказать, что Facebook был написан на PHP и до сих пор содержит определенный функционал на PHP, хотя часть его выполняется на боле быстром C++.
Панель редактирования Wikipedia реализована на PHP, а всем известно, что это универсальная интернет-энциклопедия, где может любой человек опубликовать свой контент, даже если он не знаком с программированием. Это лишь малая часть примеров. На PHP написано множество систем управления контентом: WordPress, Joomla, 1C Bitrix, Moodle, NetCat, Drupal и др., а с их помощью уже создаются современные сайты, порталы, информационные системы не только программистами, но и обычными пользователями. Такая система управления контентом, как WordPress, является одним из лидеров платформ для разработки сайтов во всем мире. Многие сайты образовательных учреждений реализованы с помощью богатого функционала всевозможных плагинов WordPress.
Среди всех языков программирования PHP уверенно входит в первую десятку, а среди языков веб-программирования является безусловным лидером. Поэтому этот простой и сравнительно легкий в освоении язык программирования может стать хорошим началом для тех, кто собирается разобраться в веб-технологиях и разработать свой веб-ресурс.
РНР – скриптовый язык, который непосредственно встраивается в HTML-код и выполняется сервером. Скриптовые языки (или языки сценариев) – это высокоуровневые языки, которые кратко описывают действия, выполняемые системой. По сути сценарий – это тоже программа, но чаще всего сценарии интерпретируются, а не компилируются. Это означает чуть более медленную работу программы, но обычный пользователь почти не почувствует разницы. Интерпретатор располагается на сервере и его задача –последовательно, команда за командой, считывать код сценария и, если в текущей инструкции нет ошибок, то выполнить код.
Чаще всего задачей интерпретатора будет сгенерировать определенный HTML-код и отправить его обратно клиенту (браузеру). Таким образом, вся вычислительная нагрузка при работе интерпретатора PHP выполняется на удаленном сервере, а на компьютер пользователя присылается HTML-код. Если в какой-то момент интерпретатор обнаружит ошибку в коде, то он может вывести часть HTML-кода до ошибки и прекратить свою работу, встретив ее. Таким образом, веб-разработчик может столкнуться с ситуацией, когда часть страницы построилась, а часть – нет, и в браузере появилось сообщение об ошибке. Компилируемые программы (C, C++, C#, Pascal, Java и др.) попросту не запустятся, если при компиляции обнаружена ошибка.
Основное отличие РНР от CGI-скриптов, написанных на других языках, типа Perl или C++, – это то, что в CGI-программах необходимо прописывать выводимый HTMLкод, а используя РНР, он встраивается в готовую HTML-страницу при помощи открывающего и закрывающего тегов
<? … ?>
или <?php … ?>
Отличие РНР от JavaScript состоит в том, что PHP-скрипт выполняется на сервере, а клиенту передается результат работы, тогда как JavaScript-код полностью передается на клиентскую машину (в браузер) и только там выполняется.
В РНР включена поддержка многих баз данных, что делает написание вебприложений с использованием БД достаточно простым: MySQL, Adabas D, InterBase, Solid, dBase, mSQL, Sybase, PostgreSQL, Empress, Velocis, File Pro, Oracle, Unixdbm, Informix.
CGI (Common Gateway Interface – общий интерфейс шлюзов) является стандартом, который предназначен для создания серверных приложений, работающих по протоколу HTTP. Такие приложения (их называют шлюзами или CGI-программами) запускаются сервером в режиме реального времени.
Сервер передает запросы пользователя CGI-программе, которая их обрабатывает и возвращает результат своей работы на экран пользователя. Таким образом, посетитель получает динамическую информацию, которая может изменяться в результате влияния различных факторов. Сам шлюз (скрипт CGI) может быть написан на различных языках программирования – Cи/C++, Fortran, Perl, TCL, UNIX Shell, Visual Basic, Python и др.
При обращении пользователя к статической странице на сервере происходит следующее (рисунок 1): браузер посылает на сервер запрос на получение содержимого файла, например news.html. При этом на сервере в файловой системе действительно существует файл news.html, и сервер попросту отправляет содержимое этого файла назад браузеру.
Рис. 1. Взаимодействие между сервером и клиентом. Обработка запроса
При обращении же к динамической PHP-странице, например program.php, происходит другой порядок действий. В физическом смысле program.php содержит код программы, которая формирует динамический HTML-код. Это значит, что при определенных обстоятельствах этот код будет генерировать разные веб-страницы. Например, program.php может извлекать из базы данных все статьи и сортировать их определенным образом. А базу данных со статьями могут постепенно изменять. Таким образом динамическая страница в физическом смысле не содержится на сервере (в отличие от статичной), а генерируется PHP-программой (рисунок 2).
Рис. 2. Взаимодействие между сервером и клиентом. Обращение пользователя к php-программе
Сервер находит запрашиваемую PHP-программу, организует ее выполнение (с помощью интерпретатора php.exe). После того как программа выполнена, получается обычный статичный HTML-файл, в котором можно увидеть только результат.
Сервер возвращает браузеру результат работы PHP-программы, причем пользователь видит его как обычный HTML-код и даже не подозревает, что это была программа.
Все ошибки в РНР выдаются в окно браузера по умолчанию (чего нельзя сказать о CGI, где все ошибки записываются в лог-файл), и найти их при внимательном поиске и определенном опыте не составит труда. Тем более, что интерпретатор подскажет номер строки, в которой произошла ошибка.
При написании программы на РНР необходимо пользоваться разделением инструкций – в РНР инструкции разделяются так же, как в C или Pascal, − точкой с запятой.
Необходимо заметить, что закрывающий тег ?> также подразумевает завершение инструкции, другими словами, если после инструкции следует закрывающий тег ?>, то можно не использовать точку с запятой в конце инструкции. Например,
<?php
echo( "Welcome to PHP");
?>
То же самое, что и
<?php echo ("welcome to PHP") ?>
Для разработки веб-проекта на языке PHP понадобится особое программное обеспечение. Во-первых, веб-разработчик должен иметь на компьютере надежный и удобный браузер для отображения страниц. Наиболее популярными, быстрыми и удобными для разработчиков являются браузеры Google Chrome, Яндекс.Браузер, Opera, Edge и др. Иногда полезно иметь несколько установленных на компьютере браузеров, так как порой приходится тестировать верстку сайта, которая может поразному отрисовываться в браузерах.
Для того чтобы программа на PHP была выполнена, необходим интерпретатор PHP, который работает на веб-сервере. Веб-сервер – это программа, которая способна воспринимать HTTP запросы от клиента (браузера) и отдавать обратно HTTP ответы (с HTML-кодом, изображениями, файлами и др. контентом). Самыми доступными вебсерверами являются бесплатный Apache и входящий в состав операционной системы
Windows веб-сервер IIS (Internet Information Server). В данном курсе будет использоваться веб-сервер Apache в силу распространенности, простой настройки и свободного распространения.
При работе с базами данных также понадобится сервер баз данных. В нашем случае работа будет осуществляться с использованием системы управления базами данных MySQL, поэтому именно сервер MySQL нам также понадобится для работы. Обычно для одного веб-проекта создается одна база данных, которая хранится на удаленном сервере, и пользователи со своих устройств могут получать доступ к этой базе данных через сайт, через интерфейс сайта формировать запросы к этой базе данных. Создание и изменение баз данных выполняется с помощью графической утилиты phpMyAdmin, которая является частью веб-сервера.
Все вышеперечисленные компоненты для разработки сайта – веб-сервер Apache, MySQL, интерпретатор PHP – входят в набор дистрибутивов, который обозначается аббревиатурой LAMP (L – Linux, A – Apache, M – MySQL, P – PHP). Набор указанных дистрибутивов входит в популярный набор Denwer Дмитрия Котерова. Для наших занятий мы будем использовать Denwer.
Для быстрого написания кода можно использовать текстовый редактор, такой как Notepad++, Atom, Sublime Text 3 и др. При выборе текстового редактора для написания кода следует обратить внимание на подсветку синтаксиса, выделение ошибок, работу с множеством файлов, быстрое перекодирование страниц в различные кодировки и др. В наших лабораторных работах будет использоваться Notepad++.
Далее, опишем процедуру развертывания веб-сервера Apache на операционную систему Windows 10.
Также необходимо позаботиться о наличии свободного места на жестком диске для работы сервера (300-500 Мб).
Для начала работы с PHP требуется сделать следующее.
1. Скачать уже установленный пакет Denwer и распаковать архив на Рабочий стол. Если вы действуете самостоятельно, то можно выполнить установку Denwer по инструкции с сайта http://www. denwer. ru или скачать и установить OpenServer. Все работы проводятся на уже установленной сборке Denwer.
2. Выполнить запуск сервера. Для этого в папке WebServers (у вас может быть немного другое название) в папке denwer найдите три .exe файла: Run.exe, Stop.exe, Restart.exe (рисунок 3). Как нетрудно догадаться, с их помощью происходит запуск сервера, остановка и перезапуск. Для запуска сервера нужно запустить программу Run.exe.
Рис. 3. Запуск, остановка и перезапуск сервера
При этом иногда операционная система может запросить у вас логин и пароль администратора для изменения файла hosts, но в этом случает не нужно вводить никакого пароля. Появится некритическая ошибка, но она не повлияет на дальнейшую работу.
Если вы все сделали правильно, то в области рядом с часами на своем компьютере увидите ярлыки (рисунок 4).
Рис. 4. Запуск, остановка и перезапуск сервера
3. Далее необходимо создать папку, где будут храниться все файлы сайта. Для этого в папке WebServers/home/localhost/www создайте папку, например program (следует обратить внимание, что все имена папок, файлов при веб-разработке следует именовать строчными буквами, без пробелов на латиннице), рисунок 5.
Рис. 5. Запуск, остановка и перезапуск сервера
4. В папке program создаются и располагаются файлы сайта и различные ресурсы (изображения, файлы стилей и др.). Традиционно стартовый файл сайта называют index.php, и он веб-сервером Apache воспринимается стартовым по умолчанию. Это значит, что дополнительно в адресной строке прописывать название файла не нужно. Создадим файл index.php с помощью Notepad++ со следующим кодом
<?php echo "Это мой первая страница!"?>
При работе с кириллицей требуется смена кодировки файла. Сделать это можно в Notepad++ с помощью пункта меню Кодировки/Преобразовать в ANSI (или Encoding / Convert to ANSI).
5. После этого можно запустить браузер и ввести адрес http://localhost/program. Здесь уже не нужно указывать папку www и файл index.php (см. рисунок 6).
Рис. 6. Запуск, остановка и перезапуск сервера
Мы рассмотрели особенности языка веб-программирования PHP, необходимое для веб-разработки программное обеспечение, а также последовательность запуска веб-сервера и создание простейшей страницы.
Также, следует обратиться к официальной документации по PHP на русском языке https://www.php.net/manual/ru/ при появлении вопросов по неописанным в этом учебном пособии функциям, операторам и синтаксису.
2. Синтаксис языка PHP
В РНР, впрочем, как и в С и PASCAL, допустимы две разновидности комментариев. Комментарии традиционного стиля начинаются знаком /* и заканчиваются знаком */.
Например,
/* это комментарий в одну строку*/
/* этот комментарий занимает несколько строк*/
// этот комментарий занимает
// несколько строк
В качестве разделителя инструкций в PHP, как и во многих других языках программирования, используется точка с запятой «;».
В PHP определены следующие типы данных:
- Integer – целое,
- double – число с дробной частью,
- string – строковая переменная,
- array – массив,
- object – объектная переменная,
- boolean – булев (логический).
Особенностью синтаксиса РНР является то, что все переменные имеют имя, которые начинаются со знака $, например, $value = 5. При этом переменную очень легко отличить от остального кода. Однозначная идентификация переменной позволила создателям РНР дать возможность программистам использовать переменные непосредственно внутри строк. При этом явно указывать тип переменной в PHP не нужно. Интерпретатор самостоятельно определяет тип переменной в зависимости от содержимого.
Примеры определения различных переменных на PHP:
$str = 'строка';
$str2 = "Это тоже строка";
$number = 3;
$pi = 3.1415926;
В РНР различаются строки, заключенные в одинарные и двойные кавычки. Подобное замещение имен в переменных их значениями производится только в строках, заключенных в двойные кавычки. Это очень важно помнить, дабы избежать ошибок в будущем.
$name = 'Maria';
$age = 20;
echo "$name is $age years old";
Переменная характеризуется именем, типом и значением. Имя переменной может быть любым и включать в себя цифры, буквы английского алфавита, а также разрешенные символы (например, символ подчеркивания или тире).
Необходимо заметить, что имя переменной чувствительно к регистру.
$first = 'Sasha';
$First = 'Tatiana';
echo "$first, $First"; // данная функция выведет
//на экран "Sasha, Tatiana"
Некоторые символы при написании кода на PHP являются служебными. Если нужно использовать определенный символ с его особым значением, то необходимо экранировать данный символ. Так, например, часто приходится внутри строки, обрамленной кавычками, использовать еще кавычки. В этом случае PHP будет выдавать ошибку. Например, при выводе строки
<?php echo "Это "строка" в кавычках";?>
получим ошибку. Чтобы правильно вывести такую строку, нужно перед внутренними кавычками поставить знак обратного слеша «\»:
<?php echo "Это \"строка\" в кавычках";?>
В таблице 1 представлены другие символы, которые нужно выводить с обратным слешем, чтобы получить желаемый символ.
Таблица 1. Символы, кодируемые с использованием обратного слеша
Последовательность | Значение |
\n | Перевод строки (LF или ОхОА в кодировке ASCII) |
\r | Возврат каретки (CR или OxOD в кодировке ASCII) |
\\t | Горизонтальная табуляция (НТ или 0x09 в кодировке ASCII) |
\\ | Обратный слеш |
\$ | Знак доллара |
\» | Двойная кавычка |
\[0-7]{1,3} | Последовательность символов, соответствующая регулярному выражению, является символом в восьмеричной нотации |
\x[0-9A-Fa-f]{1,2} | Последовательность символов, соответствующая регулярному выражению, является символом в шестнадцатеричной нотации |
Рассмотрим вопросы преобразования строк. Если строка оценивается как числовое значение, то результирующие значение и тип будут определяться следующим образом. Строка оценивается как число двойной точности, если она содержит любой из символов «.», «е» или «Е». В противном случае она будет оценена как целое число. Далее значение определяется начальной частью строки.
Если строка начинается с допустимых числовых данных, они будут использоваться в качестве значения. В противном случае значение будет равно нулю. Экспонента – это «е» или «E», за которой следуют одна или несколько цифр. Если первое выражение является строкой, тип переменной зависит от второго выражения.
Пример преобразования строк:
$x = 1 + "10.5"; //$x имеет двойную точность (11.5)
$x = 1 + "-1.3e3"; //$x имеет двойную точность (- 1299)
$x = 1 + "bob-1.3e3"; // $x целое (1)
$x = 1 + "bob3"; // $x целое (1)
$x = 1 + "10 Small Pigs";// $x целое (11)
$x = 1 + "10 Little Piggies"; // $x целое (11)
$x = "10.0 pigs " + 1; // $x целое (11)
$x = "10.0 pigs " + 1.0; // $x имеет двойную точность (11)
При работе со строками часто приходится выполнять операцию слияния строк или конкатенацию. В PHP эта операция обозначается символом точки «.». Приведем пример различных использований конкатенации.
<?php
//определение строки
$str = "Это строка";
//добавление к ней другой строки
$str = $str . " с дополнительным текстом";
//еще один короткий способ добавления строки к строке
$str .= " и перевод строки в конце. \n";
//эта строка закончится текстом '<p>Число 3</p>'
$number = 3;
$str = "<p>Число $number</p>";
//эта строка закончится текстом '<p>Число
$number</p>'
$number = 5;
$str = '<p>Число $number</p>';
$str = "Программирование";
//получение первого символа 'П'
$first = $str[0];
//получение последнего символа 'е'
$last = $str[strlen($str)-1];
?>
Строки являются упорядоченными последовательностями символов, поэтому к каждому символу строки можно обратиться по его порядковому номеру. В PHP нумерация строк начинается с 0. Чтобы вычислить всю длину строки $str (количество символов в строке), используется функция strlen($str).
Массивы – один из важных структурных типов данных в php. Они широко применяются при взаимодействиях с базами данных. По своей сути массив – это ряд переменных, упорядоченных по имени и имеющих различный индекс (ключ).
$m[0] = "компьютер";
$m[1] = "Интернет";
$m[2] = "модем";
$m[3] = "монитор";
$i = 0;
while ($i < count($m)) { echo $m[$i]."<br>";
$i++;
}
Различают одномерные массивы и многомерные массивы. Одномерный массив состоит из одной строки.
РНР поддерживает как скалярные (в качестве ключей используются порядковые номера 0, 1, 2…), так и ассоциативные массивы (в качестве ключей используется строка «а», «Ь», «с»…). Между ними, практически, нет никакой разницы.
Создать массив можно с помощью функций array() или просто определить значения элементов массива. С помощью функции print_r можно вывести весь массив целиком.
<?php
$m = array();
$m[] = 1;
$m[] = 2;
$m[4] = 4;
print_r($m);
?>
Код, указанный выше, можно написать более компактно, например, так:
<?php
$m = array(0=>1,1=>2,4=>4);
print_r($m);
?>
Для работы с массивами служит специальный цикл foreach, который мы рассмотрим ниже. Заранее можно сказать, что с помощью массива foreach можно обратиться последовательно к каждому элементу массива и его ключу и произвести с ними какие-то действия.
Если использовать ассоциативные массивы, то в качестве ключа будет выступать строка, как, например, здесь, массив $fruit хранит информацию о фрукте яблоке (его цвет, вкус, форма, название и числовая характеристика).
$fruit["color"] = "red";
$fruit["taste"] = "sweet";
$fruit["shape"] = "round";
$fruit["name"] = "apple";
$fruit[3] = 4;
Или можно так:
$fruit = array( "color" => "red", "taste" => "sweet", "shape" => "round", "name" => "apple", 3 => 4
) ;
Многомерный массив – это массив, каждый элемент которого в свою очередь тоже является массивом. В данном примере в массиве $fruit описаны три фрукта и выведен вкус апельсина. Какой он?
<?php
$fruit = array(
"apple"=>array(
"color"=>"red", "taste"=>"sweet",
"shape"=>"round"),
"orange"=>array(
"color"=>"red", "taste"=>"tart",
"shape"=>"round"),
"banana"=>array(
"color"=>"yellow", "taste"=>"pasty", "shape"=>"banana-shaped" )
);
echo $fruit["orange"]["taste"];
?>
В любом языке программирования, в том числе и в PHP, используются операции для записи некоторых действий. Например, из математики широко известны арифметические операции – сумма, разность, умножение, деление. Сюда можно отнести также нахождение целой части и остатка от деления двух чисел. Таким образом, операции являются частью синтаксических конструкций, которые позволяют сделать определенные действия с переменными.
Унарные операции, или одноместные операции, подразумевают, что число операндов (переменных), над которыми операция производит свое действие, равно единице. К ним относятся операция присваивания (=), инкремент (++), декремент (—) и др.
$number = 5;
$number++; // то же, что $number = $number +1 или
//$number += 1
--$number; // то же, что $number = $number -1 или
//$number -= 1
Префиксный инкремент увеличивает $a на единицу, затем возвращает значение $a. Запись ++$a.
Постфиксный инкремент возвращает значение $a, затем увеличивает $a на единицу. Запись $a++.
Префиксный декремент уменьшает $a на единицу, затем возвращает значение $a. Запись —$a.
Постфиксный декремент возвращает значение $a, затем уменьшает $a на единицу. Запись $a—.
Рассмотрим на примере как работают инкременты и декременты в различных ситуациях.
<?php
echo "<h3>Постфиксный инкремент</h3>";
$a = 5;
echo "Должно быть 5: " . $a++ . "<br />\n"; echo "Должно быть 6: " . $a . "<br />\n"; echo "<h3>Префиксный инкремент</h3>";
$a = 5;
echo "Должно быть 6: " . ++$a . "<br />\n"; echo "Должно быть 6: " . $a . "<br />\n"; echo "<h3>Постфиксный декремент</h3>";
$a = 5;
echo "Должно быть 5: " . $a-- . "<br />\n"; echo "Должно быть 4: " . $a . "<br />\n"; echo "<h3>Префиксный декремент</h3>";
$a = 5;
echo "Должно быть 4: " . --$a . "<br />\n"; echo "Должно быть 4: " . $a . "<br />\n";
?>
К унарным операциям можно отнести и логическую операцию «отрицание», которая обозначается символом восклицательного знака «!». Например, с помощью оператора var_dump можно посмотреть тип и значение логической переменной (нетрудно догадаться, что ее значение будет false):
<?php
$a = true; var_dump(!$a);
?>
Бинарные операции, или «двухместные», означают, что операции этого рода производят свои действия над двумя операндами. Наиболее часто употребляемые двухместные операции – это +, -, / и *. Также к двуместным операциям можно отнести логические операции (равно, не равно, меньше или равно, меньше, больше или равно, больше, логические И, логическое ИЛИ и др.).
В таблице 2 представлены бинарные операции.
Таблица 2. Основные бинарные операции в PHP
Обозначение | Название | Синтаксис |
* | Умножение | выражение * выражение |
+ | Сложение | выражение + выражение |
– | Вычитание | выражение – выражение |
/ | Деление | выражение / выражение |
% | Модуль (остаток деления) | выражение % выражение |
== | Равно | выражение == выражение |
!= | Не равно | выражение != выражение |
=== | Идентично | выражение === выражение |
!== | Не идентично | выражение !== выражение |
> | Больше | выражение > выражение |
>= | Больше или равно | выражение >= выражение |
< | Меньше | выражение < выражение |
< | Меньше или равно | выражение <= выражение |
|| | Логическое Или | выражение ||выражение |
&& | Логическое И | выражение && выражение |
Кроме обычного сравнения ==, есть сравнение тождественности ===, возвращающее true, если операнды равны по значению и имеют один тип.
Сравнение тождественности «не равно по типу и значению» записывается как !==, в отличие от обычного отношения неравенства, которое обозначается != или <>.
При разработке веб-сайта часто приходится вставлять код одного файла в другой. Например, вы сделали файл, который выводит меню или подключается к базе данных. Теперь точно такой же код должен находиться на всех страницах вашего сайта. Если в процессе работы разработчику необходимо внести в код какие-либо изменения (добавить новый пункт в меню или изменить данные для подключения к базе), то править этот код во множестве файлов представлялось бы рутинной и неэффективной задачей. Операторы включения кода позволяют создавать один исходный файл и затем подключать его к каким нужно файлам.
Рассмотрим их. Оператор include позволяет включать код, содержащийся в указанном файле, и выполнять его столько раз, сколько программа встречает этот оператор. Включение может производиться любым из перечисленных способов:
include 'имя_файла'; include $file_name; include ("имя_файла");
Пусть имеется файл data.php, которые содержит некоторые сведения
<?php
$users = array("Иванов И.И.", "Сидоров В.А.", "Ерофеева М.Ю.");
$events = array("Конференция по информационным технологиям", "Семинар по математике", "Мастер-класс по искусственному интеллекту");
?>
Файл data.php подключается к файлу index.php
<?php
include ("data.php");
echo "Здравствуйте, $users[1]!<br>";
// выведет "Здравствуйте, Иванов И.И.!"
echo "Вы приглашены на мероприятие \"$events[2]\"";
// выведет, например, "Вы приглашены на мероприятие "Семинар по математике""
?>
Использование оператора include эквивалентно простой вставке содержательной части файла data.php в код программы index.php. Может быть, тогда можно было в data.php записать простой текст без всяких тегов, указывающих на то, что это php-код? Нельзя! Дело в том, что в момент вставки файла происходит переключение из режима обработки PHP в режим HTML. Поэтому код внутри включаемого файла, который нужно обработать как PHP-скрипт, должен быть заключен в соответствующие теги.
Функция include_once работает идентично выражению include, с той лишь разницей, что если код из файла уже один раз был включён, он не будет включён и выполнен повторно и вернёт true. Как видно из имени, он включит файл только один раз.
Функция require также позволяет включать в программу и исполнять какой-либо файл. Основное отличие require и include заключается в том, как они реагируют на возникновение ошибки: include выдает предупреждение, и работа скрипта продолжается. Ошибка в require вызывает фатальную ошибку работы скрипта и прекращает его выполнение.
Функция require_once обеспечит добавление кода к сценарию только один раз и поможет избежать столкновений со значениями переменных или именами функций.
Может возникнуть резонный вопрос: в каких случаях использовать ту или иную функцию, если все они включат исходный код. Наиболее строго функцией является require – если вы сделали ошибку, то на странице не будет выведено ничего. Это лучший вариант в том случае, если сайт размещен в сети Интернет – так злоумышленники не увидят сообщение об ошибке, что может дать дополнительную информацию к взлому сайта. Но если вы ведете разработку на локальном хостинге и вам нужно понимать, где вы совершили ошибку, то include или include_once будет предпочтительнее в этом случае. Include_once и require_once используются в тех случаях, если подключаемые файлы содержат определения функций. В этих случаях функция будет описана только один раз и это не приведет к ошибке повторного описания функций.
Представленные функции повышают удобство сопровождения сайта и улучшают его масштабируемость, т.к. позволяют менять код всего лишь одного файла, а остальные страницы сайта автоматически подтягивают его из исходного.
3. Алгоритмические конструкции в PHP
Алгоритмы состоят из трех базовых алгоритмических конструкций – следований, ветвлений и циклов. Следование – это последовательное выполнение инструкций в программе, где каждая отделена от другой точкой с запятой. В некоторых приведенных выше примерах были представлены последовательные алгоритмы.
В тех случаях, когда программа должна выполнять те или иные действия в зависимости от логических условий, значений переменных, результатов выполнения функций, используется алгоритмическая конструкция ветвление. В PHP к условным операторам относят оператор if и оператор switch. Рассмотрим их работу.
Оператор if делится на две формы – неполная и полная. Неполная форма условного оператора на PHP выглядит следующим образом:
If (условие) {
Оператор_1;
Оператор_2;
… Оператор_N;
}
Оператор if (если) проверяет выполнимость условия (в результате должно получиться либо логическое true – истина, либо логическое false – ложь). В случае, если условие имеет значение true, выполняются действия операторов 1…n. Если же условие имеет значение false, то программа переходит к выполнению оператора, следующего за оператором if.
Полная форма условного оператора выглядит следующим образом:
If (условие) {
Оператор_ветви_Если_то_1; Оператор_ветви_Если_то_2;
… Оператор_ветви_Если_то_N;
}
else
{
}
Оператор_ветви_Если_Иначе_1; Оператор_ветви_Если_Иначе_2;
… Оператор_ветви_Если_Иначе_N;
Оператор if (если) проверяет выполнимость условия (в результате должно получиться либо логическое true – истина, либо логическое false – ложь). В случае, если условие имеет значение true, выполняются действия операторов_ветви_Если_то 1…n. Если же условие имеет значение false, то выполняются действия операторов_ветви_если_иначе 1…n.
Существует альтернативный синтаксис условного оператора, который удобен в том случае, если в программном коде предполагается несколько вложенных управляющих конструкций (чтобы разработчику не пришлось путаться в закрывающихся скобках множества вложенных конструкций):
If (условие):
Оператор_1;
Оператор_2;
… Оператор_N; Endif;
Здесь основной формой альтернативного синтаксиса является изменение открывающей фигурной скобки на двоеточие (:), а закрывающей скобки на Endif.
В качестве условия в алгоритмической конструкции if выступает логическое выражение, которое может состоять из логических операций и операций сравнения. К логическим операциям относят логическое И (&&), логическое ИЛИ (||), логическое НЕ (!) (таблица 2). К операциям сравнения относят восемь операций: равно, не равно, больше, больше или равно, меньше, меньше или равно, идентично, не идентично (таблица 2).
Если в алгоритме разработчику нужна альтернатива из более чем двух вариантов, то целесообразнее применить алгоритмическую конструкцию «оператор варианта» switch (переключатель). Его синтаксис:
switch (выражение или переменная) {
case значение1: блок_действий1 break; case значение2: блок_действий2 break; ... default: блок_действий_по_умолчанию
}
Switch проверяет значение переменной или выражения, сопоставляет вычисленное значение с одним из вариантов case. Если вариант выбора найден, то выполняется соответствующий блок действий. Если не найден вариант, то выполняется ветка default (по умолчанию). Иногда ветка default может отсутствовать, тогда при отсутствии нужного варианта управление переходит на оператор, следующий после switch.
Третий вид алгоритмических конструкций – циклические операторы – предназначены для программирования повторяющихся действий. Общая структура всех циклов предполагает действия, которые будут выполняться n-ое количество раз и условие прекращения цикла. Важно обязательно продумывать логическое условие и способ его выполнения и невыполнения, чтобы это не приводило к зацикливанию. В PHP используется четыре вида циклов. Рассмотрим их синтаксис и возможности использования.
Цикл с предусловием while предполагает сначала проверку условия. В случае если условие истинно, происходит выполнение действий в цикле.
while (выражение)
{
блок_выполнения
}
Альтернативный синтаксис цикла с предусловием
while (выражение): блок_выполнения
endwhile;
Пример работы цикла с предусловием
<?
//эта программа напечатает все четные цифры
$i = 1;
while ($i < 10) {
if ($i % 2 == 0) print $i;
// печатаем цифру, если она четная
$i++; // и увеличиваем $i на единицу
}
?>
Здесь в теле цикла включен оператор постфиксного инкремента $i++, который увеличивает переменную $i на единицу, что приводит к изменению условия, и тем самым рано или поздно цикл завершит свою работу.
Цикл с постусловием применяется, если гарантированно требуется совершить хотя бы одно действие прежде, чем выполнится проверка условия. Синтаксис цикла с постусловием:
do
{
блок_выполнения
}
while (выражение);
Пример работы цикла с постусловием, который выводит подряд все цифры от 0 до 10:
<?
$num = 0;
Print "счетчик цикла do: "; do
print "$num"; while ($num++ <10);
?>
Если заранее известно сколько раз должен выполниться цикл, то целесообразнее применять цикл с параметром for. У него можно задать начальное значение, условие продолжения цикла и выражение для управления циклом (достижение условия выхода):
For (начальное_выражение; условие; выражение_управления_циклом)
{
блок_выполнения
}
В некоторых случаях можно опустить начальное значение, условие продолжения цикла и выражение для управления циклом. Их можно заменить дополнительными проверками внутри цикла. Этот механизм позволяет быть PHP очень гибким. Но если вы не привыкли к такому синтаксису или боитесь ошибиться, то применяете классическую запись.
Пример работы цикла с параметром, который выводит последовательно цифры от 1 до 10:
for ($i = 1; $i <= 10; $i++)
{
print $i;
}
Того же самого можно достичь при использовании проверки выполнения тела цикла не в заголовке, а в теле цикла:
for ($i = 1;;$i++){
if ($i > 10) { break;} print $i;
}
Цикл «для каждого» foreach применяется только к массивам и объектам. При работе с упорядоченными элементами важно обращаться как к самим значениям, так и к их ключам (индексам). Именно поэтому был разработан данный вид цикла:
Foreach (array_expression as $value) { блок_выполнения
}
Здесь в качестве array_expression выступает переменная, являющаяся или массивом, или объектом.
При обращении к ключам и значениям элементов используется полная форма цикла foreach:
Foreach (array_expression as $key => $value) { блок_выполнения
}
Рассмотрим пример работы цикла foreach, который выводит в первом случае только названия стран, а во втором – название страны и код, который она имеет.
<? $countries = array("RU"=>"Россия",
"CN"=>"Китай",
"FR"=>"Франция",
"DE"=>"Германия"); foreach ($countries as $country){
echo "Страна: ".$country."<br>";
}
foreach ($countries as $code => $country){
echo "Страна: ".$country." имеет код " . $code
."<br>";
}
?>
В PHP существуют два оператора, которые позволяют принудительно прервать действие цикла, не прибегая к проверке условия цикла – операторы break и continue.
Оператор break (разбить, прервать) прерывает исполнение ближайшего внешнего оператора while, do-while, for или switch. Управление передается следующему за прерванным оператору.
Break принимает необязательный числовой аргумент, который сообщает ему, выполнение какого количества вложенных структур необходимо прервать. Значение по умолчанию 1, только ближайшая структура будет прервана.
<?php
$arr = array('один', 'два', 'три', 'четыре', 'стоп', 'пять'); foreach ($arr as $val) {
if ($val == 'стоп') {
break; /* Тут можно было написать 'break 1;'. */
}
echo "$val<br />\n";
}
?>
Оператор continue (продолжай) прекращает текущую итерацию в ближайшем внешнем цикле while, do-while или for. Управление передается проверочному выражению циклов while и do-while или выражению управления циклом в цикле for. Continue принимает необязательный числовой аргумент, который указывает на скольких уровнях вложенных циклов будет пропущена оставшаяся часть итерации. Значением по умолчанию является 1, при которой пропускается оставшаяся часть текущего цикла.
В примере показана работа оператора continue – выводятся элементы массива, стоящие на нечетных местах – 6, 10, 15 (нумерация в массивах PHP начинается с 0).
<?php
$arr = array(5,6,8,10,12,15); foreach ($arr as $key => $value) {
if (!($key % 2)) { // пропуск чётных чисел continue;
}
print_r($value." ");
}
?>
4. Обработка данных форм
Мы уже касались вопроса о том, как языки программирования, в частности PHP, способствовали развитию Интернета и превращению его из статичного, передающего пользователю только ту информацию, которую содержат HTML-страницы, в Интернет динамический, где каждый пользователь, вне зависимости от навыков программирования, может создавать собственный контент: формировать заявку, писать и получать электронные письма, загружать в Интернет файлы и прочее. Передаче информации от пользователя к информационной системе предназначены HTML-формы. Все пользователи Интернета с ними сталкивались – это текстовые поля, поля для заполнения пароля, прикрепление файла, радиокнопки и многое другое.
Рассмотрим форму, показанную на рисунке 7.
Рис. 7. Пример формы регистрации участников
Через данную форму на удаленный сервер можно передать какие-то данные от пользователя, к примеру необходимые для регистрации участника. Данные с формы отправляются после нажатия на кнопку «Отправить». Если же нажать на кнопку «Отменить», то все данные полей очистятся.
Рассмотрим общее описание HTML-формы.
<form
name="имя формы"
action="путь к программе-обработчику формы" method="метод передачи данных">
Элементы формы или тело формы
</form>
Здесь name – имя формы. Часто бывает на одной странице размещено несколько форм (например, форма поиска, регистрации участников, форма обратной связи и т.д.). Поэтому каждая форма должна иметь уникальное имя, чтобы скрипты могли получать данные к ее элементам.
Action – атрибут, указывающий URL к программе, которая будет обрабатывать данные с формы (например, записывать в базу данных, отправлять почтовое сообщение, что-то подсчитывать и др.).
Method – метод передачи данных с формы. Используется один из двух методов: или GET или POST. Подробнее о методах передачи информации с форм и их отличиях мы поговорим в конце параграфа.
Можно использовать упрощенную запись формы:
<form>
Элементы формы или тело формы
</form>
В этом случае программа-обработчик будет являться тем же файлом, который содержит эту форму, метод передачи данных по умолчанию GET.
В тело формы добавляются различные поля. Большая часть из представленных далее полей содержит атрибут name (уникальное имя), type (тип поля), value (значение поля по умолчанию), title (всплывающая подсказка). Индивидуальные атрибуты для каждого поля подписаны.
Поле для текстового ввода (рисунок 8).
<input
type="text" name="имя элемента"
value="значение элемента" title="всплывающая подсказка" size="длина"
maxlength="максимальное количество элементов">
Рис. 8. Пример текстового поля
Поле для ввода пароля – основное отличие от текстового поля в том, что текст в поле заменяется на точки или звездочки.
<input
type="password" name="имя элемента" value="пароль"
title="всплывающая подсказка" size="длина"
maxlength="максимальное количество символов">
Кнопка используется для отправки данных с форму скрипту обработчику (рисунок 9).
<input
type="submit" name="имя элемента" value="текст кнопки"
title="всплывающая подсказка">
Рис. 9. Пример кнопки
Переключатель или Radiobutton (рисунок 10).
<input
type="radio" name="имя элемента" value="значение" [checked]>
Текст для переключателя
Данное поле содержит необязательный атрибут checked, который может сделать данное поле нажатым по умолчанию. Если используется группа радиопереключателей, то нужно им всем давать одинаковое имя (атрибут name), чтобы в группе переключателей пользователь мог выбрать только один.
Рис. 10. Пример радио переключателей
Флаг (checkbox) может находиться в одном из двух состояний: отмечен или не отмечен. В отличие от радиокнопки, где из группы может быть выбран только один вариант, в группе чек-боксов может быть выбрано сколько угодно вариантов или вообще ни одного (рисунок 11).
<input
type="checkbox" name="имя элемента" value="значение" [checked]>
Текст флага
Данное поле содержит необязательный атрибут checked, который может сделать данное поле нажатым по умолчанию. Если используется группа флажков, то нужно им всем давать одинаковое имя (атрибут name), чтобы в скрипт-обработчик все выбранные переключатели передавались как элементы массива.
Предположим, что мы хотим предоставить пользователю возможность выбрать курс обучения (рисунок 11).
Рис. 11. Пример группы флажков (чек-боксов)
Группа чек-боксов в этом случае выглядит следующим образом:
<input type="checkbox" name="courses[]" value="1">
PHP
<input type="checkbox" name="courses[]" value="2" checked>
MySQL
<input type="checkbox" name="courses[]" value="3">
JavaScript
Например, атрибут name=»courses[]» соберет все данные с флагов в массив courses[]. Обратите внимание на наличие квадратных скобок [ и ]. Без этих скобок переменная courses не будет хранить значения в виде массива и передаст только последний выбранный элемент.
Список элементов позволяет выбрать один или несколько элементов из группы элементов списка (рисунок 12). Общая форма записи элементов списка следующая:
<select size="количество видимых элементов" name="имя списка" [multiple]>
<option value="значение1" [selected]>Отображаемая строка 1</option>
…
<option value="значениеN" [selected]>Отображаемая строка N</option>
</select>
Поле select содержит необязательный атрибут multiple, который позволяет выбрать несколько элементов. Для передачи скрипту-обработчику нескольких значений списка нужно использовать атрибут name с квадратными скобками [ и ], как это было в случае с чек-боксами.
Каждый элемент списка обрамляется тегами <option>…</option>, у которых также может присутствовать необязательный атрибут selected. В этом случае элемент списка считается выбранным по умолчанию. Если таких элементов несколько, то выбранным в списке отображается последний из них. Необязательный атрибут size содержит количество видимых в списке элементов. Это удобно, когда список большой, пользователю удобнее ориентироваться, что предшествует данному элементу, какой следующий и т.д.
Далее на рисунке показаны различные виды списков (выпадающий с выбором одного элемента, открывающий части элементов с выбором только одного, открытый с выбором нескольких элементов).
Рис. 12. Пример различных видов списков
Поле для ввода многострочного текста (TextArea) представляет собой элемент формы для создания области, в которую можно вводить несколько строк текста. В отличие от тега input в текстовом поле допустимо делать переносы строк, они сохраняются при отправке данных на сервер (рисунок 13).
<textarea name="имя элемента" rows="высота" cols="длина">ТЕКСТ ЭЛЕМЕНТА </textarea>
Данный элемент содержит атрибуты rows и cols, которые определяют высоту и ширину поля соответственно в символах.
Рис. 13. Пример многострочного текстового поля
Поле для добавления файла предназначено для того, чтобы можно было загружать на сервер один или несколько файлов. Для работы с файлами заголовок формы должен быть сопровожден специальным атрибутом enctype=»multipart/formdata» и данные с формы должны передаваться только с помощью метода POST (рисунок 14).
Общий вид поля для добавления файла следующий:
<input type="file" name="имя поля" accept="типы файлов" size="ширина поля" [multiple]>
Как видно из кода, поле содержит необязательный атрибут multiple, который позволяет через одно поле передать сразу несколько файлов. В этом случае атрибут name данного поля должен содержать название с квадратными скобками [ и ], как это было в случае с чек-боксами и списками.
Также в специальном атрибуте accept можно указать типы файлов, которые можно передавать через данное поле. Например, для передачи только файлов изображений можно использовать следующую запись: accept=»image/*».
Рис. 14. Пример поля для прикрепления файла
Скрытое поле – предназначено для передачи через форму каких-то данных, параметров, которые нужны разработчику. При этом пользователи этих полей не видят, но в HTML-коде страницы их можно увидеть. Синтаксис данного поля:
<input type="hidden" name="имя поля" value="значение поля">
Особенность работы по протоколу HTTP, который является основным при передаче информации от сервера к клиенту, является то, что он не поддерживает состояний. Каждый запрос, который клиент (браузер) отправляет к серверу, является независимым от других запросов, при этом сервер не запоминает никаких параметров (решение данной проблемы все же будет озвучено в этом пособии).
Все формы, которые были приведены выше, это часть HTML-кода страницы, который связан лишь с отображением форм. А вот передать данные скрипту по назначению HTML не может – это прерогатива языков программирования, в нашем случае PHP.
Данные в виде переменных и их значений передаются от формы к программе с помощью методов. Различают два основных метода: GET и POST.
Метод GET предназначен для открытой передачи данных, то есть любой человек может всегда увидеть, какие данные передаются через строку адреса браузера. Данные методом GET передаются через URL (universal resource locator – адрес ресурса). Рассмотрим пример такого адреса:
http:// …ru/index.php?var1=value1&var2=value2
Здесь, начиная со знака «?», идет передача значений методом GET в виде пар «имя_переменной=значение». Каждая пара отделяется друг от друга символом амперсанда «&». В данном примере сайту http://site.ru, скрипту index.php передаются две переменные: var1 со значением value1 и var2 со значением value2.
У метода GET есть свои особенности:
- метод GET ограничен отправкой только 1024 символов (то есть передать длинное сообщение или файл через данный метод не получится);
- нельзя использовать метод GET для передачи паролей или любой другой конфиденциальной информации (представьте, если вы ввели в поле пароль, нажали на кнопку «Отправить», и ваш пароль отразился в строке адреса браузера, видимый всем, кто стоит рядом с вами);
- метод GET применим тогда, когда данные нужно запомнить и по возможности передавать по ссылкам. Например, сложный фильтр для получения информации на сайте, поисковый запрос, параметры для доступа к определенным материалам на сайте и др.
Скрипт-обработчик данных с формы (указанные через атрибут action формы) получает данные в специальный суперглобальный массив $_GET. Ключами (индексами) данного массива являются имена переменных. Из приведенного выше примера, скрипт index.php, который находится на домене http://…ru, получает две переменные следующим образом:
$_GET["var1"] (содержит значение value1)
$_GET["var2"] (содержит значение value2)
Существует также суперглобальный массив $_REQUEST, с помощью которого можно получать все переменные, переданные и методом GET и методом POST.
Рассмотрим еще один пример. Пусть есть файл с формой form.html и обработчиком этой формы является файл handler.php.
Form.html
<form action="handler.php" method="get">
<input type="text" name="fio" value="">
<input type="text" name="email" value="example@mail.ru">
<input type="submit">
</form>
handler.php
<?
$a=$_GET["fio"]; Echo "Ваше имя $a";
$b=$_REQUEST["email"]; Echo "Ваш email $b";
?>
Из примера видно, что с формы передаются данные двух текстовых полей fio и email. Скрипт-обработчик получает их либо через массив $_GET, либо через массив $_REQUEST.
Многие разработчики применяют метод GET для передачи данных с форм крайне редко – метод хорошо применяется при передаче данных по гиперссылке, а вот при передаче данных с формы, где требуется написать длинный текст или заполнить множество полей, лучше использовать метод POST.
Особенности метода POST:
- не имеет ограничений по объему отправляемых данных;
- данные, отправленные методом POST, проходят через HTTP-заголовок, поэтому их безопасность зависит от протокола HTTP. Если использовать Secure HTTP (HTTPS), то можно обеспечить защиту передаваемой информации;
- запрос, который был сформирован методом POST в некоторый момент времени, нельзя запомнить и передать в виде ссылки.
Таким образом, можно сказать, что и метод GET и метод POST не являются абсолютно безопасными. Более того, несмотря на то, что метод POST не передает данные в строке адреса, увидеть передаваемые данные через современные браузеры все же можно. Поэтому разработчику при получении данных с форм нужно их фильтровать – проверять тип переменной или преобразовывать к нужному типу, убирать из строковых значений посторонние символы и т.д.
Данные методом POST можно получить с помощью ассоциативного массива $_POST, ключами этого массива будут названия передаваемых полей (как и случае с методом GET). Также, с помощью массива $_REQUEST можно получить значения переменных, переданных методом POST.
Рассмотрим пример обработки формы, показанной на рисунке 7.
index.php
<html>
<head><title>Форма для регистрации участников</title></head>
<body>
<h2>Форма для регистрации участников</h2>
<form action="1.php" method="post">
Имя <br><input type="text" name="first_name" ><br> Фамилия <br><input type="text" name="last_name"><br> E-mail <br><input type="text" name="email"><br>
<p>
Выберите курс:<br>
<input type="radio" name="kurs" value="PHP">PHP<br>
<input type="radio" name="kurs" value="Lisp">Рекурсия и Lisp<br>
<input type="radio" name="kurs" value="Delphi">Delphi<br>
<input type="radio" name="kurs" value="Java">Java<br>
<P>Оставьте о себе информацию <BR>
<textarea name="comment" cols="32" rows="5"></textarea>
<P><input name="confirm" type="checkbox" checked>Подтвердить получение <br>
<input type="submit" name="submit" value="Отправить">
<input type="reset" value="Отменить">
</form>
</body>
</html>
Скриптом-обработчиком формы регистрации участников является файл 1.php
<?php
$submit = $_POST["submit"]; if (isset($submit)){
$str = "Здравствуйте, ".$_REQUEST["first_name"]. " ".$_REQUEST["last_name"]."! <br>";
$str .="Вы выбрали для изучения курс по ".$_REQUEST["kurs"];
echo $str;
}
?>
Здесь важно сделать простую проверку, нажал ли пользователь на кнопку: если существует переменная $submit, полученная методом POST (непустое значение кнопки «Отправить»), то можно получить остальные данные с формы (в коде скрипта их получаем с помощью массива $_REQUEST) и произвести с ними какие-то действия. Результат работы скрипта 1.php может выглядеть в браузере следующим образом (рисунок 15).
Рис. 15. Пример результата обработки данных с формы регистрации участника
Таким образом, язык разметки гипертекста HTML и язык программирования PHP дополняют друг друга при передаче данных от клиента (браузера) на сервер. HTML предоставляет теги для формирования форм на веб-странице, а PHP обрабатывает данные, передаваемые с форм, с помощью методов GET и POST. При передаче данных на сервере их можно получить с помощью суперглобальных массивов $_GET, $_POST или все сразу с помощью $_REQUEST.
5. Сессии и COOKIE в PHP
Как уже было сказано ранее, протокол HTTP не может передать состояние и параметры. Поэтому каждый отдельный HTTP-запрос независим от других, сервер обрабатывает каждый такой запрос отдельно. Частично, эту проблему решает передача методами GET и POST. Однако, при разработке веб-проектов часто возникает необходимость передать какие-то данные между файлами (скриптами).
Типичная ситуация – представьте себе сайт, на котором есть форма авторизации пользователя. Естественно, вводя свои данные одни раз, пользователь не ожидает, что при переходе на другие страницы данного ресурса ему снова придется вводить логин и пароль. Однако все вышеописанные средства для решения этой задачи не подошли бы.
Опишем данную проблему более формально. Пусть имеется файл first.php, в котором мы задаем значение какой-либо переменной.
Файл first.php
<?php
$a = "Меня задали на first.php";
?>
<html>
<body>
<?php echo $a;
?>
</body>
</html>
И предположим, что эту переменную нам необходимо передать в файл second.php. Но файл second.php ничего не знает о значении переменной $a.
Файл second.php
<html>
<body>
<?php
echo $a;
?>
</body>
</html>
Именно из-за отсутствия поддержки передачи информации между скриптами, файл second.php выведет пустое значение переменной $a.
Решением данной проблемы является механизм сессий или сеансов. Условно говоря, сессией является сеанс связи конкретного лица, сидящего за конкретным компьютером (или цифровым устройством), который с помощью одной и той же программы-браузера посещает ресурсы удаленного сервера.
Если пользователь закрыл браузер, то сеанс его связи будет прерван. Если тот же самый пользователь, с того же самого устройства заходит на те же ресурсы, но с другого браузера, то это будет новый сеанс (сессия). Формально в начале сеанса связи сервер определяет небольшую область под хранение данных конкретного сеанса. Способ хранения этих данных (в виде файлов или в виде записей в базе данных) определяется в настройках сервера.
Любой скрипт, который будет использовать переменные (данные) из сессий, должен содержать следующую строчку:
session_start();
Эта команда говорит серверу, что данная страница нуждается во всех переменных, которые связаны с данным пользователем (браузером). Сервер берёт эти переменные (из файла либо из БД) и делает их доступными.
Очень важно открыть сессию до того, как какие-либо данные будут посылаться пользователю; на практике это значит, что функцию session_start() желательно вызывать в самом начале страницы (до тега <html>), например так:
<?php
session_start();
?>
<html>
<head>
</head>
После того как применен вызов функции session_start() и установлен сеанс, можно применить простой подход к чтению/записи сессионных переменных через суперглобальный массив $_SESSION. Еще раз подчеркнем, что сессионные значения хранятся на стороне сервера и хранятся до тех пор, пока сеанс связи не прервется (пользователь не закроет браузер или длительность сессии можно запрограммировать). При присвоении какого-либо значения любому полю массива $_SESSION, переменная с таким же именем автоматически регистрируется как переменная сессии. Этот массив доступен на всех страницах, использующих сессию.
Рассмотрим, как изменится код скриптов при решении задачи передачи значения переменной $a между скриптами first.php и second.php.
Файл first.php
<?php
// открываем сессию session_start();
// задаём значение переменной
$a = "Меня задали на first.php";
// регистрируем переменную с открытой сессией
$_SESSION["a"] = 'Меня задали на first.php'
?>
<html>
<body>
Произошел старт сессии
Перейдите по ссылке для просмотра <a href="second.php">second.php</a>
</body>
</html>
Файл second.php
<?php
// открываем сессию session_start();
?>
<html>
<body>
<?php
echo $_SESSION["a"];
?>
</body>
</html>
В этом случае можно убедиться, что second.php выведет значение «Меня задали на first.php». При этом сессионный механизм работает, т.к. и в файле first.php и в файле second.php произошло подключение к сеансу через session_start().
Другие функции для работы с сессиями:
- unset($_SESSION[‘a’]) – удаление значение переменной a из сессии;
- session_destroy() – сессия уничтожается (например, если пользователь покинул систему, нажав кнопку «Выход»);
- session_set_cookie_params(int lifetime [, string path [, string domain]]) – с помощью этой функции можно установить, как долго будет «жить» сессия, задав unix_timestamp, определяющий время «смерти» сессии. По умолчанию сессия «живёт» до тех пор, пока клиент не закроет окно браузера.
Рассмотрим классический пример применения сессии при авторизации пользователя. Простая авторизация предназначена для выяснения доступа пользователя к некоторым защищенным (засекреченным) страницам. Чаще всего для проверки пользователя используется пара «логин – пароль». Пусть есть пользователь с логином maria и паролем 123456 (не самая надежная пара, но для примера подойдет). На блок-схеме показано (рисунок 16), как работает алгоритм.
Рис. 16. Блок-схема авторизации пользователя
Файл index.php
<html>
<head>
<title>Введите пароль</title>
</head>
<body>
<form action="authorize.php" method="post"> Логин:<input type="text" name="username"><br> Пароль:<input type="password" name="password"><br>
<input type="submit" name="Submit">
</form>
</body>
</html>
Файл authorize.php
<?php
// открываем сессию session_start();
//получаем данные с формы
$Submit = $_POST["Submit"];
$username = $_POST["username"];
$password = $_POST["password"];
// данные были отправлены формой? if($Submit){
// проверяем данные на правильность... if(($username=="maria")&&($password=="123456")){
// запоминаем имя пользователя
$_SESSION["logged_user"] = $username;
// и переправляем его на <секретную> страницу... header("Location: secretplace.php");
exit;
}
}
// если что-то было не так, то пользователь получит сообщение об ошибке.
?>
<html><body>
Вы ввели неверный пароль!
</body></html>
Рассмотрим код файла secretplace.php. Просто зайти на эту страницу нельзя: если имя пользователя не зарегистрировано, то перенаправляем его на страницу index.php для ввода логина и пароля.
Файл secretplace.php
<?php
// открываем сессию session_start();
$logged_user = $_SESSION["logged_user"]; if(!isset($logged_user)){
header("Location: index.php"); exit;
}
?>
<html>
<body>
Здравствуйте, <?php echo $logged_user; ?>, вы на секретной странице<br>
<a href="logout.php">Выйти</a>
</body>
</html>
Также предусмотрим файл logout.php, который позволит выйти из сеанса текущего пользователя (сбросить авторизацию). При этом для чистоты эксперимента после уничтожения сессии перенаправим пользователя снова на секретную страницу. Если пользователь не авторизован, то уже скрипт secretplace.php перенаправит пользователя на index.php.
Файл logout.php
<?php
session_start();
//уничтожаем сессию session_destroy();
//перенаправляем на секретную страницу,
//если сессия сброшена, то произойдет перенаправление на
//index.php
header("location: secretplace.php");
?>
Увидеть файлы с данными сессии можно на локальном сервере в директории WebServers/tmp. Все файлы в этой папке имеют специальные идентификаторы, но если их отсортировать по дате, то можно легко найти последние изменённые файлы (рисунок 17).
Рис. 17. Список файлов сессий
Содержимое этого файла можно легко посмотреть с помощью текстового редактора (рисунок 18).
Рис. 18. Содержимое сессионного файла
Для отслеживания сессий часто применяются специальные cookie-файлы. Они хранятся на компьютере пользователя в виде небольшой текстовой информации. В каждом браузере своя директория для хранения cookie-файлов. В отличие от файлов сессий, cookie могут храниться дольше закрытия браузера. Более того, можно определять время хранения файлов cookie программно. Cookie-файл хранит данные в виде пар «имя – значение».
Cookie применяются для контроля за некоторыми фрагментами информации, к которой обращается пользователь при переходе от страницы к странице. При этом предполагается, что эта информация хранится и после того, как пользователь прервал сеанс связи с сайтом. Примером использования cookie может служить алгоритм голосования – с помощью cookie можно запретить пользователю принимать участие в голосовании более одного раза. Чуть позже мы разберем подробнее этот пример.
Для установки cookie-файлов используется функция setcookie().
Setcookie (имя_cookie, значение_cookie, время_жизни_cookie_в_секундах);
Как и любой другой заголовок cookie должны передаваться до того, как будут выведены какие-либо другие данные скрипта (это ограничение протокола). Это значит, что в скрипте вызовы этой функции должны располагаться до остального вывода, включая вывод тегов <html> и <head>, а также пустые строки и пробельные символы.
Пример
setcookie ('my_cookie', 'Понедельник', time()+60*60*24*3);
Функция time() – возвращает количество секунд, прошедших с 1 января 1970 года. Обратите внимание, что использование записи 60*60*24*3 в качестве добавления секунд жизни cookie гораздо информативнее, чем вычислить это значение и записать 259 200. Так сразу понятно, что время жизни cookie трое суток.
Считывание переменных cookie может происходить с помощью суперглобального массива $_COOKIE (по аналогии с суперглобальным массивом $_SESSION).
Вернемся к примеру с голосованием. Одной из наиболее частных проблем при сборе сведений через формы голосования является то, что один и тот же пользователь может многократно проголосовать. В некоторых случаях это существенно влияет на результаты голосования, поэтому разработчику нужен механизм запрета голосования для пользователя, который уже ранее голосовал.
Механизм сессий здесь не подходит, так как сессия уничтожается, как только пользователь закрыл браузер, и с точки зрения сервера – это будет новый респондент. А вот использование cookie здесь как раз пригодится. После того как пользователь первый раз проголосовал, в его cookie сохраняется небольшая информация.
При попытке в следующий раз проголосовать скрипт сначала посмотрит, не сохранено ли что-то насчет голосования в cookie, если нет, то позволит проголосовать, если есть, то не позволит. Конечно, cookie-файл привязан к браузеру, и ничто не мешает этому же пользователю проголосовать через другой браузер. Но пользователь о таком скорее всего не знает, и в большинстве своем метод сработает.
Фрагмент алгоритма голосования
if (!(isset($_COOKIE['golos']))) { setcookie('golos', 'yes', time()+60*5);
}
else { echo "Вы уже голосовали"; }
В данном случае пользователь не может проголосовать в течение пяти минут.
Таким образом, сессии и cookie позволяют отслеживать и запоминать действия пользователей при взаимодействии с сайтом. Если нужно менять информацию пользователю в зависимости от его выбора или ранее сделанных действий (посещенных страниц, авторизации, голосования, отбора продуктов в корзину, заполнении форм обратной связи и др.), то можно применять сессии и cookie. Надо понимать, что помимо удобства для пользователя, эти механизмы должны быть надежно защищены от несанкционированного доступа посторонних лиц.
6. Работа с функциями
В программировании, как и в математике, функция есть отображение множества ее аргументов на множество ее значений. То есть функция для каждого набора значений аргумента возвращает какие-то значения, являющиеся результатом ее работы.
Как и в любом другом языке программирования, в PHP различают функции, определяемые пользователем (в данном случае программистом), и функции, которые заранее определены в языке программирования. Рассмотрим их по очереди.
Функции, определяемые пользователем, это законченные части программ, которые решают определенную задачу. Пусть, к примеру, необходимо подсчитать факториал какого-либо числа. Факториал числа есть произведение всех чисел от единицы до этого числа. Если брать в качестве числа небольшое, однозначное число, например 4, то задача будет очень простой: 4! = 1*2*3*4 = 24. Но если взять число побольше, например 10, то выписывать все умножения уже несколько утомительно. Функции как раз и предназначены для решения типовой задачи, при этом параметры функции можно менять. Пример алгоритма вычисления факториала числа на PHP приведен ниже.
<?php
function fact($n){
if ($n==0) return 1;
else return $fact = $n * fact($n-1);
}
echo fact(3);
// можно было бы написать echo (3*2);
// но если число большое, echo fact(50);
// то удобнее пользоваться функцией,
// чем писать echo (50*49*48*...*3*2);
?>
Описание функции начинается с служебного слова function. В PHP не важно, где именно описывается функция – до или после вызова. После слова function идет название функции, которое должно быть уникальным и содержать символы латинского алфавита. Название не должно начинаться с цифр, служебных символов, пробелов. В имени функции допускается использование нижнего подчеркивания.
Если функция содержит входные параметры, то они должны быть определены сразу после имени функции. Внутри функции описываются действия. Если функция должна возвращать какое-то значение, то в теле функции должен быть оператор return, выполняющий эту работу. Пример общего описания функции представлен ниже.
function Имя_функции (параметр1, параметр2, ..., параметрN){
Блок_действий
return "значение возвращаемое функцией";
}
Для того чтобы функция выполнила поставленную ей задачу, ее необходимо вызвать. Вызов функции может осуществляться как до, так и после ее описания. Единственное ограничение в этом случае – описание функций внутри условных конструкций. В случае, когда функция определяется в зависимости от какого-либо условия, например как это показано в двух приведённых ниже примерах, обработка описания функции должна предшествовать её вызову. Вызов функции осуществляется указанием ее имени и значений параметров:
<?php Имя_функции("значение_параметра1","значение_параметра2",...);
?>
Аргументы функции бывают двух видов: аргументы-значения и аргументы-переменные.
Аргументы-значения не меняют своего значения в процессе выполнения функции. В этом случае при вызове функции на их месте могут находиться конкретные значения, которые будут использованы в функции. Когда аргумент передается в функцию по значению, изменение значения аргумента внутри функции не влияет на его значение вне функции.
Чтобы позволить функции изменять ее аргументы, их нужно передавать по ссылке (аргументы-переменные). Для этого в определении функции перед именем аргумента следует написать знак амперсанд «&».
<?php
//напишем функцию, которая бы добавляла к строке слово selected
function addOption(&$option){
$option .= "selected";
}
//выводит элемент формы список
$str = "<select>"; echo $str;
// пусть имеется такая строка
$option = "<option ";
echo $option .">Красный</option>";
// выведет "красный", но он не будет выделен addOption($option);
// вызовем функцию
echo $option .">Синий</option>";
//это выведет в списке выделенный "синий"
$str = "</select>"; echo $str;
?>
При работе с функциями в PHP есть замечательная особенность – задавать аргументы функции, используемые по умолчанию. В тех случаях, когда в других языках программирования необходимо дополнительно делать проверки условий существования переданных значений, в PHP можно задавать значения параметров непосредственно в заголовке функции. Само значение по умолчанию должно быть константным выражением, а не переменной и не представителем класса или вызовом другой функции.
Ниже представлена функция, создающая информационное сообщение, подпись к которому меняется в зависимости от значения переданного ей параметра. Если значение параметра не задано, то используется подпись «ЮУрГГПУ».
<?php
function message($sign="ЮУрГГПУ."){
// здесь параметр sign имеет по умолчанию значение "ЮУрГГПУ" echo "Вы приглашены на семинар по веб-технологиям.<br>"; echo "$sign<br>";
}
message();
//вызываем функцию без параметра.
//В этом случае подпись – это ЮУрГГПУ. message("С уважением, Иванов В.П.");
// В этом случае подпись "С уважением, Иванов В.П."
?>
Если у функции несколько параметров, то те аргументы, для которых задаются значения по умолчанию, должны быть записаны после всех остальных аргументов в определении функции. В противном случае появится ошибка, если эти аргументы будут опущены при вызове функции. Код функции A
<?php
function addArticle($title, $description, $author="Иванов Иван"){
echo "Заносим в каталог статью: $title,"; echo "автор $author";
echo "<br>Краткое описание: "; echo "$description <hr>";
}
addArticle("Информатика и мы", "Это статья про информатику...", "Петров Петр");
addArticle("Кто такие продакт-менеджеры", "Это статья про менеджеров проектов...");
?>
Пример неправильной работы с параметрами функции (значение параметра по умолчанию находится перед остальными параметрами):
<?php
function addArticle($author="Иванов Иван", $title, $description){
// ...действия как в предыдущем примере
}
addArticle("Кто такие продакт-менеджеры", "Это статья про менеджеров проектов...");
?>
Рассмотрим работу с областью видимости переменных, используемых как в основной программе, так и в области функций. К таким областям видимости относят глобальные и статичные переменные.
Чтобы использовать внутри функции переменные, заданные вне ее, эти переменные нужно объявить, как глобальные. Для этого в теле функции следует перечислить их имена после ключевого слова global.
Пример использования глобальных переменных
<?
$a=1;
function test_g(){ global $a;
$a = $a*2;
echo 'в результате работы функции $a=', $a;
}
echo 'вне функции $a=', $a, ', '; test_g();
echo "<br>";
echo 'вне функции $a=', $a, ', '; test_g();
?>
В результате работы этого примера будет выведено:
вне функции $a=1, в результате работы функции $a=2 вне функции $a=2, в результате работы функции $a=4
Статические переменные видны только внутри функции и не теряют своего значения, если выполнение программы выходит за пределы функции. Объявление таких переменных производится с помощью ключевого слова static.
Пример работы со статическими переменными
<?
function test_s(){ static $a = 1;
// нельзя присваивать выражение или ссылку
$a = $a*2; echo $a;
}
test_s(); // выведет 2
echo $a; // ничего не выведет, так как $a доступна
//только внутри функции test_s(); // внутри функции $a=2, поэтому
// результатом работы функции
// будет число 4
?>
Если функция в результате работы должна возвращать один результат, то используют оператор return. Отметим, что return может возвращать как одно значение, так и несколько значений в виде массива. Тем не менее считается, что функция возвращает один результат – массив.
Рассмотрим пример возвращения функцией количества дней, прошедших между двумя датами. Причем неважно, какая из дат наступила раньше.
<?php
function daysBetween($start_data, $end_data)
{
return
abs(strtotime($start_data)-strtotime($end_data))/(60*60*24);
}
$how_days = daysBetween("14.03.2021", "17.03.2021"); echo "Прошло $how_days дней";
?>
Здесь мы сталкиваемся с функцией, которая уже определена в php – strtotime. Ее задача – перевести строковое значение даты в количество секунд, прошедших с 1 января 1970 года 00:00:00 UTC (так называемое начало эпохи UNIX). Математическая функция abs возвращает модуль числа, в этой задаче она служит для вычисления абсолютной величины между двумя датами.
Рассмотрим также и другие популярные функции, уже определенные в PHP. Все функции разбиты по категориям – для работы с массивами, для работы со строками, для работы с датой/временем, для работы с mysql и другие. Большинство функций в PHP имеет особую приставку (префикс) в названии, с помощью которой разработчику легко определить ее применимость и назначение.
Кратко рассмотрим функции для работы с массивами, строками и ряд других, которые будут использованы на лабораторных занятиях в рамках данного курса. Про все неописанные функции можно узнать из источников [18; 20].
Многие функции для работы с массивами имеют префикс «array_». Самыми популярными функциями являются:
- count($array) – возвращает количество элементов массива.
- in_array($elem, $array) – проверяет, содержится ли элемент $elem в массиве $array.
- array_search($elem, $array) – проверяет, содержится ли элемент $elem в массиве $array, и возвращает индекс найденного элемента.
- array_values($array) – возвращает новый массив, содержащий все значения переданного на вход массива.
- array_keys($array) – возвращает новый массив, содержащий все индексы в качестве значений переданного на вход массива.
- sort($array, [$flag]) – сортирует массив $array в зависимости от необязательного параметра $flag. Если значение $flag задать SORT_REGULAR, то произойдет обычное сравнение элементов; если SORT_NUMERIC, то числовое сравнение элементов; если SORT_STRING, то строковое сравнение элементов.
- rsort($array, [$flag]) – выполняет сортировку массива в обратном порядке.
- asort($array, [$flag]) – простая сортировка с сохранением ассоциаций ключей.
- arsort($array, [$flag]) – обратная сортировка с сохранением ассоциаций ключей.
- ksort($array, [$flag]) – сортировка массива по ключам.
- krsort($array, [$flag]) – обратная сортировка массива по ключам.
Функции для работы со строками часто в своем названии имеют приставку str.
- str_replace($search, $replace, $subject, [$count]) – заменяет все вхождения строки поиска на строку замены. Эта функция возвращает строку или массив, в котором все вхождения $search в $subject заменены на $replace. При этом $search и $replace могут быть как строками, так и массивами строк. Результат функции также может быть строкой или массивом. Необязательный параметр $count может быть использован для возвращения количества произведённых замен.
- substr($string, $offset, [$length]) – возвращает подстроку строки string, которая начинается с номера символа $offset и имеет длину $length символов. Если $length положительный, возвращаемая строка будет не длиннее $length-символов, начиная с параметра $offset (в зависимости от длины $string). Если $length отрицательный, то будет отброшено указанное этим аргументом число символов с конца строки string (после того как будет вычислена стартовая позиция, если $offset отрицателен). Если при этом позиция начала подстроки, определяемая аргументом $offset, находится в отброшенной части строки или за ней, возвращается false.
- strlen($string) – возвращает длину строки (количество символов в строке).
- explode($separator, $string, [$limit]) – возвращает массив строк, полученных разбиением строки $string с использованием $separator в качестве разделителя. Если аргумент $limit является положительным, возвращаемый массив будет содержать максимум $limit элементов при этом последний элемент будет содержать остаток строки $string. Если параметр $limit отрицателен, то будут возвращены все компоненты, кроме последних $limit. Если $limit равен нулю, то он расценивается как 1.
- implode($separator, $array) – объединяет элементы массива $array в строку с помощью разделителя $separator. В результате возвращает строку.
- strpos($haystack, $needle, [$offset]) – ищет позицию первого вхождения подстроки $needle в строку $haystack. Если $offset указан, то поиск будет начат с указанного количества символов с начала строки. Если задано отрицательное значение, отсчёт позиции начала поиска будет произведён с конца строки.
- addslashes($string) – возвращает строку с обратным слешем перед символами, которые нужно экранировать. Экранируются следующие символы: одинарная кавычка (‘); двойная кавычка («); обратный слеш (\); NUL (байт null).
- trim($string,[$charlist]) – удаляет пробелы из начала и конца строки. Помимо пробелов также может удалять непечатные символы: табуляцию «\t», перевод строки «\n», возврат каретки «\r», NUL-байт «\0», вертикальную табуляцию «\x0B». Можно перечислить удаляемые символы через строку $charlist.
- stripslashes($string) – удаляет экранирующие обратные слэши. (\’ преобразуется в ‘, и т.д.). Двойные бэкслэши (\\) преобразуется в одиночные (\).
- htmlspecialchars($string, []) – преобразует специальные символы в HTMLсущности. ‘&’ (амперсанд) преобразуется в ‘&’; ‘»‘ (двойная кавычка) преобразуется в ‘"’; »’ (одиночная кавычка) преобразуется в ‘'’ только в режиме ENT_QUOTES; ‘<‘ (знак «меньше, чем») преобразуется в ‘<’; ‘>’ (знак «больше, чем») преобразуется в ‘>’.
- md5($string) – возвращает MD5-хеш строки в виде 32-символьного шестнадцатеричного числа. Алгоритм необратим, то есть хеш нельзя дешифровать. Функция используется для сравнения файлов, хранения паролей в закодированном виде и других криптографических задач.
Также в PHP есть функции для работы с переменными – проверка значений переменных
- isset($variable) – определяет, была ли установлена переменная $variable значением отличным от null.
- unset($variable) – удаляет переменную $variable.
- intval($variable) – функция преобразования типов, возвращает целое значение переменной $variable.
- floatval($variable) – функция преобразования типов, возвращает число с плавающей точкой по переменной $variable.
Математические функции
- abs($number) – возвращает абсолютное значение $number.
- round($num, [$precision], [$mode]) – возвращает округлённое значение $num с указанной точностью $precision (количество цифр после запятой). $precision может быть отрицательным или нулём (по умолчанию).
- ceil($num) – возвращает ближайшее большее целое от $num.
- mt_rand([$min], [$max]) – генерирует случайное значение методом с помощью генератора простых чисел. $min – необязательный параметр: минимальное значение случайного числа (по умолчанию: 0). $max – необязательный параметр: максимальное значение случайного числа
Функция для отправки почтового сообщения
- mail($to, $subject, $message, [$additional_headers], [$additional_params]) – отправляет электронную почту на адрес $to, с темой $subject и содержанием письма $message. Необязательный параметр $additional_headers – это строка или массив, которые будут вставлены в конец отправляемых заголовков письма. Параметр $additional_params может быть использован для передачи дополнительных флагов в виде аргументов командной строки для программы, сконфигурированной для отправки писем, указанной директивой sendmail_path. Например, можно установить отправителя письма при использовании sendmail с помощью опции -f.
Здесь приведена лишь малая часть функций, которые определены в PHP. В следующем параграфе мы отдельно рассмотрим функции для работы с файловой системой. Функции для работы с базами данных также рассмотрим в параграфе 2.9. Тем не менее даже такая небольшая часть функций может принести большую пользу разработчику, так как они решают наиболее частые задачи при программировании вебпроектов.
7. Работа с файловой системой
При разработке веб-проектов важной задачей является работа с файловой системой. При этом разработчик должен писать алгоритм как для взаимодействия с файловой системой локального компьютера, так и с файловой системой веб-сервера. Все такие операции, как: загрузка файла с локального компьютера на сервер, копирование файла на сервере из одной директории в другую, создание файла, переименование, удаление, редактирование и другие – реализуется с помощью особых функций в PHP.
Рассмотрим эти функции:
-
- сopy($source, $dest) – копирует файл $source в файл с именем $dest. Функция возвращает true в случае успешного завершения, или false, в случае возникновения ошибки.
- move_uploaded_file($filename, $destination) – функция проверяет, является ли файл $filename загруженным на сервер (переданным по протоколу HTTP POST). Если файл действительно загружен на сервер, он будет перемещён в место, указанное в аргументе $destination. В отличие от функции copy() эта функция перемещает файл с локального компьютера на сервер.
- rename($oldname, $newname) – пытается переименовать $oldname в $newname, перенося файл между директориями, если необходимо. Если $newname существует, то он будет перезаписан. При переименовании директории с существующим $newname будет выведено предупреждение.
- fopen ($filename, $mode) – открывает файл $filename на операцию в зависимости от значения $mode. $mode – это строка, которая может содержать одно из следующих значений.
- г – открыть только для чтения, помещает указатель на начало файла.
- г+ – открыть для чтения и для записи, помещает указатель на начало файла.
- w – открыть только для записи, помещает указатель на начало файла и очищает все содержимое файла. Если файл не существует, то создается новый.
- w+ – открыть для чтения и для записи, помещает указатель на начало файла и очищает все содержимое файла. Если файл не существует, создается новый.
- а – открыть только для записи, помещает указатель на конец файла. Если файл не существует, создается новый.
- а+ – открыть для чтения и для записи, помещает указатель на конец файла. Если файл не существует, создается новый.
- fclose($filename) – закрывает файл, который ранее был открыт дескриптором fopen(). Возвращает true, в случае успешного завершения, или false, в случае возникновения ошибки.
- feof($filename) – проверка, не конец ли файла. Возвращает true, если указатель файла указывает на EOF или произошла ошибка, иначе возвращает false.
- fgets($handle, [$length]) – читает строку из файлового указателя $handle. $length – необязательное числовое значение, указывающее размер получаемой строки в байтах.
- fread($stream, [$lenght]) – бинарно-безопасное чтение файла. Читает до $length байт из файлового указателя stream и смещает указатель. Чтение останавливается, как только было достигнуто одно из следующих условий: было прочитано $length байт; достигнут EOF (конец файла).
- fwrite($handle, $string, [$length]) – бинарно-безопасная запись в файл. Строку $string функция записывает в файловый поток $handle. Если передан аргумент $length, запись остановится после того, как $length байтов будут записаны или будет достигнут конец строки $string, смотря на то, что произойдёт раньше.
- file($filename) – читает содержимое файла $filename и помещает его в массив. Возвращает файл в виде массива. Каждый элемент массива соответствует строке файла, с символами новой строки включительно. В случае ошибки file() возвращает false.
- file_get_contents($filename) – читает содержимое файла $filename и помещает его в строку.
- unlink($filename) – удаляет файл $filename.
Рассмотрим простой пример работы с файловой системой на PHP – алгоритм открывает файл newname.txt на чтение, затем считывает из этого файла все строки длиной 3 символа и выводит их на экран браузера. После этого происходит безопасное закрытие файла.
<?php
if ($fp=fopen("newname.txt","r"))
echo "Работа функции fopen() произведена успешно !<br>"; do {
$str = fgets ($fp, 3); echo $str, " <br>";
}
while (!feof($fp));
if (!fclose($fp)){
echo "Функция fclose () выполнила ошибку<br>";
}
else {
echo "Закрытие файла newname.txt осуществлено успешно<br>";
}
?>
Рассмотрим еще одну типичную задачу работы с файлами – чтение из файла и получение данных в виде строки.
<?php
//получает содержимое файла в строку
$filename = "/usr/local/something.txt";
$handle = fopen($filename, "r");
$contents = fread($handle, filesize($filename)); fclose($handle);
?>
Помимо чтения необходимо часто использовать операцию запись в файл. При этом в рассмотренном ниже примере запись в файл происходит первых 7 символов.
<?php
$h = fopen("my_file.html","a");
$add_text = "Добавим текст в файл."; if (fwrite($h,$add_text,7))
echo "Добавление текста прошло успешно<br>";
else
?>
echo "Произошла ошибка при добавлении данных<br>"; fclose($h);
Как уже было описано выше, функция move_uploaded_file предназначена для загрузки файла на сервер. Зачастую при подобных операциях важно ограничивать размер загружаемого файла (ресурсы сервера не бесконечны), а также фильтровать файлы по типу (например, разрешать загружать файлы определенных типов). В следующем примере рассмотрено, как может быть организована загрузка файла на сервер, размером не более 30 000 байт (≈30 Кбайт). На лабораторных работах будет рассмотрен пример с проверкой типов загружаемых файлов.
Пусть имеется файл index.php, на котором есть форма для загрузки файлов. Форма должна содержать обязательный атрибут enctype=»multipart/form-data» для загрузки файлов.
<form enctype="multipart/form-data" action="parse.php" method="post">
<input type="hidden" name="MAX_FILE_SIZE" value="30000"
/>
Загрузить файл:
<input type="file" name="myfile" /><br>
<input type="submit" value="Отправить файл" />
</form>
Обработчиком формы является файл parse.php, который должен получить файл с формы и организовать его загрузку на сервер.
<?
$uploaddir = 'c:/uploads/'; /*будем сохранять загружаемые файлы в эту директорию */
$destination = $uploaddir . $_FILES['myfile']['name']; /* имя файла оставим неизменным */
print "<pre>";
if (move_uploaded_file( $_FILES['myfile']['tmp_name'],
$destination)) {
/* перемещаем файл из временной папки в выбранную директорию для хранения */
print "Файл успешно загружен <br>"; }
else { echo "Произошла ошибка при загрузке файла. Некоторая отладочная информация:<br>"; print_r($_FILES);
}
print "</pre>";
?>
Помимо работы с файлами, в PHP имеется возможность управления директориями: создание каталога и удаление каталога.
- mkdir($directory, [$permission]) – создает каталог $directory. $permission по умолчанию принимает значение 0777, что означает самые широкие права. Больше информации о правах доступа можно узнать на странице руководства функции chmod().
- rmdir($directory) – удаляет указанную директорию. Директория должна быть пустой и должны иметься необходимые для этого права. При неудачном выполнении будет сгенерирована ошибка уровня E_WARNING.