Програмуємо на РНР h2>
Це
не тільки дуже просто - це ще й захоплююче! До такого висновку незмінно
приходиш, якщо починаєш знайомитися з основами програмування мовою
гіпертекстового препроцесора РНР. Ну ось, ще тільки початок, а вже незрозумілі
слова пішли. Це ж треба було придумати таке - гіпертекстовий препроцесор! Так
що для поліпшення сприйняття матеріалу заздалегідь давайте домовимося, що будемо
застосовувати спрощені і зрозумілі всім терміни, що б було зрозуміло буквально
всім. І ще одна неодмінна умовність - робимо все так, як робимо. Є
кілька способів відкрити Панель Управління в Windows, є різні способи
приготувати одне і те ж блюдо, і є різні способи і методи
програмування. З поставленим завданням можна впоратися і так, як описано, і
зовсім по-іншому. Але в нашому випадку упор буде робитися на простоту і
логічність, а не на швидкість і чистоту коду. Все це прийде трохи пізніше, а
поки наша мета - вчитися, вчитися, і ще раз вчитися. В продовження теми,
піднятою у статті "РНР для всіх!", ми заглибимося далі в дивовижний
світ програмування. p>
Цикли в РНР h2>
Цикли
в програмуванні - це повторюються кілька разів операції. Початок (точка
відліку) вказується на початку циклу, а тривалість його виконання
обмежується яким-небудь умовою. Прикладом циклу може служити копіювання
декількох файлів. Алгоритм виконання цього завдання можна описати так:
установити лічильник скопійованих файлів в нуль, скопіювати файл, перевірити,
закінчилися файли чи ні, якщо ні - збільшити лічильник скопійованих файлів,
повернутися до початку циклу (знову скопіювати файл), якщо так - закінчити цикл.
Тепер розглянемо, як цикли реалізуються в синтаксисі РНР. P>
php p>
$ i
= 0; $ n = 10; p>
while ($ i <= $ n): p>
echo $ i. "
n"; p>
$ i ++; p>
endwhile; p>
?> p>
Сенс
скрипта дуже простий. Надаємо змінної $ i значення, що відповідає початку
циклу, а змінної $ n - значення кінця циклу. Далі відкриваємо цикл оператором
WHILE (), і всередині його дужок описуємо умова, при виконанні якої цикл
буде продовжувати свою роботу. У нашому випадку виконання не перерветься, поки $ i
<= $ n. Як тільки ця умова буде порушено, управління буде передано
наступної за циклом операції РНР. Всередині циклу можуть бути будь-які команди РНР
(розділені між собою, як звичайно, крапку з комою). Тільки треба стежити
за тим, щоб змінна $ i, що використовується в циклі, була збільшена (і зовсім не
обов'язково на одиницю), інакше цикл стане нескінченною, і інтерпретатор РНР
буде виконувати його, поки не закриється сесія (вікно браузера). Оператор
ENDWHILE означає кінець циклу. Скрипт, описаний тут, виводить на екран
браузера цифри, починаючи з 0 до 10. Причому цифри будуть виведені в стовпчик, так
як після виведення на екран значення змінної $ i ми виводимо HTML-тег перекладу
рядка (
). Після нього йде новий рядок для коду, переданого
клієнту (його можна подивитися, вибравши перегляд у вигляді HTML у меню Вашого
браузера). Це не обов'язково, але таким чином досягається легкість для читання
коду. Для прикладу я наводжу ще один варіант виконання зазначеної вище завдання,
але вже набагато більш правильно з точки зору чистоти коду та швидкості
виконання. p>
php p>
$ i = 0; while ($ i <= 10) (echo
$ i ++."< br> ";) p>
?> p>
Дивно,
але ці два приклади абсолютно ідентичні в сенсі результату. Але сам скрипт
вмістився в один рядок! Різниця - у стилі застосування оператора циклу і в тому,
що змінна циклу виводиться на екран одночасно зі збільшенням. І в цьому --
вся принадність програмування. Іноді буває щось просте зробити дуже важко,
а складне - легко. Ніколи не варто зупинятися на вже досягнутому, а
пробувати застосовувати інші алгоритми і рішення. Ось Вам ще один варіант
рішення. Він заснований на застосуванні конструкції РНР DO ... WHILE. Це теж цикл, але
він відрізняється від просто WHILE тим, що значення логічного виразу
перевіряється не до (як у випадку з WHILE), а після закінчення роботи операторів,
включених в сам цикл. Таким чином, DO ... WHILE гарантовано буде виконаний
хоча б один раз, що у випадку з WHILE зовсім не обов'язково. Адже якщо умова
це неправда, управління відразу буде передано далі. Для циклів DO .. WHILE
існує тільки один вид синтаксису: p>
php p>
$ i
= 0; do (echo $ i. "
n"; $ i + +;) while ($ i <= 10); p>
?> p>
Здавалося
б, досить варіантів, але це не все - існує ще кілька варіантів
циклу. І, як правило, саме вони і використовуються програмістами. Цикли FOR --
найбільш потужні цикли в PHP. Вони працюють подібно до їх аналогам в мові
програмування C. Синтаксис циклу FOR: p>
FOR
(expr1; expr2; expr3) statement p>
Перше
вираз (expr1), безумовно, обчислюється (виконується) на початку циклу. У
початку кожної ітерації (прохід циклу) обчислюється expr2. Якщо воно рівне TRUE
(істина), то цикл продовжується і виконуються вкладений (е) оператор (и). Якщо воно
одно FALSE (неправда), то цикл закінчується. В кінці кожної ітерації обчислюється
(виконується) expr3. Кожне з цих виразів може бути порожнім. Якщо expr2
пусто, то цикл продовжується нескінченно (PHP за замовчуванням вважає його рівним
TRUE, як і в мові С). Це не так марно, як могло б здатися, так як
часто потрібно закінчити виконання циклу, використовуючи оператор BREAK в
поєднанні з логічним умовою, замість використання логічного вираження в
FOR. Якщо всередині циклу (будь-якого) зустрічається цей оператор (BREAK), цикл
припиняє виконання ітерації і керування передається наступній за циклом
команді. Якщо зустрічається оператор CONTINUE - управління передається на початок
наступного найближчого циклу. Для прикладу подивимося, як можна ще реалізувати
виведення на екран користувача список чисел. Не забувайте про перехід з HTML в
PHP. P>
/*
приклад 1 */ p>
for
($ i = 1; $ i <= 10; $ i + +) p>
(print $ i;) p>
/* приклад 2 */ p>
for ($ i = 1;; $ i + +) p>
(if ($ i> 10) (break;) print
$ i;) p>
/* приклад 3 */ p>
$ i = 1; for (;;) p>
(if ($ i> 10) (break;) print
$ i; $ i + +;) p>
/* приклад 4 */ p>
for ($ i = 1; $ i <= 10; print $ i,
$ i + +); p>
Так
що не кажіть потім, що у Вас не було вибору :-). На прикладі тривіальної
завдання ми розглянули, як РНР дозволяє різними способами досягти однієї мети.
Як правило, на практиці застосовується найкраща конструкція, але часто
в цьому немає ніякої необхідності, досить використовувати найпростіший і
логічний варіант. p>
Відправка пошти h2>
Дуже
часто хочеться знати, що відбувається на сайті за час Вашої відсутності.
Звичайно, можна періодично перевіряти форум, гостьову і т.д. на предмет нових
повідомлень, але є спосіб краще! Чому б не надсилати самому собі повідомлення
на поштову скриньку, коли на сайті відбувається та чи інша подія? Як приклад
можу запропонувати такі варіанти: реєстрація в розсилці, щоб написати у форум,
гостьову і т.д., помилка відкриття файлу, організація зворотного зв'язку, опитування
думки читачів про розміщеної статті і т.д і т.п. Способів застосувати цю
можливість РНР - маса, залишилося розібратися, як це працює. Як завжди --
просто! Синтаксис такий: p>
Mail
($ Email, "Введено повідомлення", $ str, "From: повідомлення"); p>
Звичайно,
перед цим відповідні змінні повинні бути введені або вручну, або з
допомогою форми (потрібно стежити за відповідністю імен змінних у формі і в
скрипті). При виконанні цієї команди інтерпретатор РНР надішле листа з
текстом із змінної $ str за адресою, вказаною у змінній $ email. Всі
решта - службова інформація, яка може бути в деяких випадках
опущена через непотрібність. Для прикладу розглянемо систему контролю за
відвідувачами певних сторінок сайту. Така можливість може знадобитися
для аналізу відвідувань певних статей, сторінок і т.д. Нам буде потрібно
інформація про відвідувача, яка в РНР автоматично доступна через змінні
оточення. Цю інформацію ми будемо відсилати собі на поштову скриньку. Тільки не
перестарайтеся - кожне відвідування такої сторінки викличе відправку листи, і
ящик може виявитися переповненим. p>
php p>
if (isset ($ HTTP_X_FORWARDED_FOR)) p>
( p>
$ host =
gethostbyaddr ($ HTTP_X_FORWARDED_FOR); p>
) else ( p>
$ host = gethostbyaddr ($ REMOTE_ADDR);
) P>
$ ip = getenv ( 'REMOTE_ADDR'); p>
$ date = date ( 'd M Y, H: i: s'); p>
$ host1 = gethostbyaddr ( "$ ip "); p>
$ str =(" p>
Дата - $ date p>
Хост - $ host p>
IP-адреса - $ ip p>
---------------------"); p>
mail (
$ email, "статистика", $ str, "From: інформація "); p>
?> p>
Якщо
Ви розмістите на одній з Ваших сторінок цей код РНР, інформація про відвідувача
(це дата входу, хост та IP-адреса) буде у Вашій поштовій скриньці. Ще можна
надіслати собі повідомлення при виникненні помилки (наприклад, відкриття файлу) на
сайті: p>
$ filename = "data.txt"; p>
$ fp =
@ fopen ($ filename, "r"); p>
if (! $ fp) (@ mail ($ email, "Помилка!", "Помилка відкриття файлу $ filename
! ");) P>
Як
звичайно, можна поставити знак @, і якщо виникне помилка при відправці пошти,
повідомлення про це не буде виведено на екран. А можна просто перевірити, пішло
лист чи ні: if (@ mail ($ email, "Тест", $ str)) (... що зробити
якщо лист пішло ...) else (... що робити, якщо сталася помилка відправлення (не
доступний ящик, сайт і т.д)). Власне кажучи, є можливість забирати
пошту з будь-якого облікового запису, але це вимагає розширення РНР за рахунок підключення
додаткових модулів, і в стандартному постачанні недоступне. Якщо у змінній
$ email вказати декілька адрес, розділених пробілами, інформація буде
розіслано по всіх вказаними адресами. Це відкриває простий шлях до організації
власної, ні від кого не залежить системи поштових розсилок. p>
Пори і дати h2>
Раз
вже розмова торкнулася дати, спробуємо розібратися, як все це можна використовувати
в своїх власних цілях. У РНР найбільш часто використовується функція DATE в
форматі $ date = date ( 'параметр');. Параметрів може бути декілька, і розділяються
вони між собою комою. Ось перелік допустимих параметрів. P>
•
a - "am" або "pm" p>
•
A - "AM" або "PM" p>
•
d - день місяця, цифровий, 2 цифри (на першому місці нуль) p>
•
D - день тижня, текстовий, 3 літери; тобто "Fri" p>
•
F - місяць, текстовий, довгий; тобто "January" p>
•
h - година, цифровий, 12-годинний формат p>
•
H - година, цифровий, 24-годинний формат p>
•
i - хвилини, цифровий p>
•
j - день місяця, цифровий, без початкових нулів p>
•
l (рядкова 'L') - день тижня, текстовий, довгий; тобто "Friday" p>
•
m - місяць, цифровий p>
•
M - місяць, текстовий, 3 літери; тобто "Jan" p>
•
s - секунди, цифровий p>
•
S - англійський порядковий суфікс, текстовий, 2 символу; тобто "th",
"nd" p>
•
U - секунди з початку століття p>
•
Y - рік, цифровий, 4 цифри p>
•
w - день тижня, цифрової, 0 означає неділю p>
•
y - рік, цифровий, 2 цифри p>
•
z - день року, цифровой; тобто "299" p>
Зверніть
увагу на різницю в регістрі. Кожен символ у різних регістрах має різні
функції. Тепер Ви легко можете отримати інформацію про поточний часу і
використовувати її на своєму сайті. Один з найпоширеніших варіантів --
висновок поточного часу та дати. Звичайно, все це робиться без проблем на JavaScript,
але хто бачив ці скрипти, той зрозуміє різницю (по крайней мере, в розмірі і
швидкості виконання, не кажучи вже про трафік від сервера до браузера). Ну, час,
на мій погляд, виводити даремно, тому що воно є у кожного користувача в
треї Windows-а, а ось вивести число, місяць і день тижня (та ще українською
мовою) буває корисно. Почнемо з вітання відвідувачеві. Було б непогано вивести
відповідну фразу в залежності від часу відвідування. Сказано - зроблено: p>
php
p>
$ h = date ( 'H'); p>
if
($ h> = 5 & & $ h <= 11) echo "Доброго ранку !"; p>
if
($ h> = 12 & & $ h <= 18) echo "Здрастуйте !"; p>
if
($ h> = 19 & & $ h <= 24) echo "Добрий вечір !"; p>
if
($ h> = 1 & & $ h <= 4) echo "Доброї ночі !"; p>
?> p>
Цифри
бажаного часу можна проставити будь-які, в залежності від особистого поняття дня
і ночі :-). Наступний крок - виведення числа, дня тижня та імені місяці. Але перш
ніж ми приступимо до реалізації алгоритму, нам потрібно познайомитися ще з одним
важливим моментом в мовах програмування. p>
Масиви в РНР h2>
Якщо
Ви чітко уявляєте собі, що таке масив, пропоную Вам відразу перейти до
читання наступного абзацу. Якщо ні, тоді саме це Ви зараз і дізнаєтеся.
Масив - це ряд змінних, упорядкованих по імені і що мають різний індекс.
Для прикладу уявіть, що у Вас є двадцять назв, і всі їх потрібно внести
в програму. Можна для зручності обізвати змінні однаковим ім'ям і ставити
в кінці кожного імені змінної число у відповідності з номером назви. У Вас
вийде найпростіший одновимірний масив. Тільки будь-яку мову програмування (і
РНР теж!) Надає набір засобів для більш детальної і зручної роботи з
таким набором-масивом. І число (так званий індекс) потрібно укладати в
квадратні дужки. Припустимо, є ряд строкових змінних: комп'ютер,
Інтернет, модем, монітор. Ім'я для масиву виберемо $ m, хоча є будь-яке, як
і у звичайної змінної. Індекс в масивах починається не з одиниці, а з нуля, і
таким чином для внесення наших слів в масив треба зробити так: p>
$ m [0]
= "Комп'ютер"; p>
$ m [1]
= "Інтернет"; p>
$ m [2]
= "Модем"; p>
$ m [3]
= "Монітор"; p>
Тепер
у нас створено масив з іменем "$ m і максимальним індексом (це кількість
елементів у масиві) - 4. Саме 4, хоча останній заповнений елемент - 3.
Якщо ми спробуємо вважати елемент з 4-им індексом, результат буде дорівнює порожній
рядку, тому що там просто нічого немає. Звертатися до елементів масиву потрібно по
імені масиву і його індексу, що і складає основний зручність. Наприклад, ми
можемо вивести на екран всі елементи масиву: p>
$ i
= 0; while ($ i "; $ I + +;) p>
Функція
count ($ m) видає нам число, відповідне максимального індексу масиву.
Таким чином, у нас завжди є можливість знати, скільки елементів
присутня в цьому масиві. Що ще можна дізнатися про масивах в РНР? Дещо
можна ... Наприклад, функція current повертає поточний елемент масиву. Кожна
змінна-масив має внутрішній покажчик (це не індекс, а спеціальний
параметр, який, як правило, або збігається з індексом, або перевищує його
на одиницю, але необов'язково), що вказує на один зі своїх елементів.
Крім того, всі елементи в масиві зв'язуються двонаправленим списком
покажчиків для додаткових цілей. Внутрішній покажчик вказує на першу
елемент, який включався до масиву, поки Ви не виконували одну з функцій,
які модифікують цей покажчик для цього масиву. Функція current () просто
повертає елемент масиву, на який в даний момент вказує внутрішній
покажчик. Вона ніяк не переміщує покажчик. Якщо внутрішній покажчик
вказує на кінець списку елементів, current () повертає false (хибно).
Увага: якщо масив містить порожні елементи (0 або "", порожню
рядок), то функція поверне "false" для кожного з них. Це
показує, що поточний елемент є нульовим значенням або ви дійшли до
кінця масиву. End - встановлюєте внутрішній покажчик масиву на останній
елементі. Next - пересуває внутрішній покажчик масиву. Повертає наступний
елемент масиву, від поточної позиції внутрішнього покажчика масиву, або
"неправда" (false), якщо немає більше елементів. Якщо масив містить порожні
елементи, тоді ця функція поверне "неправда" (false) і для цих
елементів. next () веде себе подібно current (), з однією лише різницею: він
пересуває внутрішній покажчик масиву на один елемент вперед перш, ніж
повернути елемент. Це означає, що він повертає значення наступного
елемента і пересуває на нього внутрішній покажчик масиву. Якщо при зверненні
до наступного елементу виявлений кінець масиву - next () повертає
"неправда" (false). Prev - переміщує внутрішній вказівник масиву.
Повертає попередній елемент масиву, або "неправда" (false), якщо перед
поточним немає більше елементів. Якщо масив містить порожні елементи, то функція
поверне "брехня" і на цих елементах. prev () веде себе подібно
next (), за винятком того, що він перекладає внутрішній покажчик масиву на
одну позицію тому, а не вперед. Reset () - встановлює внутрішній покажчик
масиву на першому елементі. Rsort () - сортує масив у зворотному порядку (за
спаданню), за абеткою в тому числі. На жаль, російська алфавіт тут не при
чим. Sort () - сортує масив. Точнісінько те саме, що і попереднє, тільки по
зростанням. Звичайно, це далеко не всі функції, які є в РНР
щодо масивів. Але решта часто дуже специфічно і вирішується іноді
більш простими методами. p>
Дата по-русски h2>
Скрипт,
який ми зараз розглянемо, дозволяє вивести на екран відвідувача дату в
форматі російської мови. Відразу попереджаю, що реалізація алгоритму цієї
завдання не найкраща, але працездатна, ясна у всіх відносинах і проста.
А головне - використовується тільки те, що вже було описано. Спочатку я приведу сам
текст скрипта, а потім детально опишу його. p>
php p>
// --
визначаємо масив для місяців - p>
$ q []=""; p>
$ q [] = "січня";
p>
$ q [] = "лютого";
p>
$ q [] = "березня";
p>
$ q [] = "квітня";
p>
$ q [] = "травня"; p>
$ q [] = "червня";
p>
$ q [] = "липня";
p>
$ q [] = "серпня";
p>
$ q [] = "Вересень";
$ q [] = "грудня";
p>
$ q [] = "Листопад"; p>
$ q [] = "грудня"; p>
// --
визначаємо масив для днів тижня - p>
$ e [0] = "Неділя";
p>
$ e [1] = "Понеділок";
p>
$ e [2] = "вівторок";
p>
$ e [3] = "середовище";
p>
$ e [4] = "Четвер"; p>
$ e [5] = "П'ятниця";
p>
$ e [6] = "Субота";
p>
//
---- Зчитуємо місяць p>
$ m = date ( 'm'); p>
if ($ m == "01") $ m = 1; p>
if ($ m == "02") $ m = 2; p>
if ($ m == "03") $ m = 3; p>
if ($ m == "04") $ m = 4; p>
if ($ m == "05") $ m = 5; p>
if ($ m == "06") $ m = 6; p>
if ($ m == "07") $ m = 7; p>
if ($ m == "08") $ m = 8; p>
if ($ m == "09") $ m = 9; p>
//
---- Зчитуємо день тижня p>
$ we = date ( 'w'); p>
//
---- Зчитуємо число p>
$ chislo = date ( 'd'); p>
//
- Витягаємо день тижня p>
$ den_nedeli
= $ E [$ we]; p>
//
- Витягаємо значення місяця p>
$ mesyac
= $ Q [$ m]; p>
echo "Сегодня". $ chislo. "
". $ mesyac.", ". $ den_nedeli; p>
?> p>
Тепер
розглянемо, як працює цей скрипт. Спочатку нам потрібно визначити два масиви,
в яких будуть зберігатися відповідно російська назва місяця і російське
назва дня тижня. Так як місяць не може бути нульовим, нам потрібно
подбати про введення елемента масиву з нульовим індексом. Якщо індекс масиву
не вказаний, він приймається рівним внутрішньому вказівником. Якщо масив зруйнований, а ще
не визначено, внутрішній покажчик указує на перший елемент (що має індекс
нуль). Введення нового елемента масиву переміщує внутрішній вказівник на одиницю
вгору, і, таким чином, забезпечується подальший введення значення масиву в
комірку масиву, що має індекс на одиницю більший, ніж попередній. У принципі,
можна забезпечити введення даних в масив різними способами. Але вказаний тут --
самий простий і примітивний. Ми просто надаємо по черзі потрібні нам дані
елементів масиву і, таким чином, заповнюємо його. Точно така ж історія
спостерігається і з другим масивом. Тільки тут вже індекс потрібних осередків масиву
вказується явно, і внутрішній покажчик встановлюється на той індекс, який
вказаний, а після введення значення пересувається вгору на одиницю. Різниця між
цими двома методами в тому, що якщо масив вже було визначено раніше і індекс
при введенні не вказаний, заповниться осередок масиву, на яку вказує внутрішній
покажчик. А він же може знаходитися і в кінці! А якщо індекс вказаний явно,
внутрішній покажчик встановлюється на його значення і запис відбувається в явно
зазначену клітинку. Власне, частіше масиви бувають набагато довше наведених у
прикладі, і зручніше скористатися спеціальною функцією, яка дозволяє
вважати зазначений у ній файл і ввести все, що є в цьому файлі, в масив.
Причому роздільником вважається переклад рядка, що дуже зручно. Синтаксис цієї
функції - $ ім'я масиву = file ( "ім'я файлу");. Далі формується
масив з вказаним ім'ям і значеннями, відповідними рядках файлу. p>
Коли
масиви визначені, нам потрібно вважати номер місяця. Він зчитується з ведучим
нулем, якщо номер місяця менше десяти, і тому нам потрібно подбати про його
відсіканні. Тут можна застосувати теж різні алгоритми і методи, але ми
скористаємося лобовим рішенням - просто порівняємо отримане рішення з низкою
заздалегідь відомих варіантів і змінимо номер місяця на правильний без нуля.
Рішення грубе, зате зрозуміле і вже знайоме нам. Хоча так робити не правильно
- Є більш витончені методи, наприклад, перевірити отримане значення на провідний
нуль, і якщо перевірка є істина (самий перший символ у рядку - нуль),
видалити перший символ. p>
Далі
по ходу скрипта ми зчитуємо день тижня і число. З числом робити нічого не
потрібно, тому що дата буде зрозуміла всім, а ось день тижня і місяць повинні
піддатися обробці. Витягуємо з введеного нами раніше масиву день
тижні. Номер дня тижня вказує на клітинку нашого масиву, де зберігається
потрібне російське ім'я, і таким чином ми в будь-якому випадку отримаємо правильне
значення. Змінюється номер дня тижня, змінюється номер (індекс) комірки, з якої
зчитується значення. Причому тут, на відміну від масиву з іменем місяця, нулю відповідає
Неділя, що ми і врахували під час введення масиву днів тижня. Таку саму
операцію проводимо і для місяця. Його номер вказує на комірку масиву, де
зберігається правильне ім'я місяця українською мовою. А далі - виводимо результат
на екран у довільній формі. p>
Висновок h2>
Отже,
ми познайомилися з дуже важливими в будь-якій мові програмування принципами
організації циклів і масивів, а також дізналися, як застосовувати на практиці
можливість відправки пошти і зчитування дати. Не сумніваюся, що ви зможете придумати
ще багато прикладів для застосування цих речей. Не соромтеся експериментувати
і пробувати різні варіанти. Саме так і вивчаються мови програмування --
на прикладах. Використовуйте для пошуку нових рішень і скриптів Інтернет,
підпишіться на розсилання по РНР для отримання нової інформації. Якщо не всі
зрозуміло - сміливо ставте питання, я постараюся в міру сил і знань відповісти
на них. І ніколи не зупиняйтеся на досягнутому, тому що завжди існує
те, що ми ще поки не знаємо, але ж так хочеться ... p>
Список літератури h2>
Для
підготовки даної роботи були використані матеріали з сайту http://www.i2n.ru
p>