Лекція №3

 

Лекція №3

Робота з масивами, Сортування масивів, Застосування функції до всіх елементів масиву, Виділення під масивів, Робота з рядками, Робота з файловою системою, Завантаження файлу на сервер, Математичні функції, Функції для роботи з датою і часом

Мова PHP підтримує безліч функцій для роботи з масивами даних. Як правило, ці функції найбільш часто зустрічаються у задачах, пов'язаних з обробкою великих кількостей однотипних данних.

Робота з масивами

Масив можна створити двома способами:

  1. За допомогою конструкції array

$аrray_name = array ("key1" => "value1",
"key2" => "value2");

  1. Безпосередньо задаючи значення елементів масиву

$ аrray_name ["key1"] = value1;

Наприклад, нам потрібно зберігати список документів, які будуть видалені з бази даних. Природно зберігати його у вигляді масиву, ключем в якому буде ідентифікатор документа (його унікальний номер), а значенням - назва документа. Цей масив можна створити таким чином

<? 
$Del_items = array ("10" => "Наука і життя", 
"12" => "Інформатика"); 
$Del_items ["13"] = "Програмування на Php"; 
// Додаємо елемент в масив 
?>

Операції з масивами

Масив - це тип даних, для роботи з ними існуює група операцій. Які ж операції можна проводити з масивами? Масиви можна складати і порівнювати.

Складають масиви за допомогою стандартного оператора «+». Взагалі кажучи, цю операцію по відношенню до масивів точніше назвати об'єднанням. Якщо у нас є два масиви, $a та $b, то результатом їх складання (об'єднання) буде масив $c, що складається з елементів $a, до яких праворуч дописані елементи масиву $b. Причому, якщо зустрічаються одинакові ключі, то в результуючий масив включається елемент з першого масиву, тобто з $a. Таким чином, якщо складаються масиви в мові PHP, то від зміни місць доданків сума змінюється.

Приклад 1. Додавання масивів

<? 
$а = array ("і" => "Інформатика", 
"М" => "Математика"); 
$  = array ("і" => "Історія", "м" => "Біологія", 
"Ф" => "Фізика"); 
$c = $a + $b; 
$d = $b + $a; 
print_r ($c); 
/* Отримаємо: Array ([і] => Інформатика 
[М] => Математика [ф] => Фізика) */ 
print_r ($d); 
/* Отримаємо: Array ([і] => Історія 
[М] => Біологія [ф] => Фізика) */ 
?>

Порівнювати масиви можна, перевіряючи їх на рівність чи нерівність або еквівалентність або нееквівалентність. Рівність масивів - це коли співпадають всі пари ключа / значення елементів масивів. Еквівалентність - коли крім рівності значень і ключів елементів потрібно ще, щоб елементи в обох масивах були записані в одному і тому ж порядку. Рівність значень в PHP позначається символом «==», а еквівалентність - символом «===».

Приклад 2. Порівняння масивів

<? 
$а = array ("і" => "Інформатика", 
"м" => "Математика"); 
$b = array ("м" => "Математика", 
"І" => "Інформатика"); 
if ($a == $b) echo "Масиви рівні і"; 
else echo "Масиви НЕ рівні і"; 
if ($a === $b) echo "еквівалентні"; 
else echo "НЕ еквівалентні"; 
// Отримаємо echo "Масиви рівні і НЕ еквівалентні " 
?>

Далі розглянемо ще одну важливу операцію з масивом - підрахунок кількості його елементів. Для її реалізації в PHP існує спеціальна функція.

Функція count

Не раз вже ми використовували функцію count (), щоб обчислити кількість елементів масиву. Насправді ця функція обчислює число елементів у змінній взагалі. Якщо застосувати її до будь-якої іншої змінної, вона поверне 1. Виняток становить змінна типу NULL - count (NULL) є 0. Крім того, застосовуючи цю функцію до багатовимірного масиву, щоб отримати число його елементів, потрібно використовувати додатковий параметр COUNT_RECURSIVE.

Приклад 3. Застосування функції count ()

<? 
$del_items = array ("langs" => array ( 
"10" => "Python", "12" => "Lisp"), 
"Other" => "Інформатика"); 
echo count ($del_items). ""; 
// Виведе 2 
echo count ($del_items, COUNT_RECURSIVE); 
// Виведе 4 
?>

Функція in_array

in_array ("шукане значення", "масив", 
["Обмеження на тип"]);

Дозволяє встановити, чи міститься у заданому масиві шукане значення. Якщо третій аргумент заданий як true, то в масиві потрібно знайти елемент, що співпадає з шуканим не тільки за значенням, але і по типу. Якщо шукане значення - рядок, то порівняння чутливе до регістру.

Наприклад, є масив не вивчених нами мов програмування. Ми хочемо дізнатися, чи міститься в цьому масиві мова PHP. Напишемо наступну програму:

<? Php 
$langs = array ("Lisp", "Python", "Java", 
"PHP", "Perl"); 
if (in_array ("PHP", $langs, true)) 
echo "Треба б вивчити PHP <br>"; 
// Виведе повідомлення "Треба б вивчити PHP" 
if (in_array ("php", $langs)) 
echo "Треба б вивчити php <br>"; 
// Нічого не виведе, оскільки в масиві 
// Є рядок "PHP", а не "php" 
?>

В якості шуканого значення цієї функції може виступати і масив. Правда, ця опція була додана тільки починаючи з PHP 4.2.0.

Наприклад:

<? Php 
$langs = array ("Lisp", "Python", array ("PHP", "Java"), "Perl"); 
if (in_array (array ("PHP", "Java"), $langs)) 
echo "Треба б вивчити PHP і Java <br>"; 
?>

Функція array_search

Це ще одна функція для пошуку значення в масиві. На відміну від in_array в результаті роботи array_search повертає значення ключа, якщо елемент знайдено, і брехня - в іншому випадку. А ось синтаксис у цих функцій однаковий:

array_search ("шукане значення", "масив", 
["Обмеження на тип"]);

Порівняння рядків чутливе до регістру, а якщо вказаний опціональний аргумент, то рівняються ще й типи значень. До PHP 4.2.0, якщо шукане значення не було знайдено, ця функція повертала помилку або пусте значення NULL.

Приклад 4. Тепер, навпаки, нехай у нас є масив мов програмування, які ми знаємо. Причому ключем кожного елемента є номер, що вказує, яким за рахунком було вивчено цю мову.

Приклад 5. Застосування функції array_search ()

<? Php 
$ angs = array (""," Lisp "," Python "," Java ", 
"PHP", "Perl"); 
if (! array_search ("PHP", $langs)) 
echo "Треба б вивчити PHP <br>"; 
else { 
$ K = array_search ("PHP",$ langs); 
echo "PHP я вивчила $k-м"; 

?>

У результаті ми отримаємо рядок: 
PHP я вивчила 4-м

Очевидно, що ця функція більш функціональна, ніж in_array, оскільки ми не тільки отримуємо інформацію про те, що шуканий елемент у масиві є, але і дізнаємося, де саме в масиві він знаходиться. А що буде, якщо шуканих елементів у масиві декілька? У такому випадку функція array_search () поверне ключ першого зі знайдених елементів. Щоб отримати ключі всіх елементів, потрібно скористатися функцією array_keys ().

Функція array_keys

Функція array_keys () повертає всі ключі масиву. Але в неї є додатковий аргумент, за допомогою якого можна отримати список ключів елементів з конкретним значенням. Синтаксис цієї функції такий:

array_keys ("масив", 
["Значення для пошуку"])

Функція array_keys () повертає як рядкові, так і числові ключі масиву, організовуючи всі значення у вигляді нового масиву з числовими індексами.

Приклад 6. Ми записали масив мов, які вивчили. Список був довгим, і деякі мови були записані декілька разів. У нас виникла підозра, що одина з таких мов - Lisp. Давайте це перевіримо:

<? Php 
$langs = 
array ("Lisp", "Python", "Java", "PHP", 
"Perl", "Lisp"); 
$lisp_keys = array_keys ($langs, "Lisp"); 
echo "Lisp входить в масив". 
count ($lisp_keys). "рази: <br>"; 
foreach ($lisp_keys as $ val) { 
echo "під номером $val <br>"; 

?>

У результаті отримаємо: 
Lisp входить в масив 2 рази: 
під номером 0 
під номером 5

Функція array_keys (), як і дві попередні, залежать від регістра, тобто елементів LISP в масиві вона не виявить. array_keys () з'явилася лише в PHP4. У PHP3 для реалізації її функціональності потрібно придумувати свою функцію.

Якщо є функція для отримання всіх ключів масиву, то можна припустити, що існує і функція для отримання всіх значень масиву. Дійсно, вона існує. Це функція array_values (масив). Всі значення переданого їй масиву записуються в новий масив, проіндексований цілими числами, тобто всі ключі масиву губляться, залишаються лише значення. Але повернемося до нашого прикладу.

Отже, ми з'ясували, що мова Lisp випадково згадана в нашому масиві двічі. Оскільки вивчити одну мову двічі не можна («вивчав, але забув» не береться до уваги), то потрібно якось позбутися від повторюваних мов. Зробити це досить просто за допомогою функції array_unique ().

Функція array_unique

Функція array_unique (масив) повертає новий масив в якому елементи, що повторюються фігурують в одному екземплярі. Таким чином, замість кількох однакових значень і їх ключів ми маємо одне значення. Який у нього буде ключ? Як з декількох ключів однакових елементів вибирається той, який буде збережений в новому масиві? Відбувається наступне. Всі елементи масиву перетворюються у рядки та сортуються. Потім обробник запам'ятовує перший ключ для кожного значення, а решту ключів ігнорує.

Спробуємо позбутися від повторюваних мов у списку вивчених.

<? Php 
$langs = 
array ("Lisp", "Java", "Python", "Java", 
"PHP", "Perl", "Lisp"); 
print_r (array_unique ($langs)); 
?>

Отримаємо наступне:

Array ([0] => Lisp [1] => Java [2] => Python [3] 
=> PHP [4] => Perl)

Далі розглянемо задачу сортування масиву.

Сортування масивів

Необхідність сортування даних, в тому числі й даних, що зберігаються у вигляді масивів, дуже часто виникає при вирішенні найрізноманітніших завдань. Якщо мові Сі для того, щоб вирішити цю задачу, потрібно написати десятки рядків коду, то в PHP це робиться однією простою командою.

Функція sort

Функція sort має наступний синтаксис:

sort (масив [, опції])

і сортує масив, тобто впорядковує його значення за зростанням. Ця функція видаляє всі існуючі в масиві ключі, замінюючи їх числовими індексами, відповідно новим порядком елементів. У разі успішного завершення роботи вона повертає true, інакше - false.

Приклад 7. Нехай у нас є два масиви: ціна товарів - їх назви і, навпаки, назви товарів - їх ціна. Впорядкуємо ці масиви за зростанням:

<? 
$іtems = array (10 => "хліб", 20 => "молоко", 
30 => "бутерброд"); 
sort($items); 
// Рядки сортуються в алфавітному 
// Порядок, ключі змінюються 
print_r ($items); 

$rev_items = array ("хліб" => 10, 
"Бутерброд" => 30, "молоко" => 20); 
sort ($rev_items); 
// Числа сортуються за зростанням, 
// Ключі змінються 
print_r ($rev_items); 
?>

Отримаємо:

Array ([0] => бутерброд [1] =>молоко [2] => хліб) 
Array ([0] => 10 [1] => 20 [2] => 30)

В якості додаткового аргументу можна використовувати одне з наступних констант:

  • SORT_REGULAR - порівнювати елементи масиву звичайним чином;
  • SORT_NUMERIC - порівнювати елементи масиву як числа;
  • SORT_STRING - порівнювати елементи масиву як рядки.

Функції asort, rsort, arsort

Якщо потрібно зберігати індекси елементів масиву після сортування, то потрібно використовувати функцію asort (масив [, опції]). Якщо необхідно відсортувати масив у зворотному порядку, тобто від найбільшого значення до найменшого, то можна використати функцію rsort (масив [, опції]). А якщо при цьому потрібно ще й зберегти значення ключів, то слід використовувати функцію arsort (масив [, опції]). Як ви, напевно, помітили синтаксис у цих функцій абсолютно такий же, як у функції sort. Відповідно і значення опцій можуть бути такими ж, як у sort: SORT_REGULAR, SORT_NUMERIC, SORT_STRING. До речі кажучи, прапор SORT_NUMERIC з'явився тільки в PHP4.

Приклад 7. Застосування функцій asort, rsort, arsort

<? Php 
$books = array ("Пушкін" => "Руслан і Людмила", 
"Толстой" => "Війна і мир", 
"Лермонтов" => "Герой нашого часу"); 
asort ($books); 
// Сортуємо масив, 
// Зберігаючи значення ключів 
print_r ($books); 
echo "<br>"; 
rsort ($books); 
// Сортуємо масив у зворотному порядку, 
// Ключі будуть замінені 
print_r($books); 
?>

У результаті роботи цього скрипта одержимо: 
Array ([Толстой] => Війна і мир 
[Лермонтов] => Герой нашого часу 
[Пушкін] => Руслан і Людмила) 
Array ([0] => Руслан і Людмила 
[1] => Герой нашого часу 
[2] => Війна і мир)

Припустимо, ми створюємо каталог описів документів. У кожного документа є автор, назва, дата публікації і короткий зміст. Ми вже не раз відображали данні, складені з цих характеристик. Кожного разу порядок відображення цих елементів залежав від створеної нами програми. Тепер же ми хочемо мати можливість змінювати порядок відображення елементів за бажанням користувача. Складемо для цього наступну форму:

Приклад 8a. Форма для прикладу 8

<form action=task.php> 
<table border=1> 
<tr> <td> Назва </ td> <td> <input type = text 
name = title size = 5> </ td> </ tr> 
<tr> <td> Короткий зміст </ td> <td> <input 
type = text name = description size = 5> 
</ Td> </ tr> 
<tr> <td> Автор </ td> <td> <input type = text 
name = author size = 5> </ td> </ tr> 
<tr> <td> Дата публікації </ td> <td> <input 
type = text name = published size = 5> </ td> </ tr> 
</ Table> 
<input type=submit value="Відправити"> 
</ Form>

Будемо упорядковувати дані, передані цією формою, за зменшенням їх значень, зберігаючи при цьому значення ключів. Для цього зручно скористатися функцією arsort (). Оскільки нам важливий тільки новий порядок елементів, збережемо у новому масиві ключі вихідного масиву в потрібному порядку. Ми зберігаємо ключі вихідного масиву, оскільки вони є іменами елементів, з яких конструюється опис документа, пам'ятати їх важливо. Отже, отримуємо такий скрипт:

Приклад 8b. Програма обробки форми з прикладу 8

<? Php 
print_r ($_GET); echo "<br>"; 
arsort ($_GET); 
// Сортуємо масив у зворотному порядку, 
// Зберігаючи ключі 
print_r ($_GET); echo "<br>"; 
$ordered_names = array_keys ($_GET); 
// Складаємо новий масив 
foreach ($ordered_names as $ key => $ val) 
echo "$ key: $ val <br>"; 
// Виводимо елементи нового масиву 
?>

Сортування масиву по ключах

Очевидно, що може виникнути необхідність у сортуванні масиву за значеннями ключів. Наприклад, якщо у нас є масив даних про книжки, як у наведеному вище прикладі, то цілком ймовірно, що ми захочемо відсортувати книги по іменах авторів. Для цього в PHP також не потрібно писати багато рядків коду - можна просто скористатися функцією ksort () для сортування за зростанням (прямий порядок сортування) або krsort () - для сортування за спаданням (зворотний порядок сортування). Синтаксис цих функцій знову ж аналогічний синтаксису функції sort ().

Приклад 9. Сортування масиву по ключах

<? Php 
$books = array ("Пушкін" => "Руслан і Людмила", 
"Толстой" => "Війна і мир", 
"Лермонтов" => "Герой нашого часу"); 
ksort ($books); 
// Сортуємо масив, 
// Зберігаючи значення ключів 
print_r ($books); 
?>

Отримаємо:

Array ([Лермонтов] => Герой нашого часу 
[Пушкін] => Руслан і Людмила 
[Толстой] => Війна і мир)

Сортування за допомогою функції, створеної користувачем

Крім двох простих способів сортування значень масиву (за спаданням або за зростанням) PHP пропонує користувачеві можливість самому задавати критерії для сортування даних. Критерій задається за допомогою функції, ім'я якої вказується в якості аргументу для спеціальних функцій сортування usort () або uksort (). За назвами цих функцій можна здогадатися, що usort () сортує значення елементів масиву, а uksort () - значення ключів масиву за допомогою певної функції користувача. Обидві функції повертають true, якщо сортування пройшла успішно, і false - в протилежному випадку. Їх синтаксис виглядає наступним чином:

usort (масив, сортуюча функція) 
uksort (масив, сортуюча функція)

Звичайно ж, не можна сортувати масив за допомогою будь-якої функції користувача. Ця функція повинна задовольняти певним критеріям, що дозволить порівнювати елементи масиву. Яка повинна бути структура функції сортування? По-перше, вона повинна мати два аргументи. У них інтерпретатор буде передавати пари значень елементів для функції usort () або ключів масиву для функції uksort (). По-друге, функція, що сортує повинна повертати:

  • ціле число, менше нуля, якщо перший аргумент менше другого;
  • число, рівне нулю, якщо два аргументи рівні;
  • число більше за нуль, якщо перший аргумент більше другого.

Як і для інших функцій сортування, для функції usort () існує аналог, що не змінює значення ключів, - функція uasort ().

Приклад 10. Припустимо, у нас є масив, який містить такі відомості про літературні твори, як назва, автор і рік створення. Ми хочемо впорядкувати книги за датою створення.

<? Php 
// Масив виглядає таким чином: 
$books = array ("Герой нашого часу" => 
array ("Лермонтов", 1840), 
"Руслан і Людмила" => array ("Пушкін", 1820), 
"Війна і мир" => array ("Толстой", 1863), 
"Ідіот" => array ("Достоєвський", 1868)); 
/* Можна, звичайно переписати цей масив 
по-іншому, зробивши рік видання, наприклад, 
індексом, але набагато зручніше написати свою 
функцію для сортування * / 

uasort ($books, "cmp"); 
// Сортуємо масив за допомогою функції cmp 

foreach ($books as $key => $book) { 
echo "$ book [0]: \" $ key \ "<br>"; 

function cmp ($a, $b) { 
// Функція, що визначає спосіб сортування 
if ($a [1] <$b[1]) return -1; 
elseif ($a [1] == $b [1]) return 0; 
else return 1; 

?>

У результаті отримаємо:

Пушкін: "Руслан і Людмила" 
Лермонтов: "Герой нашого часу" 
Толстой: "Війна і мир" 
Достоєвський: "Ідіот"

Ми застосували нашу власну функцію сортування до всіх елементів масиву. Далі розглянемо, як застосувати до елементів масиву будь-яку іншу функцію користувача.

Застосування функції до всіх елементів масиву

Функція array_walk (масив, функція [, дані]) застосовує створену користувачем функцію до всіх елементів масиву масив і повертає true у разі успішного виконання операції і false - в протилежному випадку.

Функція користувача, як правило, має два аргументи, у які по черзі передаються значення і ключ кожного елемента масиву. Але якщо при виконанні функції array_walk () вказано третій аргумент, то він буде розглянутий, як значення третього аргументу для функції користувача, зміст якого визначає сам користувач. Якщо функція користувача потребує більше аргументів, ніж у неї передано, то при кожному виклику array_walk () буде видаватися попередження.

Якщо необхідно працювати з реальними значеннями масиву, а не з їх копіями, слід передавати аргумент на функцію по посиланню. Однак потрібно мати на увазі, що не можна додавати або видаляти елементи масиву і проводити дії, що змінюють сам масив, оскільки в цьому випадку результат роботи array_walk () вважається невизначеним.

Приклад 11. Застосування функції до всіх елементів масиву

<? Php 
$books1 = array ( 
"А. С. Пушкін" => "Руслан і Людмила", 
"Л. Н. Толстой" => "Війна і мир", 
"М. Ю. Лермонтов" => "Герой нашого часу"); 
// Створюємо функцію, яку хочемо 
// Застосувати до елементів масиву 

function try_walk ($val, $key, $data) { 
echo "$data \" $val \ "написав $key <br>"; 

// Застосовуємо до всіх елементів масиву 
// $books1 функцію try_walk 
array_walk ($books1, "try_walk", "Роман");
?>

У результаті роботи скрипта одержимо: 
Роман "Руслан і Людмила" написав А.С. Пушкін 
Роман "Війна і мир" написав Л.М. Толстой 
Роман "Герой нашого часу" написав М.Ю. Лермонтов

Зауважимо, що ми не змінили значень у елементах масиву. Щоб їх змінити, треба було передавати значення в змінну $val функції try_walk по посиланню.

Приклад 12. Застосування функції до всіх елементів масиву. Варіант 2

<? Php 
$books1 = array ( 
"А. С. Пушкін" => "Руслан і Людмила", 
"Л. Н. Толстой" => "Війна і мир", 
"М. Ю. Лермонтов" => "Герой нашого часу"); 
// Створюємо функцію, яку хочемо 
// Застосувати до елементів масиву 

function try_walk (&$val, $key) { 
$key = "<p> Автор:". $key. "<br>"; 
$val = "Назва: \" ". $val." \ ""; 
echo $key. $val; 

// Застосовуємо до всіх елементів масиву 
// $book1 функцію try_walk 

array_walk ($books1, "try_walk"); 
print_r ($books1); 
?>

У результаті роботи скрипта одержимо: 
Автор: А.С. Пушкін 
Назва: "Руслан і Людмила" 
Автор: Л.М. Толстой 
Назва: "Війна і мир" 
Автор: М.Ю. Лермонтов 
Назва: "Герой нашого часу" 
Array ([А. С. Пушкін] => 
Назва: "Руслан і Людмила" 
[Л.М. Толстой] => 
Назва: "Війна і мир" 
[М.Ю. Лермонтов] => 
Назва: "Герой нашого часу")

Виділення підмасивів

Функція array_slice

Оскільки масив - це набір елементів, цілком ймовірно, буде виділити з нього який-небудь піднабір. У PHP для цих цілей є функція array_slice. Її синтаксис такий:

array_slice (масив, 
номер_елемента [, довжина])

Ця функція виділяє підмасив певної довжини в масиві, починаючи з елемента, номер якого заданий параметром номер_елемента. Позитивний номер_елемента вказує на порядковий номер елемента щодо початку масиву, негативний - на номер елемента з кінця масиву.

Приклад 13. Використання функції array_slice ()

<? Php 
$arr = array (1,2,3,4,5); 
$sub_arr = array_slice ($arr, 2); 
print_r ($sub_arr); 
/*виведе Array ([0] => 3 [1] => 4 [2] => 5), 
тобто підмасив, що складається з елементів 
3, 4, 5 * / 
$sub_arr = array_slice ($arr, -2); 
print_r ($sub_arr); 
//Виведе Array ([0] => 4 [1] => 5), 
//Тобто підмасив, з елементів 4, 5 
?>

Якщо задати параметр довжини при використанні array_slice, то буде виділений підмасив, що має рівно стільки елементів, скільки задано цим параметром. Довжину можна вказувати і негативну. У цьому випадку інтерпретатор скопіює з кінця масиву число елементів, рівне модулю параметру довжини.

Приклад 14. Використання функції array_slice (). Варіант 2

<? Php 
$arr = array (1,2,3,4,5); 
$sub_arr = array_slice ($arr, 2, 2); 
// Містить масив з елементів 3, 4 
$sub = array_slice ($ arr, -3, 2); 
// Теж містить масив з елементів 3, 4 
$sub1 = array_slice ($arr, 0, -1); 
// Містить масив з 
// Елементів 1, 2, 3, 4 
$sub2 = array_slice ($arr, -4, -2); 
// Містить масив з елементів 2, 3 
?>

Функція array_chunk

Є ще одна функція, схожа на array_slice () – це array_chunk (). Вона розбиває масив на кілька підмасивів заданої довжини. Синтаксис її такий:

array_chunk (масив, розмір 
[, зберігати_ключі])

У результаті роботи array_chunk () повертає багатовимірний масив, елементи якого являють собою отримані підмасиви. Якщо задати параметр зберігати ключі як true, то при розбитті будуть збережені ключі вихідного масиву. В іншому випадку ключі елементів замінюються числовими індексами, які починаються з нуля.

Приклад 15. У нас є список запрошених, оформлений у вигляді масиву їх прізвищ. У нас є столики на три персони. Тому потрібно розподілити всіх запрошених по троє.

<? Php 
$persons = array ("Іванов", "Петров", 
"Сидорова", "Зайцева", "Волкова"); 
$triples = array_chunk ($persons, 3); 
// Ділимо масив на підмасиви 
// По три елементи 
foreach ($triples as $k => $table) { 
// Виводимо отримані трійки 
echo "За столиком номер $ k сидять: <ul>"; 
foreach ($table as $pers) 
echo "<li> $pers"; 
echo "</ ul>"; 
} ?>

У результаті отримаємо: 
за столиком номер 0 сидять:

  • Іванов
  • Петров
  • Сидорова

за столиком номер 1 сидять:

  • Зайцева
  • Волкова

Сума елементів масиву

У цьому розділі ми познайомимося з функцією, що обчислює суму всіх елементів масиву. Сама задача обчислення суми значень масиву гранично проста. Але навіщо писати зайвий раз один і той самий код, якщо можна скористатися спеціально створеною і завжди доступною функцією. Функція ця називається, як можна здогадатися, array_sum (). І як параметр їй передається тільки ім'я масиву, суму значень елементів якого потрібно обчислити.

Як приклад використання цієї функції наведемо рішення більш складного завдання, ніж просто обчислення суми елементів. Цей приклад також ілюструє застосування функції array_slice (), яку ми здадали трохи раніше.

Приклад 16. Нехай дано масив натуральних чисел. Потрібно знайти в ньому таке число, що сума елементів праворуч від нього дорівнює сумі елементів зліва від нього.

<? Php 
// Масив задається функцією array 
$arr = array (2,1,3,4,5,6,4); 
// Перебираємо кожний елемент масиву $arr. 
// Для циклу поточний ключ масиву 
// Міститься у змінній $k, 
// Поточне значення - у змінній $ val 
foreach ($arr as $k => $val) { 
$р = $k + 1; 
// Синтаксис array array_slice ( 
// Array array, int offset [, int length]) 
// Array_slice виділяє підмасив 
// Довжини length в масиві array, 
// Починаючи з елемента offset. 
$оut_next = array_slice ($arr, $p); 
// Отримуємо масив елементів, 
// Що йдуть після поточного 
$оut_prev = array_slice ($arr, 0, $k); 
// Отримуємо масив елементів, 
// Що йдуть перед поточним 
// Функція mixed array_sum (array array) 
// Підраховує суму елементів масиву array 
$next_sum = array_sum ($out_next); 
$prev_sum = array_sum ($out_prev); 
// Якщо сума елементів до поточного дорівнює 
// Сумі елементів після, то виводимо 
// Значення поточного елемента 
if ($next_sum == $prev_sum) 
echo "value: $val"; 
// Можна подивитися, що представляють собою 
// Розглянуті масиви на кожному кроці 
// Print_r ($out_next); echo "<br>"; 
// Print_r ($out_prev); 
// Echo "$next_sum, $prev_sum <br>"; 
echo "<hr>"; 

?>

Робота з рядками

Ймовірно, читачі приблизно уявляють, що таке тип даних «рядок» і як створити змінну такого типу. В одній з перших лекцій ми приводили три способи задання рядків: за допомогою одинарних лапок, подвійних лапок і з допомогою heredoc-синтаксису. Відзначали ми й основні відмінності між цими способами. В основному вони стосуються обробки змінних і керуючих послідовностей всередині рядка.

Приклад 17. Способи задання рядків

<? Php 
echo 'У такому рядку НЕ обробляються 
змінні і більшість 
послідовностей '; 
echo "Тут змінні і послідовності 
обробляються "; 
echo <<<
Тут теж обробляються як змінні, 
так і керуючі послідовності. 
І крім того, можна вводити символи лапок 
без їх екранування зворотним слешем. 
EOT;
?>

Вже не раз, починаючи з самої першої лекції, ми використовували функцію echo. Насправді, echo - не функція, а мовна конструкція, тому використовувати при її виклику круглі дужки не обов'язково. Echo дозволяє виводити на екран рядки, передані їй в якості параметрів. Параметрів у echo може бути скільки завгодно. Їх поділяють комами або поєднують за допомогою оператора конкатенації і ніколи не розміщують в круглі дужки.

Приклад 18. Використання функції echo 

<? 
echo "Прийшов", "побачив", "переміг"; 
// Виведе рядок "Прийшов побачив переміг" 
// Багато хто воліє передавати кілька 
// Параметрів у echo за допомогою конкатенації 

echo "Прийшов". "Побачив". "Переміг"; 
// Теж виведе рядок 
// "Прийшов побачив переміг" 
echo ("Прийшов", "побачив", "переміг"); 
// Видасть помилку: unexpected ',' 
?>

Існує скорочений синтаксис для команди echo: 
<? = Рядок_для_виводу?>

Тут параметр рядок_для_виводу містить рядок, заданий будь-яким з відомих способів, який повинний бути виведений на екран.

Наприклад, такий скрипт виведе на екран червоним кольором "Мене звуть Вася":

<? $name = "Вася"?> 
<font color=red> Мене звуть <? = $name?> </ font>

Крім мовної конструкції echo існує ряд функцій для виводу рядків. Це в першу чергу функція print і її різновиду printf, sprintf і т.п.

Функція print дозволяє виводити на екран тільки один рядок і, як і echo, не може бути викликана за допомогою змінних функцій, оскільки є мовною конструкцією.

Функція print_r не відноситься до рядкових функцій, як можна було б подумати. Вона відображає інформацію про змінну в формі, зрозумілою користувачеві.

Функції sprintf і printf обробляють переданий їм рядок у відповідності із заданим форматом. Але про них ми говорити не будемо. А поговоримо про те, як можна здійснювати пошук в тексті, представленому у вигляді рядка.

Пошук елемента в рядку

Для того щоб визначити, чи входить даний підрядок до складу рядка, використовується функція strpos (). Синтаксис strpos () такий:

strpos (вихідний рядок, рядок для пошуку
[, З якого символу шукати])

Вона повертає позицію появи шуканого рядку у вхідному рядку або повертає логічне false, якщо входження не знайдено. Додатковий аргумент дозволяє задавати символ, починаючи з якого буде проводитися пошук. Крім логічного false ця функція може повертати і інші значення, які приводяться до false (наприклад, 0 або ""). Тому для того, щоб перевірити, чи знайдений шуканий рядок, рекомендують не використовувати оператор еквівалентності «===».

Приклад 19. Використання функції strpos ()

<? 
$str = "Ідея наносити дані на перфокарти 
і потім зчитувати та обробляти їх 
автоматично належала Джону Біллінгс, 
а її технічне рішення здійснив Герман 
Холлеріт. Перфокарта Холлеріта виявилася 
настільки вдалою, що без жодних змін 
проіснувала до наших днів. "; 
$pos = strpos ($str, "Холлеріт"); 
if ($pos! == false) echo "Шуканий рядок 
в позиції номер $pos "; 
else echo "Підрядок не знайдено"; 
/* Зауважимо, що ми перевіряємо значення 
$pos на еквівалентність з false. 
Інакше рядок, що знаходиться в першій позиції, 
не був би знайдений, тому що 0 
інтерпретується як false. */ 
?>

Якщо значення параметра рядок_для_пошука не є рядком, то воно перетвориться до цілого типу і розглядається як ASCII-код символу. Щоб отримати ASCII-код будь-якого символу в PHP, можна скористатися функцією ord ("символ")

Наприклад, якщо ми напишемо $pos = strpos ($str, 228); то інтерпретатор буде вважати, що ми шукаємо символ «д». Якщо додати цей рядок у наведений вище приклад і вивести результат, то отримаємо повідомлення, що шуканий рядок знайдений в позиції 1.

Функція, обернена за змістом ord, - це chr (код символу). Вона по ASCII-коду виводить символ, що відповідає цьому коду.

За допомогою функції strpos можна знайти номер тільки першої появи підрядка у заданому рядку. Природно, є функції, які дозволяють обчислити номер останньої появи підрядка у заданому рядку. Це функція strrpos (). Її синтаксис такий:

Strrpos (вихідний рядок, символ для пошуку)

На відміну від strpos () ця функція дозволяє знайти позицію останньої появи в рядку зазначеного символу.

Бувають ситуації, коли знати позицію, де знаходиться шуканий рядок, необов'язково, а потрібно просто отримати всі символи, які розташовані після входження цього рядка. Можна, звичайно, скористатися і наведеними вище функціями strpos () і strrpos (), але можна зробити і простіше - виділити підрядок з допомогою призначених саме для цього функцій.

Виділення підрядка

Функція strstr

Говорячи про виділення підрядка з рядка в мові PHP, в першу чергу варто відзначити функцію strstr ():

strstr (вихідний рядок, рядок для пошуку)

Вона знаходить першу появу підрядка і повертає підрядок, починаючи з цього підрядка до кінця початкового рядка.

Якщо рядок для пошуку не знайдено, то функція поверне false. Якщо рядок для пошуку не належить рядковому типу даних, то вона переводиться в ціле число і розглядається як код символу. Крім того, ця функція чутлива до регістру, тобто якщо ми будемо паралельно шукати входження слів «Ідея» та «ідея», то результати будуть різними. Замість strstr () можна використовувати абсолютно ідентичну їй функцію strchr ().

Приклад 20. Виділимо з рядка, що містить назву та автора дослідження, підрядок, що починається зі слова «Назва»:

<? 
$str = "Автор: Іванов Іван (<a 
href = mailto: van@mail.ru> написати лист </ a>), 
Назва: 'Дослідження мов 
програмування '"; 
echo "<b> Вихідний рядок: </ b>", $str; 
if (!strstr ($str, "Назва")) 
echo "Рядок не знайдено <br>"; 
else echo "<p> <b> Отриманий підрядок: </ b>", 
strstr ($str, "Назва"); ?>

У результаті отримаємо: 
Вихідний рядок: Автор: Іванов Іван 
(Написати лист), 
Назва: 'Дослідження мов 
програмування ' 
Отриманий підрядок: Назва: 
'Дослідження мов програмування'

Для реалізації регістронезалежного пошуку підрядка існує відповідний аналог цієї функції – функція stristr(вихідний рядок, шуканий рядок). Діє і використовується вона точно так само, як і strstr (), за винятком того, що регістр, в якому записані символи шуканого рядка, не грають ролі при пошуку.

Очевидно, що функція strstr () не надто часто використовується - на практиці рідко буває потрібно отримати підрядок, що починається з певного слова або рядка. Але в деяких випадках і вона може стати в нагоді. Крім того, в PHP є і більш зручні функції для пошуку входжень. Найбільш потужні з них, звичайно, пов'язані з регулярними виразами. Їх ми розглянемо в одній з наступних лекцій.

Функція substr

Іноді ми не знаємо, з яких символів починається шуканий рядок, але знаємо, наприклад, що починається він з п'ятого символу і закінчується за два символи до кінця початкового рядка. Як виділити підрядок за таким описом? Дуже просто, за допомогою функції substr (). Її синтаксис можна записати наступним чином

substr (вхідний рядок, 
позиція початкового символу [, довжина])

Ця функція повертає частину рядка, заданої параметрами довжини, починаючи з символу, зазначеного параметром позиція початкового символу. Позиція, з якої починається копіюватися підрядок, може бути як позитивним цілим числом, так і негативним. В останньому випадку відлік елементів проводиться з кінця рядка. Якщо параметр довжина опущений, то substr () повертає підрядок від зазначеного символу і до кінця початкового рядка. Довжина підрядка, що виділяється теж може бути задана негативним числом. Це означає, що вказане число символів відкидається з кінця рядка.

Приклад 21. Припустимо, у нас є фраза, виділена жирним шрифтом за допомогою тега <b> мови HTML. Ми хочемо отримати цю ж фразу, але в звичайному записі. Напишемо таку програму:

<? Php 
$word = "<b> Hello, world! </ B>"; 
echo $ word, "<br>"; 
$pure_str = substr ($word, 3, -4); 
/* Виділяємо підрядок, 
починаючи з 3-го символу, 
не включаючи 4 символи з кінця рядка */ 
echo $pure_str; 
?>

У результаті роботи цього скрипта одержимо: 
Hello, world! 
Hello, world!

Насправді вирішити таке завдання можна набагато простіше, за допомогою функції strip_tags:

strip_tags (рядок [, допустимі теги])

Ця функція повертає рядок, з якої вилучені всі html і php-теги. За допомогою додаткового аргументу можна задати теги, які не будуть видалені з рядка. Список з кількох тегів вводиться без будь-яких знаків роздільників. Функція видає попередження, якщо зустрічає неправильні або неповні теги.

Приклад 22. Використання функції strip_tags ()

<? Php 
$string = "<b> Bold text </ b> 
<i> Italic text </ i> "; 
$str = strip_tags ($string); 
// Видаляємо всі теги з рядка 
$ str1 = strip_tags ($string, '<b>'); 
// Видаляємо всі теги крім тега <b> 
$str2 = strip_tags ($string, '<i>'); 
// Видаляємо всі теги крім тегів <i> 
echo $str, "<br>", $str1, "<br>", $str2; 
?>

У результаті отримаємо: 
Bold text Italic text 
Bold text Italic text 
Bold text Italic text

Наведемо ще один приклад використання функції substr (). Припустимо, у нас є якесь повідомлення з привітанням і підписом автора. Ми хочемо видалити спочатку вітання, а потім і підпис, залишивши тільки змістовну частину повідомлення.

<? Php 
$text = "Привіт! Сьогодні ми вивчаємо роботу 
з рядками. Автор. "; 
$no_hello = substr ($text, 8); 
// Прибираємо привітання 
$content = substr ($text, 8, 45); 
// Те ж саме, що substr ($text, 8, -6). 
// Прибираємо підпис. 
echo $text, "<br>", $no_hello, 
"<br>", $content; 
?>

У результаті отримаємо: 
Привіт! Сьогодні ми вивчаємо роботу 
з рядками. Автор. 
Сьогодні ми вивчаємо роботу з рядками. Автор. 
Сьогодні ми вивчаємо роботу з рядками.

Якщо нам потрібно отримати один конкретний символ з рядка, знаючи його порядковий номер, то не слід задіяти функції типу substr. Можна скористатися більш простим синтаксисом - записуючи номер символу в фігурних дужках після імені рядкової змінної. У контексті попереднього прикладу букву «р», розташовану другою за рахунком, можна отримати так:

echo $text {1}; // виведе символ "р"

Зауважимо, що номером цього символу є число один, а не два, так як нумерація символів рядка починається з нуля.

Раз вже ми почали говорити про символи в рядку і їх нумерації, то мимоволі виникає питання, скільки всього символів в рядку і як це визначити. Кількість символів у рядку - це довжина рядка. Обчислити довжину рядка можна за допомогою функції strlen (рядок). Наприклад, довжина рядка «Розробка інформаційної моделі» обчислюється за допомогою команди: strlen ("Розробка інформаційної моделі"); і дорівнює 32 символам.

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

Заміна входження підрядка

Функція str_replace

Для заміни входження підрядка можна використовувати функцію str_replace (). Це проста і зручна функція, що дозволяє вирішувати безліч завдань, які потребують особливих тонкощів при виборі замінної підрядка. Для того щоб робити заміни з більш складними умовами, використовують механізм регулярних виразів і відповідні функції ereg_replace () і preg_replace (). Синтаксис функції str_replace () такий:

str_replace (шукане значення,  
значення для заміни, об'єкт)

Функція str_replace () шукає в даному об'єкті значення і заміняє його значенням, призначеним для заміни.

Чому ми говоримо тут не про рядки для пошуку і заміни на вихідний рядок, а і про значення об'єкт, в якому відбувається заміна? Справа в тому, що починаючи з PHP 4.0.5 будь-який аргумент цієї функції може бути масивом.

Якщо об'єкт, в якому проводиться пошук і заміна, є масивом, то ці дії виконуються для кожного елемента масиву і в результаті повертається новий масив.

Приклад 23. Використання функції str_replace ()

<? Php 
$greeting = array ("Привіт", "Привіт всім!", 
"Привіт, дорога!"); // Об'єкт 
$new_greet = str_replace ("Привіт", 
"Доброго ранку", $greeting); 
// Робимо заміну 
print_r ($new_greet); 
/* Отримаємо: Array ([0] => Добрий ранок 
[1] => Добрий ранок усім! 
[2] => Добрий ранок, дорога!) */ 
?>

Якщо шукане значення і значення для заміни - масиви, то береться по одному значенню з кожного масиву і проводиться їх пошук і заміна в об'єкті. Якщо значень для заміни менше, ніж значень для пошуку, то в якості нових значень використовується порожній рядок.

Приклад 24. Використання функції str_replace ().

<? Php 
$greeting = array ("Привіт", "Привіт всім!", 
"Привіт, дорога!", "Здрастуйте", 
"Здрастуйте, товариші", "Hi"); 
// Об'єкт 
$search = array ("Привіт", 
"Добрий день", "Hi"); 
// Значення, що будемо замінювати 
$replace = array ("Доброго ранку", 
"День добрий"); 
// Значення, якими будемо замінювати 
$new_greet = str_replace ($search, $replace, 
$greeting); 
// Робимо заміну 
print_r ($new_greet); 
// Виводимо отриманий масив 
?>

У результаті отримаємо такий масив: 
Array ( 
[0] => Добрий ранок 
[1] => Добрий ранок усім! 
[2] => Добрий ранок, кохана! 
[3] => День добрий 
[4] => День добрий, товариші 
[5] => )

Якщо значення для пошуку - масив, а значення для заміни - рядок, то цей рядок буде використаний для заміни всіх знайдених значень.

Приклад 25. Використання функції str_replace ().

<? Php 
$greeting = array ("Привіт", "Привіт всім!", 
"Привіт, дорога!", "Здрастуйте", 
"Здрастуйте, товариші"); 
// Об'єкт 
$search = array ("Привіт", "Здрастуйте"); 
// Значення, що будемо замінювати 
$replace = "День добрий"; 
// Значення, яким будемо замінювати 
$new_greet = str_replace ($search,
$replace, $ greeting); / / робимо заміну print_r ($new_greet); 
// Виводимо отриманий масив 
?>

Отримаємо: 
Array ( 
[0] => День добрий 
[1] => День добрий усім! 
[2] => День добрий, дорога! 
[3] => День добрий 
[4] => День добрий, товариші )

Функція str_replace () чутлива до регістру, але існує її регістронезалежний аналог – функція str_ireplace (). Однак ця функція підтримується не у всіх версіях PHP.

Функція substr_replace

Ця функція поєднує в собі властивості двох уже розглянутих нами функцій - функції str_replace () і substr (). Її синтаксис такий:

substr_replace (вихідний рядок,
рядок для заміни позиція початкового символу [, довжина])

Ця функція замінює частину рядка рядком, для заміни. Замінюється та частина рядка (тобто підрядок), яка починається з позиції, вказаної параметром позиція початкового символу. За допомогою додаткового аргументу довжина можна обмежити число замінних символів. Тобто, фактично, ми не вказуємо конкретно рядок, який потрібно замінити, ми тільки описуємо, де він знаходиться і, можливо, яку довжину має. У цьому відмінність функції substr_replace () від str_replace ().

Як і у випадку з функцією substr () аргументи позиції початкового символу і довжина можуть бути негативними. Якщо позиція початкового символу позитивна, то заміна відбувається, починаючи з цієї позиції щодо кінця рядка. Негативна довжина задає, скільки символів від кінця рядка не повинно бути замінено. Якщо довжина не вказується, то заміна відбувається до кінця рядка.

Приклад 26. Використання функції substr_replace ()

<? Php 
$text = "Мене звуть Вася."; 
echo "Вихідний рядок: $text <hr> \ n"; 
/* Наступні два рядки замінять весь 
вихідний рядок рядком 'А мене - Петя' * / 
echo substr_replace ($text, 'А мене - Петя',0). "<br> \ N"; 
echo substr_replace ($text, 'А мене - Петя',0, strlen ($ text)). "<br> \ N"; 
// Наступний рядок додасть слово 'Привіт! ' 
// У початок початкового рядка 
echo substr_replace ($text, 'Привіт!',0, 0). "<br> \ N"; 
// Наступні два рядки замінять ім'я Вася 
// На ім'я Іван у вихідному рядку 
echo substr_replace ($text, 'Іван', 11,-1). "<br> \ N"; 
echo substr_replace ($text, 'Іван', -5,-1). "<br> \ N"; 
?>

У результаті роботи цього скрипта одержимо: 
Вихідний рядок: Мене звуть Вася. 
------------------------------------------ 
А мене - Петя 
А мене - Петя 
Привіт! Мене звуть Вася. 
Мене звуть Іван. 
Мене звуть Іван

Поділ і з'єднання радка

Дуже корисні функції - функції розподілу рядка на частини і обернені до них. Чому дуже корисні? Наприклад, якщо ви динамічно генеруєте форму за бажанням користувача, можна запропонувати йому вводити елементи для створення списку вибору, розділяючи їх яким-небудь символом. І для того щоб обробити отриманий список значень, якраз і стане в нагоді вміння розбивати рядок на шматочки. Для реалізації такого розбиття в PHP можна використовувати кілька функцій:

explode (роздільник, вхідний рядок 
[, Максимальна кількість елементів])

split (шаблон, вхідний рядок 
[, Максимальна кількість елементів])

preg_split (шаблон, вхідний рядок
[, Максимальна кількість елементів 
[, опції]])

Останні дві функції працюють з регулярними виразами, тому в даній лекції ми їх розглядати не будемо. Розглянемо більш просту функцію - explode ().

Функція explode () ділить заданий рядок на підрядки, кожний з яких відділений від сусіднього з допомогою зазначеного роздільника, і повертає масив отриманих рядків. Якщо задано додатковий параметр Максимальна кількість елементів, то число елементів у масиві буде не більше цього параметра, в останній елемент записується весь залишок рядка. Якщо в якості роздільника вказана порожній рядок «""», то функція explode () поверне false. Якщо символу роздільника у вхідному рядку немає, то повертається вхідний рядок без змін.

Приклад 27. ми хочемо створити елемент форми - випадаючий список і значення для цього списку повинен ввести користувач, не знайомий з мовою html. Створимо таку форму:

<form action=exp.php> 
Введіть варіанти для вибору автора статті 
через двокрапку (":"):< br> 
<input type=text name=author size=40> 
<br> 
<input type=submit value=Створити елемент> 
</ Form>

Приклад 28. Використання функції explode (). Скрипт, який буде її обробляти (exp.php), може бути таким:

<? Php 
$str = $ _GET ["author"]; 
$names = explode (":",$ str); 
// Розбиваємо рядок введений, 
// Користувачем за допомогою ":" 
$s = "<select name=author>"; 
// Створюємо список, що випадає 
foreach ($ names as $ k => $ name) { 
$s .= "$name"; 
// Додаємо елементи до списку 

$s .= "</ select>"; 
echo $ s;
?>

У результаті, якщо ми введемо такий рядок у форму: 

то отримаємо такий випадаючий список: 

Крім поділу рядка на частини іноді, навпаки, виникає необхідність об'єднання кількох рядків в одне ціле. Існує функція для цього, називається implode ():

implode (string $glue, array $pieces)

Ця функція об'єднує елементи масиву з допомогою переданого їй об'єднуючого елементу (наприклад, коми). На відміну від функції explode (), порядок аргументів у функції implode () не має значення.

Приклад 27. Припустимо, ми зберігаємо ім'я, прізвище і по батькові людини окремо, а виводити їх на сторінці потрібно разом. Щоб з'єднати їх в один рядок, можна використовувати функцію implode ():

<? Php 
$data = array ("Іванов", "Іван", "Іванович"); 
$str = implode ("", $data); 
echo $str; 
?>

У результаті роботи цього скрипта отримаємо рядок: 
Іванов Іван Іванович

У функції implode () існує псевдонім - функція join (), тобто ці дві функції відрізняються лише іменами.

Рядки, що містять html-код

Досить часто ми працюємо з рядками, що містять html-теги. Якщо відобразити такий рядок в браузері за допомогою звичайних функцій відображення даних echo () або print (), то ми не побачимо самих html-тегів, а отримаємо відформатований у відповідності з цими тегами рядок. Браузер обробляє всі html-теги у відповідності зі стандартом мови HTML. Іноді нам потрібно бачити безпосередньо рядок, без обробки його браузером. Щоб цього досягти, потрібно перед тим, як виводити, застосувати до нього функцію htmlspecialchars ().

Функція htmlspecialchars (рядок [, стиль лапок [, кодування]]) переводить спеціальні символи, такі як «<», «>», «&», «" »,« '» в екранований вигляд для того щоб відобразити в браузері.

Додатковий аргумент стиль лапок визначає, як повинні інтерпретуватися подвійні та одинарні лапки. Він може мати одне з трьох значень: ENT_COMPAT, ENT_QUOTES, ENT_NOQUOTES. Константа ENT_COMPAT означає, що подвійні лапки повинні бути переведені в спецсимволи, а одинарні повинні залишитися без змін. ENT_QUOTES говорить, що повинні конвертуватися і подвійні та одинарні лапки, а ENT_NOQUOTES залишає і ті й інші лапки без змін.

У пункті кодування можуть бути задані такі кодування, як UTF-8, ISO-8859-1 та інші (кириличні кодування також підтримуються).

Приклад 29. Використання функції htmlspecialchars ()

<? Php 
$new = htmlspecialchars ("<a 
href = 'mailto: au@mail.ru'> 
Написати листа </ a> ", ENT_QUOTES); 
echo $ new; 

/* Наш рядок перекодовується в такий: 
<a href='mailto:au@mail.ru'> 
Написати листа </ a> */

У браузері ми побачимо: 
<a href='mailto:au@mail.ru'> 
Написати листа </ a>

Функція htmlspecialchars () перекодує тільки найбільш часто використовувані спецсимволи. Якщо необхідно конвертувати всі символи структури HTML, слід задіяти функцію htmlentities (). Кириличні літери при використанні цієї функції теж кодуються спеціальними послідовностями. Наприклад, літера «А» замінюється комбінацією «A». Її синтаксис і принцип дії аналогічний синтаксису і принципом дії htmlspecialchars ().

Робота з файловою системою

Створення файлу

Функція fopen

Взагалі кажучи, в PHP не існує функції, призначеної саме для створення файлів. Більшість функцій працюють з вже існуючими файлами в файловій системі сервера. Є кілька функцій, які дозволяють створювати тимчасові файли, або, що те ж саме, файли з унікальним для поточної директорії імені. А от для того, щоб створити самий звичайний файл, потрібно скористатися функцією, яка відкриває локальний або віддалений файл. Називається ця функція fopen (). Що значить «відкриває файл»? Це означає, що fopen пов'язує цей файл з потоком управління програми. Причому зв'язування буває різним в залежності від того, що ми хочемо робити з цим файлом: читати його, записувати в нього дані або робити і те й інше. Синтаксис цієї функції такий:

resource fopen (ім'я_файлу, тип_доступу 
[, Use_include_path])

У результаті роботи ця функція повертає покажчик (типу ресурс) на відкритий нею файл. В якості параметрів цієї функції передаються: ім'я файлу, який потрібно відкрити, тип доступу до файлу (визначається тим, що ми збираємося робити з ним) і параметр, що визначає, чи шукати вказаний файл у include_path. Є ще один параметр, але про нього ми говорити не будемо, щоб не ускладнювати виклад. Обговоримо докладніше кожен з цих трьох параметрів.

Параметр ім'я_файлу повинен бути рядком, що містить правильне локальне ім'я файлу або URL-адресу файлу в мережі. Якщо ім'я файлу починається з вказівки протоколу доступу (наприклад, http:// ... або ftp:// ...), то інтерпретатор вважає це ім'я адресою URL і шукає обробник зазначеного в URL протоколу. Якщо обробник знайдений, то PHP перевіряє, чи дозволено працювати з об'єктами URL як зі звичайними файлами (директива allow_url_fopen). Якщо allow_url_fopen = off, то функція fopen викликає помилку і генерується попередження. Якщо ім'я файлу не починається з протоколу, то вважається, що зазначено ім'я локального файлу. Для відкриття локального файлу, потрібно, щоб PHP мав відповідні права доступу до цього файлу.

Параметр use_include_path, встановлений в значення 1 або TRUE, змушує інтерпретатор шукати зазначений в fopen () файл у include_path. Нагадаємо, що include_path - це директива з файлу налаштувань PHP, що задає список директорій, в яких можуть знаходитися файли для включення. Крім функції fopen () вона використовується функціями include () і require ().Параметр use_include_path, встановлений в значення 1 або TRUE, змушує інтерпретатор шукати зазначений у fopen () файл у include_path. Нагадаємо, що include_path - це директива з файлу налаштувань PHP, що задає список директорій, в яких можуть знаходитися файли для включення. Крім функції fopen () вона використовується функціями include () і require ().

Параметр тип_доступу може приймати одне з наступних значень:

Тип доступу

Опис

r

Відкриває файл тільки для читання; встановлює вказівник позиції у файлі на початок файлу.

r +

Відкриває файл для читання і запису; встановлює вказівник файлу на його початок.

w

Відкриває файл тільки для запису; встановлює вказівник файлу на його початок і обрізає файл до нульової довжини. Якщо файл не існує, то намагається створити його.

w +

Відкриває файл для читання і запису; встановлює вказівник файлу на його початок і обрізає файл до нульової довжини. Якщо файл не існує, то намагається створити його.

a

Відкриває файл тільки для запису; встановлює вказівник файлу в його кінець. Якщо файл не існує, то намагається створити його.

a +

Відкриває файл для читання і запису; встановлює вказівник файлу в його кінець. Якщо файл не існує, то намагається створити його.

x

Створює і відкриває файл тільки для запису; поміщає вказівник файлу на його початок. Якщо файл вже існує, то fopen () повертає false і генерується попередження. Якщо файл не існує, то робиться спроба створити його. Цей тип доступу підтримується починаючи з версії PHP 4.3.2 і працює тільки з локальними файлами.

x +

Створює і відкриває файл для читання і запису; поміщає вказівник файлу на його початок. Якщо файл вже існує, то fopen () повертає false і генерується попередження. Якщо файл не існує, то робиться спроба створити його. Цей тип доступу підтримується, починаючи з версії PHP 4.3.2, і працює тільки з локальними файлами.

Отже, щоб створити файл, потрібно, як би безглуздо це не звучало, відкрити неіснуючий файл на запис.

Приклад 30. Використання функції fopen ()

<? Php 
$h = fopen ("my_file.html", "w"); 
/* Відкриває на запис файл my_file.html, 
якщо він існує, або створює порожній 
файл з таким ім'ям, якщо його ще немає */ 
$h = fopen ("dir / another_file.txt", "w +"); 
/* Відкриває на запис і читання або створює 
файл another_file.txt в директорії dir */ 
$h = fopen ("Http://www.server.ru/dir/file.php", "r"); 
/* Відкриває на читання файл, що знаходиться за 
вказаною адресою */ 
?>

Створюючи файл, потрібно враховувати, під якою операційною системою ви працюєте, і під яку ОС імовірно цей файл буде використовуватись. Справа в тому, що різні операційні системи по-різному позначають кінець рядка. У Unix-подібних ОС кінець рядка позначається \ n, в системах типу Windows - \ r \ n. Windows пропонує спеціальний параметр t для перетворення символів кінця рядка систем типу Unix в свої символи кінця рядка. На противагу цьому існує опція b, використовується найчастіше для бінарних файлів, завдяки чому такої трансляції не відбувається. Використовувати ці прапори можна, просто дописавши їх після останнього символу обраного типу доступу до файлу. Наприклад, відкриваючи файл на читання, замість r слід використовувати rt, щоб перекодувати всі символи кінця рядка в \ r \ n. Якщо не використовувати прапор b при відкритті бінарних файлів, то можуть з'являтися помилки, пов'язані зі зміною вмісту файлу. З міркувань переносимості програми на різні платформи рекомендується завжди використовувати прапор b при відкритті файлів за допомогою fopen ().

Що відбувається, якщо відкрити або створити файл за допомогою fopen не вдається? У цьому випадку PHP генерує попередження, а функція fopen повертає як результат своєї роботи значення false. Такого роду попередження можна «придушити» (заборонити) за допомогою символу @.

Наприклад, така команда не виведе попередження, навіть якщо відкрити файл не вдалося:

$h = @ fopen ("dir / another_file.txt", "w +");

Таким чином, функція fopen () дозволяє створити тільки лише порожній файл і зробити його доступним для запису. Як же записати дані в цей файл? Як прочитати дані з вже існуючого файлу?

Перш ніж відповісти на ці запитання, розглянемо, як закрити встановлене з допомогою fopen () з'єднання.

Закриття з'єднання з файлом

Після виконання необхідних дій з файлом, будь то читання або запис даних або що-небудь інше, з'єднання, встановлене з цим файлом функцією fopen (), потрібно закрити. Для цього використовують функцію fclose (). Синтаксис у неї наступний:

fclose (покажчик на файл)

Ця функція повертає TRUE, якщо з'єднання успішно закрито, і FALSE - у зворотному випадку. Аргумент цієї функції повинен вказувати на файл, успішно відкритий, наприклад, за допомогою функції fopen ().

Приклад 31. Використання функції fclose ()

<? Php 
$h = fopen ("my_file.html", "w"); 
fclose ($ h);
?>

Звичайно, якщо не закривати з'єднання з файлом, ніяких помилок виконання скрипта не відбудеться. Але в цілому для сервера це може мати серйозні наслідки. Наприклад, хакер може скористатися відкритим з'єднанням і записати в файл вірус, не кажучи вже про зайві витрати ресурсів сервера. Тож радимо завжди закривати з'єднання з файлом після виконання необхідних дій.

Запис даних у файл

Функція fwrite

Для того щоб записати дані у файл, доступ до якого відкритий функцією fopen (), можна використовувати функцію fwrite (). Синтаксис у неї наступний:

int fwrite (покажчик на файл, 
рядок [, довжина])

Ця функція записує рядок у файл, на який вказує покажчик на файл. Якщо вказаний додатковий аргумент довжина, то запис закінчується після того, як записано кількість символів, рівне значенню цього аргументу, або коли буде досягнуто кінець рядка.

У результаті своєї роботи функція fwrite () повертає число записаних байтів або false, у разі помилки.

Приклад 31. Нехай у нашій робочій директорії немає файлу my_file.html. Створимо його і запишемо в нього рядок тексту:

<? Php 
$h = fopen ("my_file.html", "w"); 
$text = "Цей текст запишемо у файл."; 
if (fwrite ($ h, $ text)) 
echo "Запис пройшов успішно"; 
else 
echo "Сталася помилка під час запису даних"; 
fclose ($ h); 
?>

У результаті роботи цього скрипта в браузері ми побачимо повідомлення про те, що запис пройшов успішно, а у файлі my_file.html з'явиться рядок "Цей текст запишемо у файл.". Якщо б цей файл існував до того, як ми виконали цей скрипт, що всі дані в ньому були б видалені.

Якщо ж ми напишемо такий скрипт:

<? Php 
$h = fopen ("my_file.html", "a"); 
$add_text = "Додамо текст у файл."; 
if (fwrite ($ h, $ add_text, 7)) 
echo "Додавання тексту пройшло 
успішно <br> "; 
else echo "Сталася помилка при 
додаванні даних <br> "; 
fclose ($h); 
?>

то до рядка, що вже існує у файлі my_file.html, додасться ще сім символів з рядка, що міститься у змінній $ add_text, тобто слово «Додамо»

Функція fwrite () має псевдонім fputs (), використовуваний таким же чином, що і сама функція.

Далі ми розглянемо, які методи зчитуння даних пропонує мова PHP.

Читання даних з файлу

Якщо ми хочемо прочитати дані з існуючих файлів, однієї функції fopen (), як і у випадку з записом даних, недостатньо. Вона лише повертає покажчик на відкритий файл, але не зчитує ні одного рядка з цього файлу. Тому для того, щоб прочитати дані з файлу, потрібно скористатися однією із спеціальних функцій: file, readfile, file_get_contents, fread, fgets і т.п.

Функція fread

Ця функція здійснює читання даних з файлу. Її можна використовувати і для читання даних з бінарних файлів, не побоюючись їх пошкодження. Синтаксис fread () такий: 

string fread (покажчик на файл, довжина)

При виклику цієї функції відбувається читання даних довжини (у байтах), визначеної параметром довжина, з файлу, на який вказує покажчик на файл. Параметр покажчик на файл повинен бути реально існуючої змінної типу ресурс, що містить у собі зв'язок з файлом, відкритий, наприклад, за допомогою функції fopen (). Читання даних відбувається до тих пір, поки не зустрінеться кінець файлу або поки не буде прочитано зазначене параметром довжина число байтів.

У результаті роботи функція fread () повертає рядок із зчитаної з файлу інформації.

Як ви помітили, у цій функції параметр довжина - обов'язковий. Отже, якщо ми хочемо зчитати весь файл в рядок, потрібно знати його довжину. PHP може самостійно обчислити довжину зазначеного файлу. Для цього потрібно скористатися функцією filesize (ім'я файлу). У випадку помилки ця функція поверне false. На жаль, її можна використовувати тільки для отримання розміру локальних файлів.

Приклад 32. Прочитаємо вміст файлу my_file.html

<? Php 
$h = fopen ("my_file.html", "r +"); 
// Відкриваємо файл на запис і читання 
$content = fread ($h,filesize ("my_file.html")); 
// Зчитуємо вміст файлу в рядок 
fclose ($h); / / закриваємо з'єднання з файлом 
echo $content; 
// Виводимо вміст файлу 
// На екран браузера 
?>

Для того щоб вирахувати вміст бінарного файлу, наприклад, зображення, в таких системах, як Windows, рекомендується відкрити файл з допомогою прапора rb або йому подібних, що містять символ b в кінці.

Функція filesize () кешує результати своєї роботи. Якщо змінити вміст файлу my_file.html і знову запустити наведений вище скрипт, то результат його роботи не зміниться. Більш того, якщо запустити скрипт, що зчитує дані з цього файлу з допомогою іншої функції (наприклад, fgetss), то результат може виявитися таким, як якби файл не змінився. Щоб цього уникнути, потрібно очистити статичний кеш, додавши в код програми команду clearstatcache ();

Функція fgets

За допомогою функції fgets () можна зчитати з файлу рядок тексту. Синтаксис цієї функції практично такий же, як і у fread (), за винятком того, що довжину зчитуваного рядка вказувати необов'язково:

string fgets (покажчик на файл [, довжина])

У результаті роботи функція fgets () повертає рядок довжиною (довжина-1) байт з файлу, на який вказує покажчик на файл. Читання закінчується, якщо прочитано (довжина-1) символів або зустрівся символ переходу рядка або кінець файлу. Нагадаємо, що в PHP один символ - це один байт. Якщо довжина, рядка не зазначена (дана можливість з'явилася починаючи з PHP 4.2.0), то зчитується 1 Кбайт (1024 байт) тексту або, що те ж саме, 1024 символів. Починаючи з версії PHP 4.3, якщо параметр довжина не заданий, зчитується рядок цілком. У випадку помилки функція fgets () повертає false. Для версій PHP починаючи з 4.3 ця функція безпечна для двійкових файлів.

Приклад 31. Використання функції fgets ()

<? Php 
$h = fopen ("my_file.html", "r +"); 
$content = fgets ($ h, 2); 
// Вважає перший символ з 
// Першого рядка файлу my_file.html 
fclose ($h); 
echo $content; 
?>

Обидві функції, fread () і fgets (), припиняють зчитування даних з файлу, якщо зустрічають кінець файлу. У PHP є спеціальна функція, що перевіряє, чи дивиться покажчик позиції файлу на кінець. Це булева функція feof (), як параметр передається покажчик на з'єднання з файлом.

Наприклад, ось так можна вважати всі рядки файлу my_file.html:

<? Php 
$h = fopen ("my_file.html", "r"); 
while (! feof ($h)) { 
$content = fgets ($ h); 
echo $content, "<br>"; 

fclose ($h); 
?>

Функція fgetss

Існує різновид функції fgets () - функція fgetss (). Вона теж дозволяє зчитувати рядок із зазначеного файлу, але при цьому видаляє з нього всі html-теги, за винятком, деяких. Синтаксис fgetss () такий:

string fgetss (покажчик на файл, 
довжина [, допустимі теги])

Зверніть увагу, що тут аргумент довжина обов'язковий.

Приклад 32. Нехай у нас є файл my_file.html наступного змісту:

<h1> Без праці не виймеш і рибку зі ставка. </ h1> 
<b> Тихіше їдеш - далі будеш </ b> У семи няньок <i> дитя без ока </ i>.

Виведемо на екран всі рядки файлу my_file.html, видаливши з них всі теги, крім <b> і <i>:

<? Php 
$h = fopen ("my_file.html", "r"); 
while (! feof ($ h)) { 
$content = fgetss ($ h, 1024, '<b> <i>' ); 
echo $ content, "<br>"; 

fclose ($h); 
?> 
 

У результаті роботи цього скрипта одержимо: 
Без праці не виймеш і рибку зі ставка. 
Тихіше їдеш - далі будеш У семи няньок дитя без ока.

Функція fgetc

Якщо можна зчитувати інформацію з файлу порядково, то можна зчитувати її і посимвольно. Для цього призначена функція fgetc (). Легко здогадатися, що синтаксис у неї наступний:

string fgetc (покажчик на файл)

Ця функція повертає символ з файлу, на який посилається вказівник на файл, і значення еквівалентне FALSE, якщо зустрінутий кінець рядка.

Ось так, наприклад, можна зчитати файл по одному символу:

<? Php 
$h = fopen ("my_file.html", "r"); 
while (! feof ($h)) { 
$ content = fgetc ($h); 
echo $content, "<br>"; 

fclose ($h); 
?>

Насправді для того щоб прочитати вміст файлу, відкривати з'єднання з ним за допомогою функції fopen () зовсім не обов'язково. У PHP є функції, які дозволяють робити це, використовуючи лише ім'я файлу. Це функції readfile (), file () і file_get_contents (). Розглянемо кожну з них детальніше.

Функція readfile

Синтаксис: 
int readfile (ім'я_файлу 
[, Use_include_path])

Функція readfile () зчитує файл, ім'я якого передано їй як параметр ім'я_файлу, і виводить його вміст на екран. Якщо додатковий аргумент use_include_path має значення TRUE, то пошук файлу з заданим ім'ям виконується і по директоріях, що входять в include_path.

У програму ця функція повертає число лічених байтів (символів) файлу, а в разі помилки - FALSE. Повідомлення про помилку в цій функції можна придушити оператором @.

Приклад 33. Використання функції readfile (). Наступний скрипт виведе на екран вміст файлу my_file1.html і розмір цього файлу, якщо він існує. В іншому випадку виведеться наше повідомлення про помилку - рядок "Error in readfile".

<? Php 
$n = @ readfile ("my_file1.html"); 
/* Виводить на екран вміст файлу і 
записує його розмір у змінну $n * / 
if (! $n) echo "Error in readfile"; 
/* Якщо функція readfile () виконалася 
з помилкою, то $n = false і виводимо 
повідомлення про помилку */ 
else echo $n; 
// Якщо помилки не було, то виводимо число 
// Лічених символів 
?>

За допомогою функції readfile () можна читати вміст віддалених файлів, вказуючи їх URL-адресу в якості імені файлу, якщо ця опція не відключена в налаштуваннях сервера.

Відразу ж виводити вміст файла на екран не завжди зручно. Часом потрібно записати інформацію з файлу в змінну, щоб надалі зробити з нею будь-які дії. Для цього можна використовувати функцію file () або file_get_contents ().

Функція file

Функція file () призначена для зчитування інформації з файлу в змінну типу масив. Синтаксис у неї такий же, як і у функції readfile (), за винятком того, що в результаті роботи вона повертає масив:

array file (ім'я_файлу 
[, Use_include_path])

Що за масив повертає ця функція? Кожен елемент даного масиву є рядком у файлі, інформацію з якого ми зчитуємо (його ім'я задано аргументом ім'я_файлу). Символ нового рядка теж включається в кожен з елементів масиву. У випадку помилки функція file (), як і всі вже розглянуті, повертає false. Додатковий аргумент use_include_path знову ж таки визначає, шукати чи ні даний файл в директоріях include_path. Відкривати віддалені файли за допомогою цієї функції теж можна, якщо не заборонено сервером. Починаючи з PHP 4.3 робота з бінарними файлами за допомогою цієї функції стала безпечною.

Наприклад, у нас є файл my_file.html наступного змісту:

<h1> Без праці не виймеш 
і рибку зі ставка. </ h1> 
<b> Тихіше їдеш - далі будеш </ b>

Прочитаємо його вміст за допомогою функції file ():

<? Php 
$arr = file ("my_file.html"); 
foreach ($arr as $i => $ a) echo $i, ":", 
htmlspecialchars ($a), "<br>"; 
?>

У результаті на екран буде виведено наступне повідомлення:

0: <h1> Без праці не виймеш 
і рибку зі ставка. </ h1> 
1: <b> Тихіше їдеш - далі будеш </ b>

Функція file_get_contents

У версіях PHP починаючи з 4.3 з'явилася можливість зчитувати вміст файлу в рядок. Робиться це за допомогою функції file_get_contents (). Як і дві попередні функції, як параметри вона приймає значення імені файлу і вказівку шукати чи ні, його в директоріях include_path. Для порядку все одно наведемо її синтаксис:

string file_get_contents ( 
ім'я_файлу [, use_include_path])

Ця функція абсолютно ідентична функції file (), тільки повертає вона вміст файлу у вигляді рядка. Крім того, вона безпечна для обробки бінарних даних і може зчитувати інформацію з віддалених файлів, якщо це не заборонено налаштуваннями сервера. 

Перевірка існування файлу

Отже, створювати файл ми навчилися, записувати дані в нього - навчилися, зчитувати дані з файлу - теж навчилися. Але от питання: а що якщо файл, з яким ми намагаємося виконати всі ці операції, не існує? Або він недоступний для читання або запису? Очевидно, що в такому разі жодна з вивчених нами функцій працювати не буде і PHP видасть повідомлення про помилку. Щоб відстежувати такого роду помилки, можна використовувати функції file_exists (), is_writable (), is_readable ().

Функція file_exists

Синтаксис: 
bool file_exists (ім'я файлу або директорії)

Функція file_exists () перевіряє, чи існує файл або директорія, ім'я якої передано їй як аргумент. Якщо директорія або файл у файловій системі сервера існує, то функція повертає TRUE, в іншому випадку - FALSE. Результат роботи цієї функції кешується. Відповідно очистити кеш можна, як уже зазначалося, за допомогою функції clearstatcache (). Для нелокальних файлів використовувати функцію file_exists () не можна.

Приклад 34. Використання функції file_exists ()

<? Php 
$filename = 'c: / users / files / my_file.html'; 
if (file_exists ($ filename)) { 
print "Файл <b> $ filename </ b> існує"; 
} Else { 
print "Файл <b> $ filename </ b>НЕ існує "; 

?>

Функція is_writable Якщо крім перевірки існування файлу потрібно дізнатися ще, чи дозволено записувати інформацію в цей файл, слід використовувати функцію is_writable () або її псевдонім - функцію is_writeable().

Синтаксис: 
bool is_writable (ім'я файлу або директорії)

Ця функція повертає TRUE, якщо файл (або директорія) існує і доступний для запису. Доступ до файлу здійснюється під тим обліковим записом користувача, під яким працює сервер (найчастіше це користувач nobody або www). Результати роботи функції is_writable кешуються.

Функція is_readable Якщо крім перевірки існування файлу потрібно дізнатися ще, чи дозволено читати інформацію з нього, потрібно використовувати функцію is_readable (). Синтаксис: bool is_readable (ім'я файлу) Ця функція працює подібно до функції is_writable ().

Приклад 34. Використання функції is_readable ()

<? Php 
$filename = 'c: / users / files / my_file.html'; 
if (is_readable ($filename)) { 
print "Файл <b> $filename </ b> існуєі доступний для читання "; 
} Else { 
print "Файл <b> $filename </ b>НЕ існує або 
НЕ доступний для читання "; 

?>

Видалення файлу

Останнє, що ми хочемо вивчити з дій над файлами, - це видалення файлів. Для того щоб видалити файл за допомогою мови PHP, потрібно скористатися функцією unlink (). Синтаксис цієї функції можна описати таким чином:

bool unlink (ім'я_файлу)

Ця функція видаляє файл, який має ім'я ім'я_файлу, повертає TRUE у разі успіху цієї операції і FALSE - у разі помилки. Щоб видалити файл, потрібно теж мати відповідні права доступу до нього (наприклад, доступу тільки на читання для видалення файлу недостатньо).

Приклад 35. Використання функції unlink ()

<?Php 
$filename = 'c: / users / files / my_file.html'; 
unlink ($ filename); 
// Видаляємо файл з ім'ям 
// C: / users / files / my_file.html
?>

Завантаження файлу на сервер

Тепер вирішимо більш складне і часто, виникаюче на практиці завдання завантаження файлу на сервер. Перше, що потрібно зробити, щоб завантажити файл на сервер, це створити html-форму. Для того щоб за допомогою цієї форми можна було завантажувати файли, вона повинна містити атрибут enctype в тезі form зі значенням multipart / form-data, а також елемент input типу file.

Приклад 36. Форма для завантаження файлу на сервер

<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>

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

Приклад форми для завантаження файлу на сервер

Тепер потрібно написати скрипт, який буде обробляти отриманий файл.

Вся інформація про завантажений на сервер файл міститься в глобальному масиві $_FILES. Цей масив з'явився починаючи з PHP 4.1.0. Якщо включена директива register_globals, то значення переданих змінних доступні просто за їхніми іменами.

Якщо ми завантажили з комп'ютера-клієнта файл з ім'ям critics.htm розміром 15136 байт, то скрипт з єдиною командою print_r ($_FILES); виведе на екран наступне:

Array ([myfile] => 
Array ([name] => critics.htm 
[Type] => text / html 
[Tmp_name] => C: \ WINDOWS \ TEMP \ php49F.tmp 
[Error] => 0 
[Size] => 15136
) )

Взагалі кажучи, масив $_FILES завжди має такі елементи:

  • $_FILES ['myfile'] ['name'] - ім'я, яке мав файл на машині клієнта.
  • $_FILES ['myfile'] ['type'] - mime-тип відправленого файлу, якщо браузер надав цю інформацію. У нашому прикладі це text / html.
  • $_FILES ['myfile'] ['size'] - розмір завантаженого файлу в байтах.
  • $_FILES ['myfile'] ['tmp_name'] - тимчасове ім'я файлу, під яким він був збережений на сервері.
  • $_FILES ['myfile'] ['error'] - код помилки, що з'являється при завантаженні.

Тут 'myfile' - це ім'я елемента форми, за допомогою якого проведено завантаження файлу на сервер. Тобто воно може бути іншим, якщо елемент форми назвати інакше. Але от інші ключі (name, type і т. д.) залишаються незмінними для будь-якої форми.

Якщо register_globals = On, то доступні також додаткові змінні, такі як $ myfile_name, яка еквівалентна $_FILES ['myfile'] ['name'], і т.п.

Помилок при завантаженні в PHP виділяють п'ять типів і відповідно $ _FILES ['myfile'] ['error'] може мати п'ять значень:

0 - помилки не сталося, файл завантажений успішно

1 - завантаження перевищує розмір, встановлений директивою upload_max_filesize у файлі php.ini

2 - завантаження перевищує розмір, встановлений елементом MAX_FILE_SIZE форми html

3 - файл був завантажений частково

4 - файл завантажений не був

За замовчуванням завантажені файли зберігаються в тимчасовій директорії сервера, якщо інша директорія не вказана за допомогою опції upload_tmp_dir у файлі налаштувань php.ini. Перемістити завантажений файл в потрібну директорію можна за допомогою функції move_uploaded_file ().

Функція move_uploaded_file () має наступний синтаксис:

bool move_uploaded_file (тимчасове_імя_файла, 
місце_призначення)

Ця функція перевіряє, чи дійсно файл, позначений рядком тимчасове_імя_файла, був завантажений через механізм завантаження HTTP методом POST. Якщо це так, то файл буде перенесено в файл, заданий параметром місце_призначення (цей параметр містить як шлях до нової директорії для збереження, так і нове ім'я файлу).

Якщо тимчасове_імя_файла задає неправильний завантажений файл, то ніяких дій зроблено не буде, і move_uploaded_file () поверне FALSE. Те ж саме станеться, якщо файл з якихось причин не може бути переміщений. У цьому випадку інтерпретатор виведе відповідне попередження. Якщо файл, заданий параметром місце_призначення, існує, то функція move_uploaded_file () перезапише його.

Приклад 37. Програма завантаження файлу на сервер

<? 
/* У версіях PHP, раніших, 
ніж 4.1.0, замість масиву 
$_FILES Потрібно використовувати 
масив $ HTTP_POST_FILES */ 

$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. Точніше, в прикладах використовуватися будуть лише найчастіші з них, так як повний список найпростіше знайти на офіційному сайті, разом з докладними описами.

Математичні функції оперують змінними чисельних типів. Це означає, що операндами будуть змінні типу int і float.

Розділемо ці функції на кілька типів:

0. Загальні функції 
1. Тригонометричні функції 
2. Зворотні тригонометричні функції 
3. Логарифмічні функції 
4. Статистичні функції 
5. Функції перетворення основ чисел 
6. Решта (які важко класифікувати)

Загальні функції

До загальних функцій відносяться:

abs 
floor 
ceil 
max 
min 
round 
rand 
sqrt

Опишемо їх більш докладно.

Abs

Синтаксис: 
number abs (mixed number)

Функція обчислює модуль числа. Нагадаю, що | x | = x, якщо x> 0 або x = 0, і | x | =- x, якщо x <0.

Floor

Синтаксис: 
float floor (float value)

Ця функція округляє дріб в меншу сторону. Але не варто думати, що це - "відкидання" дробової частини. Тому що, по-перше, результат все одно буде не цілочисловим, а дійсним. До того ж для негативних чисел найближчим меншим цілим числом буде дріб, доповнений до нього.

Ceil

Синтаксис: 
float ceil (float value)

Ця функція також округлює аргумент до найближчого цілого, але вже до найближчого більшого цілого. Функції floor і ceil повертають дійсний результат з однієї простої причини - діапазон дійсних чисел в PHP більше, ніж цілих.

Max

Синтаксис: 
mixed max (number arg1, number arg2 [, number ...]) 
mixed max (array numbers)

Ця функція має 2 різновиди синтаксису. Вона повертає максимальне значення серед аргументів, якщо вони передані у вигляді повного списку (1-й варіант синтаксису), або ж найбільший елемент масиву, у разі, якщо був переданий масив (2-й варіант синтаксису). Цікаво те що: аргументи можуть бути різних типів. Наприклад:

< ? PHP 
$test = max ('рядок', array (0, 1), 4, 7); 
// Повернеться array (0, 1) - масив завжди вважається більшим, хоча таке "порівняння" виглядає досить безглуздо
?>

Повністю аналогічна функція min, її не будемо описувати. Різниця в тому, що повертається мінімум.

Round

Синтаксис: 
float round (float val [, int precision])

Округлює дійсне число за арифметичними правилами. Можна вказати точність заокруглення. У цьому випадку буде вестися округлення до вказаного числа знаків дробу. Цю точність можна вказати рівною 0 (рівносильно викликом функції без вказівки точності). Крім цього, можна вказати і негативне значення точності. Результат аналогічний.

Rand

Синтаксису: 
int rand ([int min, int max])

Повертає випадкове ціле число в діапазоні від min до max включно. Ці параметри не обов'язкові. Якщо їх не вказувати, повернеться випадкове число в діапазоні від 0 до константи RAND_MAX.

На операційних системах сімейства Windows значення RAND_MAX всього лише 32767

Якщо потрібно випадкове дробове число, то можна скористатися, наприклад, таким кодом:

<? PHP 
// Генеруємо випадкове дійсне число в діапазоні $a.. $b припущенні $ a <$ b 
$iMaxRand = 30000; // по суті, можна задавати і більше для більшої точності 
$iRand = rand (1, $iMaxRand); 
$fRand = $ a + ($b-$a) * $iRand / $iMaxRand; 
?>

Sqrt

Синтаксис: 
float sqrt (float arg)

Функція обчислює квадратний корінь аргументу. І аргумент і результат - дійсні.

Тригонометричні і зворотні тригонометричним функції

До тригонометричним функціям я відніс функції:

acos 
acosh 
asin 
asinh 
atan2 
atan 
atanh 
cos 
cosh 
sin 
sinh 
tan 
tanh

Всі ці функції приймають в якості аргументу параметри типу float, і повертають значення цього ж типу. Всі описи даних функції приводитися не будуть, так як призначення цих функцій відомо з геометрії та алгебри).

Acos

Синтаксис: 
float acos (float arg)

Обчислює арккосинус числа. У разі, якщо аргумент неприпустимий (тобто | arg |> 1), повертає NAN.

Логарифмічні функції

До логарифмічним функцій я відніс функції:

log10 
log1p 
log

Ці функції також не вимагають окремого опису. Окремо відмітимо лише функцію log1p. Справа в тому, що, в силу особливості самого логарифма, при значеннях аргументу, близького до 1, він сильно прямує до нуля. Це може бути перешкодою в "тонких" обчисленнях. Ця функція обчислює значення більш точним способом.

Окрім іншого, наведемо приклад корисної функції, яка обчислює логарифм з довільною основою:

<? PHP 
function Log ($base, $arg) 

if ($base == 1 | | $base <= 0) 

return null; 

if ($arg <= 0) 

return null; 

return log ($arg) / log ($base); 
}
?>

Статистичні функці

Перейдемо до статистичних функцій:
exp 
expm1 
pow

Аналогічно логарифмам, окремо слід звернути увагу лише на expm1, що повертає точно обчислену степінь аргументу, близького до 0.

Функції перетворення основ чисел

У php є спеціальний ряд функцій, які працюють з перетворенням систем числення. Якщо врахувати, що bin - двійкова система, oct - вісімкова, dec - десяткова, а hex – шіснадцяткова, то призначення багатьох з них стає інтуїтивно зрозумілим:

base_convert 
bindec 
decbin 
dechex 
decoct 
hexdec 
octdec

Інтерес представляє функція base_convert:

Синтаксис: 
string base_convert (string number, int frombase, int tobase)

Повертає рядок, що містить число number, записане в основі tobase. Основа, в якій number подається, вказується в frombase. І frombase, і tobase повинні бути в діапазоні від 2 до 36 включно. Чому таке обмеження? Та тому, що цифри, більше 10, записуються за допомогою символів латинського алфавіту. Тобто від a до z. Разом з першими 9-у цифрами вийде якраз 35 можливих значень.

Некласифіковані функції

На кінець наведемо ряд корисних, не класифікованих, функцій:

is_finite 
is_infinite 
is_nan

is_finite

Синтаксис: 
bool is_finite (float val)

Ця функція визначає, чи міститься число в діапазоні чисел з плаваючою крапкою. Цей діапазон береться із специфікацій поточної платформи.

is_ifinite

Синтаксис: 
bool is_infinite (float val)

Ця функція визначає, чи число є нескінченним в діапазоні чисел з плаваючою крапкою. При цьому, звичайно, враховуються можливості платформи.

is_nan

Синтаксис: 
bool is_nan (float val)

Показує, чи є аргумент дійсним числом. З точки зору алгебри, в категорію не дійсних чисел потраплять не зовсім числа (наприклад арккосинус від двійки), так і комплексні числа (наприклад квадратний корінь з -1). В обох випадках функція поверне false.

Функції для роботи з датою і часом

Ці функції дозволяють отримати поточний час сервера, на якому виконується скрипт. Крім того час можна представити в різних форматах, порахувати різницю між двома моментами часу і навіть дізнатися час сходу сонця в певній місцевості в той чи інший день!

Розберемо основні з цих функцій.

bool checkdate (int $month, int $day, int $year)

Повертає TRUE якщо дата, визначена аргументами, є правильною; інакше повертає FALSE. Дата вважається правильною, якщо:

  • рік у діапазоні від 1 до 32767 включно
  • місяць в діапазоні від 1 до 12 включно
  • day є допустимим номером дня для місяця, заданого аргументом month, беручи до уваги, що year може задавати високосний рік.

array date_parse (string $date)

Повертає асоціативний масив з інформацією про дату $date. Масив містить рік, день, місяць, години, хвилини, секунди і інші складові дати.

array date_sun_info (int $time, float $latitude, float $longitude)

Повертає масив з часом сходу, заходу сонця, тривалості світлового дня та ін.

Аргументи - мітка часу, яку можна, наприклад з рядка отримати функцією datetotime ($str). Або функцією time () - поточний час.

string date (string $ format [, int $ timestamp])

Повертає час, відформатований відповідно до аргумента format, використовуючи мітку часу, задану аргументом timestamp або поточний системний час, якщо timestamp не заданий.

Формат - це рядок, що містить символи форматування. І звичайні символи теж. Звичайні виводяться як є, а символи форматування замінюються відповідними значеннями:

Символ рядка format

Опис

Приклад значення, що повертається

a

Ante meridiem або Post meridiem в нижньому регістрі

am або pm

A

Ante meridiem або Post meridiem у верхньому регістрі

AM або PM

B

Час в стандарті Swatch Internet

Від 000 до 999

c

Дата в форматі ISO 8601 (додано в PHP 5)

2004-02-12T15: 19:21 +00:00

d

День місяця, 2 цифри з передуючим нулем

від 01 до 31

D

Скорочене найменування дня тижня

3 символи від Mon до Sun

F

Повне найменування місяця

від January до December

g

Годинник у 12-годинному форматі без ведучих нулів

Від 1 до 12

G

Годинник у 24-годинному форматі без ведучих нулів

Від 0 до 23

h

Годинник у 12-годинному форматі з провідними нулями

Від 01 до 12

H

Годинник у 24-годинному форматі з провідними нулями

Від 00 до 23

i

Хвилини з передуючим нулем

Від 00 до 59

I

Ознака літнього часу

1, якщо дата відповідає літньому часу, інакше 0

j

День місяця без ведучих нулів

Від 1 до 31

l (мала 'L')

Повне найменування дня тижня

Від Sunday до Saturday

L

Ознака високосного року

1, якщо рік високосний, інакше 0

m

Порядковий номер місяця з провідними нулями

Від 01 до 12

M

Скорочене найменування місяця

3 символи Від Jan до Dec

n

Порядковий номер місяця без ведучих нулів

Від 1 до 12

O

Різниця з часом по Грінвічу в годинах

Наприклад: +0200

r

Дата в форматі RFC 2822

Thu, 21 Dec 2000 16:01:07 +0200

s

Секунди з передуючим нулем

Від 00 до 59

S

Англійський суфікс порядкового числівника дня місяця. Застосовується спільно з j

2 символи st, nd, rd або th

t

Кількість днів місяця

Від 28 до 31

T

Тимчасова зона сервера

EST, MDT ...

U

Кількість секунд, що пройшли з початку Епохи Unix (The Unix Epoch, 1 січня 1970, 00:00:00 GMT)

 

w

Порядковий номер дня тижня

Від 0 (неділя) до 6 (субота)

W

Порядковий номер тижня року по ISO-8601, перший день тижня - понеділок (додано в PHP 4.1.0)

42 (42-й тиждень року)

Y

Порядковий номер року, 4 цифри

1999, 2003

y

Номер року, 2 цифри

99, 03

z

Порядковий номер дня року (нумерація з 0)

Від 0 до 365

int time (void)

Повертає кількість секунд, що пройшли з початку Епохи Unix (The Unix Epoch, 1 січня 1970, 00:00:00 GMT) до поточного часу.