16:09 

Очередная бредня...

Джей Ди
Всё будет Кока-Кола.
Исходники:
Мой вариант
Вариант Nuclear Snow

У каждого PHP програмиста наступает момент когда ему очень хочется написать свой класс для работы с HTTP... я долго ждал, решил вот немного накидать. Критика привествуется.
Исходный класс:

class gsocket
{
var $CONNECTION=FALSE;
var $STREAM;
var $METHOD='GET';
var $POST = ARRAY();
var $GET = ARRAY();

var $COOKIES = ARRAY();
var $PROTOCOL = ARRAY('TYPE' => 'HTTP','VERSION' => '1.0', 'PORT' => 80);

//Заголовки соединения
var $HEADERS=ARRAY();

//Инициализация
function gsocket()
{
//Генерируем заголовки
$HEADERS=&$this->HEADERS;
$HEADERS['Connection']='Close';
$HEADERS['Referer']='';
$HEADERS['Host']='';
$HEADERS['User-Agent']='grex-gsockets/1.2';
$HEADERS['Cache-Control']='no-cache';
}


//Выдача сформированных заголовков
function headers()
{
//Заголовки для посылки
$HEADERS='';

$COOKIES='';
FOREACH($this->COOKIES AS $NAME => $PROPERTY)
$COOKIES.="$NAME=$PROPERTY;";

//Кукисы
$this->HEADERS['сoоkiе']=$COOKIES;

//Генерируем заголовки
FOREACH($this->HEADERS AS $NAME => $PROPERTY)
IF($PROPERTY) $HEADERS.="$NAME: $PROPERTY\r\n";
RETURN $HEADERS;
}

function get_extract($QUERY_STRING)
{
$RESULT=ARRAY();
IF(!$QUERY_STRING) RETURN $RESULT;
FOREACH(EXPLODE('&', $QUERY_STRING) AS $QUERY)
{
$QUERY=LTRIM($QUERY);
IF(!STRPOS($QUERY,'=')) $RESULT[$QUERY]=''; ELSE $RESULT[SUBSTR($QUERY,0,STRPOS($QUERY,'='))]=RAWURLDECODE(SUBSTR($QUERY,STRPOS($QUERY,'=')+1));
}
UNSET($QUERY);
RETURN $RESULT;
}

function make_get_string($ARRAY)
{
$RESULT='';
FOREACH($ARRAY AS $NAME => $DATA)
{
IF($DATA) $DATA='='.RAWURLENCODE($DATA);
$RESULT.='&'.$NAME.$DATA;
}
RETURN SUBSTR($RESULT,1);
}


function setcookie($NAME,$PROPERTY)
{
$this->COOKIES[$NAME]=$PROPERTY;
}

function clean($ARRAY)
{
$this->$ARRAY=ARRAY();
}



function post($DATAS)
{
$this->POST=ARRAY_MERGE($this->POST,$DATAS);
}




function connect($REQUEST_URI)
{
//Закрываем предыдущий сеанс
$this->close_connection();

//Получаем сотавляющие адреса
PREG_MATCH("/(http:\/\/){0,1}(www\.){0,1}([^\/]+)\/{0,1}([^\?]*)\?{0,1}(.*)$/",$REQUEST_URI,$MATCHES);
$this->HEADERS['Host']=$MATCHES[3];
//Запрашиваемый скрипт
$sсript_NAME=$MATCHES[4];
//Строка запроса

$QUERY_STRING=$MATCHES[5];

$TEMP_GET=$this->GET=$this->get_extract($QUERY_STRING);
FOREACH($TEMP_GET AS $NAME => $PROPERTY)
$this->GET[$NAME]=$PROPERTY;

$QUERY_STRING=$this->make_get_string($this->GET);

IF($QUERY_STRING) $QUERY_STRING='?'.$QUERY_STRING;

//Создаем основной заголовок
$HEADERS=$this->METHOD." /$sсript_NAME$QUERY_STRING ".$this->PROTOCOL['TYPE'].'/'.$this->PROTOCOL['VERSION']."\r\n".$this->headers();

IF($this->METHOD=='POST')
{
$POST_DATAS=$this->make_get_string($this->POST);
//Дополнительные заголовки для POST
$HEADERS.="Content-Type: application/x-www-form-urlencoded\r\nContent-length:".STRLEN($POST_DATAS)."\r\n\r\n";
$HEADERS.=$POST_DATAS;
}
ELSE $HEADERS.="\r\n";



//Посылаем запрос

IF(!@$this->STREAM=FSOCKOPEN($this->HEADERS['Host'],$this->PROTOCOL['PORT'],$ERROR)) RETURN FALSE;
ELSE
{
FWRITE($this->STREAM,$HEADERS);
$this->CONNECTION=TRUE;
}
RETURN TRUE;
}

function close_connection()
{
$this->CONNECTION=FALSE;
@FCLOSE($this->STREAM);
}

function read($LENGTH)
{
IF($this->CONNECTION) RETURN FREAD($this->STREAM,$LENGTH);
RETURN FALSE;
}

function rfull()
{
//Читаем полностью
$RESULT='';
WHILE(!FEOF($this->STREAM))
$RESULT.=FREAD($this->STREAM,256);
$this->close_connection();
RETURN $RESULT;
}
}



А вот пример использования:

$f = new gsocket();
$f->setcookie('user_login','%E2%EE%EB%F7%EE%ED%EE%EA+%E4%E6%E5%E9');
$f->setcookie('user_pass','пароль');

$f->connect('pda.diary.ru/member/?'.(1*@$_GET['id']).'&fullreaderslist&fullfavoriteslist');

echo $f->rfull();

//Можно и не закрывать
$f->close_connection();


Что умеет (ну это наверно умеют все подобные классы):
- Посылать GET запросы
- Посылать POST запросы (в старой форме, мультипарт можно дописать)
- Устанавливать куки
- Модифицировать запросы

@темы: PHP, Разное

Комментарии
2008-09-17 в 16:16 

Джей Ди
Всё будет Кока-Кола.
Извиняюсь, код немного подпортился... похоже пропали некоторые переносы...
Рабочий пример тут.
А скачать можно здесь.

2008-09-17 в 16:37 

Да,подобный код делали наверное многие. И у меня лежит два подобынх класса (для HTTP и для SMTP) .И хотя код вполне универсален (я был удивлен, увидев совместимость с php 4 ) и использует простые сокеты,все же надежность у него невысока. Проверено на опыте,что код основанный на fsockopen не всегда хорошо работает (соединение теряется и т.п. ). Хотя для простых скриптов этого достаточно.

2008-09-17 в 16:41 

Джей Ди
Всё будет Кока-Кола.
[NOMAD] в принципе, он разрабатывался как парент класс. Т.е. доращивание планируется, а насчет надежности - это да. Но у меня, к счастью, не было никаких проблем с массовыми гейтами, следовательно навороты не трубуются.

2008-09-17 в 22:08 

Nuclear Snow
Never Say Never (c)
я кстати писал уже тут про свою)
сслыка правда сдохла но кто интересуется я могу перезалить =)
тред был www.diary.ru/~phpmysql/p40154183.htm

2008-09-18 в 00:06 

Джей Ди
Всё будет Кока-Кола.
Nuclear Snow ну по моим данным это традиция. =) Попробуй перезалить, интересно посмотреть творения других.

2008-09-18 в 00:48 

Гм... Вспомнил,что когда то писал класс HTTP-клиента на C++ (под Qt),а потом его версию на PHP. Правда php-версия была не дописана. Но там были некоторые полезные возможности : поддержка HTTP-прокси,поддержка туннелей из прокси, корректная обработка Transfer-Encoding: chunked ,поддержка gzip/zlib сжатия ... Думаю,может дописать и выложить.Вдруг кому нибудь понадобится.

2008-09-18 в 13:24 

Джей Ди
Всё будет Кока-Кола.
Поддержку Гзип я уже почти дописал, и монтажнуть прокси тоже в планах, дальше больше. =) Но мудрить особо не хочется - нужно сделать класс гибким, но простым.

2008-09-18 в 22:29 

Nuclear Snow
Never Say Never (c)
Перезалил
narod.ru/disk/2677951000/raw_req_v1.11.zip.html
по поводу традиции - ну а что тут.. все логично.. хорошая тема что бы обучиться работе с сокетами и проблемы с ними - таймауты, обрывы и прочее...

2008-09-18 в 22:36 

[NOMAD] [DELETED user]
Имхо, но работе с сокетами лучше учится на C/C++ )))

2008-09-18 в 22:54 

Джей Ди
Всё будет Кока-Кола.
Nuclear Snow да-да, при должной модернизации можно написать очень даже неплохой класс. Кинь мне файлик на мыло, что-то народ не хочет мен его выдавать, выложу куда получше (wolfy [фас!] mail.by).
[NOMAD] для начала можно и так. Более мошьные инструменты пишук уже команды, а там пхп и не нужен.

2008-09-18 в 23:16 

Nuclear Snow
Never Say Never (c)
выслал

   

Сообщество PHP программистов

главная