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