Огляд мережних функцій PHP h2>
В
цій статті розглядається використання мережевих функцій популярної мови
програмування PHP. При написанні цієї статті я вирішив відійти від загальноприйнятої
схеми, яка вживається в керівництві по PHP: p>
«тип
назва (параметри) - опис » p>
Навпаки,
у статті зібрані корисні практичні приклади. З-за великого обсягу
інформації (мова PHP призначений для Web-програмування, тому досить
більшу частину функцій можна назвати мережевими), я обмежусь тільки тими,
які використовую найчастіше. p>
Змінні оточення інтерфейсу
CGI b> p>
При
використанні інтерфейсу CGI (Common Gateway Interface) програмісту є
безліч змінних оточення. Зараз ми розглянемо найбільш корисні в нашому
випадку змінні (див. таблицю 1). p>
Змінні
оточення можна використовувати в програмі також як звичайні змінні.
Наприклад, для виведення IP-адреси клієнта достатньо одного оператора: p>
echo
$ REMOTE_ADDR p>
Таблиця
1. p>
Змінна p>
Опис p>
HTTP_USER_AGENT p>
За допомогою цієї зміною можна
визначити броузер користувача, а також його операційну систему. Наприклад,
для Netscape, запущеним під Linux, ця змінна буде содердать значення: p>
Mozilla/4.7 [en] (Linux; I) p>
Для Internet Explorer 5.0 і Win98: p>
Mozilla/4.0 (compatible; MSIE 5.0; Windows
98; DigExt) p>
HTTP_HOST p>
Містить доменне ім'я сервера,
на якому запущений сценарій. p>
SERVER_PORT p>
Порт сервера, до якого
звернувся броузер. Зазвичай використовується порт 80. P>
REMOTE_ADDR p>
Містить IP-адреса клієнта, то
є IP-адресу користувача, який запустив броузер p>
REMOTE_PORT p>
Порт для отримання відповіді
сервера. Цей порт закріплюється за кожною запущеної копією броузера p>
Отримання документа по протоколу HTTP p>
Отримати
документ по протоколу HTTP досить просто: p>
Лістинг
1. Отримання документа по HTTP p>
p>
1. $ file = join ('', file (
'http://localhost/index.html')); p>
2.
echo $ file; p>
?> p>
В
першому рядку лістингу 1 ми одержуємо весь документ в рядок $ file, а другий --
відправляємо документ в броузер. Функція file () повертає масив рядків. N-ий
елемент цього масиву відповідає N-ої рядку файлу. p>
Якщо
нас цікавить HTML-код одержуваного документа, вивести код в броузер допоможе
лістинг 2, який я запозичив з керівництва по PHP. p>
Лістинг
2. Висновок HTML-коду документа p>
p>
1. $ fcontents = file (
'http://localhost'); p>
2. while (list ($ line_num, $ line)
= Each ($ fcontents)) ( p>
3. echo " Line
$ line_num: b> ". htmlspecialchars ($ line)."
n "; p>
4.
) p>
?> p>
Робота з сокетами b> p>
Функція
file () (так само як і fopen ()) дозволяє нам працювати тільки з вмістом файла,
який отриманий з того чи іншого протоколу. Припустимо, що нас цікавлять
заголовки, передані сервером. Отримати ці заголовки ми можемо за допомогою функції
p>
int fsockopen (string $ host, int
$ port, [, int & $ errno] [, string & $ errstr]) p>
Дана
функція дозволяє ініціалізувати потокове з'єднання з зазначеним хостом і
програмою, яка пов'язана із зазначеним портом. Крім того, ця функція
підтримує Unix-сокети. При цьому параметр $ hostname буде використаний як
шлях до файлу сокета, а параметр $ port повинен бути дорівнює 0. p>
Після
підтримання зв'язку функція повертає звичайний дескриптор файлу. З
цим дескриптором можуть працювати функції fread (), fwrite (), fgets (), feof () і
інші. p>
В
випадку помилки функція поверне false і, якщо вказані необов'язкові параметри
$ errno і $ errstr, відповідно, номер помилки і текст повідомлення про помилку. p>
Розглянемо
лістинг 3 - «Віртуальний браузер»: ми посилаємо серверу HTTP-запит GET і,
одержавши відповідь, виводимо його в броузер. p>
Лістинг
3. «Віртуальний браузер» p>
p>
//
Підключаємося до сервера p>
1. $ fsoc =
fsockopen ( "localhost", 80); p>
2. fputs ($ fsoc, "GET /
HTTP/1.0nn "); p>
3. echo "
"; p>
4. while (! feof ($ fsoc)) p>
5. echo
HtmlSpecialChars (fgets ($ fsoc, 1000 )); p>
6. echo " pre >"; p>
//
Відключається від сервера p>
7.
fclose ($ fsoc); p>
?> p>
Як
я вже зазначав вище, при використанні функції fsockopen ми отримуємо вся відповідь
сервера - разом із заголовками. Функцію HtmlSpesialChars () ми використовуємо для
коректного відображення HTML-коду в текстовому форматі. У броузері ми повинні
отримати приблизно наступне: p>
HTTP/1.1
200 OK p>
Date:
Sat, 16 Mar 2002 10:46:59 GMT p>
Server: Apache/1.3.12 (Linux) p>
Last-Modified: Sat, 20 Nov 1999
13:29:40 GMT p>
ETag: "0-574-3836a244" p>
Accept-Ranges: bytes p>
Content-Length: 1396 p>
Connection: close p>
Content-Type: text/html p>
p>
p>
sp;
p>
Test Page for Apache
Installation TITLE> p>
HEAD> p>
... p>
Відповідь
сервера HTTP/1.1 200 OK відповідає коду відповіді 200 і означає безпомилкове
виконання операції (в даному випадку передачі документа на запит GET). p>
Встановити
потрібний нам заголовок відповіді ми можемо з допомогою функції Header (). Наприклад,
Header ( "Location:// www.softerra.ru/freeos"); p>
Заборонити
кешування можна за допомогою установки заголовка Pragma: no-cache. На жаль
одного цього заголовка явно не вистачить для заборони кешування. Для повного
заборони потрібно використовувати цілих чотири заголовка. Встановити за допомогою Header їх можна так: p>
Header ( "Pragma:
no-cache "); p>
Header ( "Cache-control:
no-cache, must-revalidate "); p>
Header ( "Expires: Mon, 01 Jan
1990 01:01:01 GMT "); p>
Header ( "Last-Modified:
". gmdate (" D, d M Y H: i: s ")." GMT "); p>
Перший
з них встановлює заголовок заборони кешування згідно протоколу HTTP/1.0,
а другий - HTTP/1.1. Третій визначає задає дату в минулому, а четвертий
встановлює дату останнього оновлення документа. Функція gmdate () повертає
дату в потрібному нам форматі. Встановлювати всі чотири заголовка вкрай
бажано, так як заборона кешування може не спрацювати або на проксі-сервер
або в броузері, і користувач отримає застарілу версію документа. p>
Функції для роботи з DNS b> p>
При
написанні сценаріїв незалежно від мови програмування часто виникає
потреба дозволу IP-адреса в доменне ім'я і навпаки. p>
Перетворення
IP-адреса в доменне ім'я виконує функція p>
string gethostbyaddr (string
$ ip_address); p>
В
випадку помилки повертається IP-адресу. p>
Перетворення
імені хоста в IP-адреса виконує функція p>
string
gethostbyname (string $ host); p>
Якщо
вам потрібно отримати всі IP-адреси хоста з іменем "$ host, використовуйте функцію p>
array
gethostbynamel (string $ host); p>
В
лістингу 4 застосована саме функція gethostbynamel. p>
Лістинг
4. Отримання всіх IP-адрес хоста $ host p>
p>
$ host = "www.yahoo.com"; p>
$ ips = gethostbynamel ($ host); p>
foreach ($ ips as $ ip) echo $ ip; p>
?> p>
Визначити
почтовик для зазначеного хоста hostname можна за допомогою функції p>
int getmxrr (string hostname, array
mxhosts, array [weight]); p>
Дана
функція запитує DNS на предмет наявності записів MX для зазначеного хоста. p>
Наступні
функції ніякого відношення до DNS не мають, але щоб не створювати іншого
розділу в статті, я описав їх тут. p>
int
getprotobyname (string name); p>
Функція
getprotobyname () повертає номер протоколу, який відповідає імені $ name.
p>
Зворотній їй
функція p>
string getprotobynumber (int number);
p>
повертає
ім'я протоколу за його номером. p>
Функція p>
int getservbyname (string service,
string protocol); p>
повертає
номер порту Internet-сервісу, назва якого зазначено в параметрі $ service.
Другий параметр функції - це протокол: tcp чи udp. p>
Наприклад,
оператор p>
echo
getservbyname ( "ftp", "tcp"); p>
виведе
у вікно броузера число 21. p>
Для
функції getservbyname () також існує зворотна їй: p>
string getservbyport (int port,
string protocol); p>
При
використанні функції getservbyport () потрібно вказати номер порту і протокол (tcp
або udp) і, як результат, ви отримаєте назву Internet-сервісу. p>
Наприклад,
p>
echo
getservbyport (21, "tcp"); p>
виведе
у вікно броузера назва сервісу - ftp. p>
Опції протоколювання p>
Іноді
потрібно записати деяку інформацію, наприклад, повідомлення про помилку, в системний
журнал syslog. У PHP для цього передбачена ціла серія функцій: p>
int openlog (string ident, int
option, int facility); p>
int syslog (int priority, string
message); p>
int
closelog (void); p>
Перша
з них відкриває з'єднання з демоном syslog. Друга - породжує системне
повідомлення (іншими словами записує повідомлення з вказаним пріоритетом у
протокол). Функція closelog () закриває з'єднання протоколу. p>
Відправлення повідомлення b> p>
Я
не відкрию Америки, якщо заявлю, що для відправки пошти в PHP використовується
функція mail. Тут я тільки наведу кілька рекомендацій щодо
використання цієї функції. p>
Нагадаю формат виклику функції: p>
mail (string $ to, string $ subject,
string $ msg [, string $ headers]); p>
Наприклад, p>
mail ( "root @ localhost",
"Test", "MessagenLine2", "From:
den @ localhostn "," Reply-To: den @ localhostn "); p>
Всі
працює добре до тих пір, поки не починаються проблеми з кодуваннями. Для
вказівки кодування потрібно встановити заголовок p>
Content-type:
text/plain; charset = koi8-r p>
Для
перетворення самих кодувань використовується функція convert_cyr_string ().
Використовувати її гранично просто, наприклад, p>
convert_cyr_string ($ msg, "k", "w");
p>
Цим
викликом функції convert_cyr_string () ми перетворимо кодування koi8-r в
windows-1251. Зрозуміло, заголовок Content-type потрібно змінити на p>
Content-type: text/plain;
charset = win-1251 p>
При
використанні функції mail доцільно зберігати всі заголовки в тексті листа.
Тоді один раз викликавши функції convert_cyr_string () ми конвертуємо все листа до
нужнию нам кодування. У цьому випадку виклик функції mail повинен бути зроблений
так: p>
mail ( "root @ localhost ","",$ msg);
p>
Значення
змінної $ msg буде таким: p>
$ msg = "From: Денис n p>
To: Адміністратор n p>
Content-type: text/plain;
charset = win-1251n p>
n p>
Текст
повідомлення p>
... p>
Зверніть
увагу, що після всіх заголовків має слідувати два символи нового рядка
n: одна після останнього заголовка, а інший перед текстом повідомлення. p>
Список літератури h2>
Для
підготовки даної роботи були використані матеріали з сайту http://www.i2n.ru
p>