Добро пожаловать!
Здесь вы можете найти ответ на интересующий вас вопрос в отрасли сайтостроения, познакомится ближе с web технологиями и web стандартами.

Статьи

Импортирование информации с помощью PHP

Если вы уже некоторое время занимаетесь WEB-программированием, то наверняка перед Вами хотя бы раз вставала задача заимствования информации с других WEB-узлов, например, для сбора статистики вашего сайта с сервера статистики с последующей её отправкой электронной почтой или импорт курса валют с обработкой специально под ваш дизайн. PHP представляет нам много возможностей для импортирования информации. Зачастую хватает самых простых, вроде приведенных ниже, строк.

<?php
/*
Функция file() считывает информацию из файла или URL и возвращает его построчно 
ввиде массива: одна строка - один элемент массива. Полученный массив преобразуется 
в строку функцией implode().
*/
echo implode(''file('http://some.site.ru/infopage.html'));
?>

или

<?php
// Открываем URL в режиме чтения "r"
$fp fopen"http://some.site.ru/infopage.html""r" );
//Если соединение успешно открыто
if( $fp ) {
  
// Считывать строки из удалённого файла до тех пор, пока не достигнут конец файла.
  
while( !feof$fp ) ) {
  echo 
fgets$fp1024 );
}
//Закрываем соединение
fclose$fp );
}
?>

Однако, бывают случаи когда простого заимствования оказывается мало. Допустим, нам нужно взять информацию с сайта требующего авторизации. В этом случае, нам сначала требуется узнать какие поля и на какой адрес передаются формой авторизации. Это несложно. Заходим на страницу авторизации и в браузере нажимаем "Просмотр в виде HTML" или "Просмотреть исходный текст". Перед нами HTML-код страницы. В ней находим форму авторизации. В теге <form> смотрим параметры action и method. Соответственно, в action содержится адрес скрипта авторизации, а method - метод передачи данных (GET или POST). Затем выбираем имена полей, которые непосредственно передают данные для авторизации. Например:

<form action="http://some.site.ru/auth.php" method="post">
Логин: <input type="text" name="login" /><br/>
Пароль: <input type="password" name="password" /><br/>
<input type="submit" name="submit" value="Войти" />
</form>

Здесь мы видим, что форма передаёт три параметра ( login, password с введёнными логином и паролем к аккаунту, а также поле submit, значением которого является слово "Войти") на адрес http://some.site.ru/auth.php методом POST. Этих знаний уже вполне хватает для написания скрипта импорта.

<?php
//Сначала требуется упаковать все передаваемые данные
$data = array( "login"=>"vasya""password"=>"PaSsWoRd""submit"=>"Войти" );
while( list(
$name$value) = each($data) ) {
  
$temp[] = urlencode($name)."=".urlencode($value);
}
$PostData implode("&"$temp);

//Организация запроса к сайту
$ch curl_init("http://some.site.ru/auth.php");
curl_setopt$chCURLOPT_HEADER); // Не выводить заголовки
curl_setopt$chCURLOPT_NOBODY); // Выводить получаемый Content
curl_setopt$chCURLOPT_USERAGENT"User-Agent: Opera/7.54 (Windows 98; U) [ru]" ); //Браузер
curl_setopt$chCURLOPT_REFERER"http://some.site.ru" ); //Адрес формы авторизации
// Если используется метод GET, следующие две строки не нужны, а данные
// передаются в функции curl_init() вместе с адресом страницы, например:
// $ch = curl_init("http://some.site.ru/auth.php?login=vasya&password=PaSsWoRd&submit=%C2%EE%E9%F2%E8");
curl_setopt$chCURLOPT_POST); //Использовать метод POST
curl_setopt$chCURLOPT_POSTFIELDS$PostData ); //Отправить данные
curl_exec$ch );
curl_close$ch );
?>

Сразу следует обратить внимание, в данном примере мы использовали библиотеку CURL, которая делает передачу данных достаточно простой. Тем не менее, наличие установленной библиотеки зависит от хостера. Именно поэтому рассмотрим скрипт выполняющий аналогичные функции.

<?php
$data 
= array( "login"=>"vasya""password"=>"PaSsWoRd""submit"=>"Войти" );
while( list(
$name$value) = each($data) ) {
  
$temp[] = urlencode($name)."=".urlencode($value);
}
$PostData = implode("&"$temp);

$fp fsockopen("some.site.ru",80,$errno,$errstr,30);
if( 
$fp ) {
  
fputs$fp,"POST /auth.php HTTP/1.0\r\n" );
  
fputs$fp,"Referer: http://some.site.ru\r\n" );
  
// Если используется метод GET, следующие две строки не нужны, также не нужна строка
  // "fputs($fp,$PostData);", а данные передаются вместе с адресом страницы, например:
  // fputs($fp,"GET /auth.php?login=vasya&password=PaSsWoRd&submit=%C2%EE%E9%F2%E8 HTTP/1.0\r\n");
  
fputs$fp"Content-Type: application/x-www-form-urlencoded\r\n" );
  
fputs$fp"Content-Length: ".strlen($PostData )."\r\n" );
  
fputs$fp,"Host: some.site.ru\r\n" );
  
fputs$fp,"User-Agent: Opera/7.54 (Windows 98; U) [ru]\r\n\r\n" );
  
fputs$fp,$PostData );
  while( !
feof$fp ) ) {
    echo 
fgets($fp,1024);
  }
  
fclose($fp);
}
?>

Во всех выше приведенных примерах мы выводим результат импорта сразу в браузер, однако, на практике этот результат требуется записать в переменную для последующей обработки. И если в первом скрипте достаточно заменить "echo " на "$varname=", то к остальным примерам такое решение едва ли подойдёт, даже если оно и кажется вам очевидным. Дело в том, конструкция вроде

<?php
$varname 
'';
while( !
feof$fp ) ) {
  
$varname .= fgets$fp1024 );
}
?>

являет собой ничто иное, как многократную дозапись в переменную, а это в свою очередь замедляет работу скрипта. Тем более, что в случае с CURL такая возможность не доступна вообще. Решением является использование функций управления выводом: в начале скрипта вы пишите

ob_start();

а в конце

$varname ob_get_contents();
ob_end_clean();

А если сайт-экспортёр использует HTTP-аутентификацию? Вы строите обычный GET-запрос к нужной странице добавив один заголовок:

fputs$fp"Authorization: Basic ".base64_encode("vasya:PaSsWoRd")."\r\n" );

Соответственно для CURL

curl_setopt$chCURLOPT_USERPWDbase64_encode("vasya:PaSsWoRd") );

Если требуется использовать при обращении прокси-сервер, для скрипта использующего CURL вам следует добавить следующую строку:

curl_setopt$chCURLOPT_PROXY'0.0.0.0:80' );

где соответственно "0.0.0.0" - это IP-адрес прокси-сервера, а "80" - порт. Для варианта с сокетом вы в функции fsockopen() указываете параметры подключения к прокси-серверу (адрес и порт), а всё остальное оставляете без изменений. Наконец, получив страницу в переменную, вам наверняка потребуется её обработать. Для этого можно порекомендовать почитать раздел мануала "Функции регулярных выражений (Perl-совместимые)", этот инструмент отлично подходит для решения подобных задач.

Автор: Бажанов Артём