Web - кодинг: PHP:
Обзор сетевых функций PHP
Автор: Денис Колисниченко
Сайт:
Источник:
Краткий обзор (с примерами) сетевых функций php:
ведения протоколов; cgi и dns; сокеты и работа с сообщениями.
В этой статье рассматривается
использование сетевых функций популярного языка программирования PHP. При
написании этой статьи я решил отойти от общепринятой схемы, которая
употребляется в руководстве по PHP: «тип название (параметры) –
описание» Наоборот, в статье собраны полезные практические
примеры. Из-за большого объема информации (язык PHP предназначен для
Web-программирования, поэтому достаточно большую часть функций
можно назвать сетевыми), я ограничусь только теми, которые использую
наиболее часто.
Переменные
окружения интерфейса CGI Получение
документа по протоколу HTTP Работа
с сокетами Функции
для работы с DNS Функции
протоколирования Отправка
сообщения
Переменные окружения интерфейса
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 = join( '', file( 'http://localhost/index.html' ) );
2. echo $file;
?>
В первой строке листинга 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 "Line $line_num: " . htmlspecialchars( $line) . " \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.0\n\n");
3. echo "";
4. while (!feof($fsoc))
5. echo HtmlSpecialChars(fgets($fsoc,1000));
6. echo " ";
// Отключаемся от сервера
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
sp;
Test Page for Apache Installation
...
Ответ сервера 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
$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", "Message\nLine2", "From: den@localhost\n", "Reply-To:
den@localhost\n");
Все работает хорошо до тех пор, пока не
начинаются проблемы с кодировками. Для указания кодировки нужно установить
заголовок 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: Денис \n
To: Администратор \n
Content-type: text/plain; charset=win-1251\n
\n
Текст сообщения
...
Обратите внимание, что после всех
заголовков должно следовать два символа новой строки \n: один после
последнего заголовка, а другой перед текстом сообщения. На этом я и
заканчиваю этот небольшой обзор, любые ваши комментарии, вопросы прошу
присылать mailto:dhsilabs@mail.ru
Денис Колисниченко Copyright
© "Софтерра", www.softerra.ru, inform@softerra.ru
При перепечатке любого материала
с сайта, видимая ссылка на источник www.warayg.narod.ru
и все имена, ссылки авторов обязательны.
© 2005
|