Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Help. Как через PHP передать файл

4.5K
06 сентября 2003 года
Kasper1985
18 / / 06.09.2003
Люди, кто знает, подскажите!
Мне нужно через PHP с сервера передать файл на другую машину, желательно по частям!
Заранее благодарен.

PS. Если сможете, то скинте какие-нибудь исходники мне на мыло [email]Kasper1985@rambler.ru[/email]
1.8K
06 сентября 2003 года
2NetFly
132 / / 01.09.2003
По какому протоколу?
4.5K
08 сентября 2003 года
Kasper1985
18 / / 06.09.2003
Цитата:
Originally posted by 2NetFly
По какому протоколу?



По протоколу TCP/IP. Надо передать через HTTP.

283
08 сентября 2003 года
Alone
910 / / 20.11.2002
А другая машина это тоже веб-сервер?
4.5K
08 сентября 2003 года
Kasper1985
18 / / 06.09.2003
Вроде как да!
Я выполнил просьбу моего приятеля «RTFM», но мне всё ещё не понятно как это делаеться. В хелпе я прочитал, что нужно при помощи сокетов это делать.
Но у меня проблемы с REQUEST'ом. Я записываю в сокет socket_write($socket, $in, strlen($in));
где $socket — ресурс, а $in — 'Get /XXX\r\nHost: XXX\r\n\r\n';
В результате socket_read(...)выдаёт ошибку...
Может я что-то не то делаю?..:(
1.8K
08 сентября 2003 года
2NetFly
132 / / 01.09.2003
Цитата:
Originally posted by Kasper1985
socket_write($socket, $in, strlen($in));
где $socket — ресурс, а $in — 'Get /XXX\r\nHost: XXX\r\n\r\n';


Так ты определись: тебе получить файл нужно или отправить?
Выше ты пытаешься его получить методом GET.

4.5K
08 сентября 2003 года
Kasper1985
18 / / 06.09.2003
Цитата:
Originally posted by 2NetFly

Так ты определись: тебе получить файл нужно или отправить?
Выше ты пытаешься его получить методом GET.



Если честно, то и то и другое. GET - это была первая версия, так сказать «сделать хот что нибудь». К стати, я не сказал какая именно ошибка:

Method Not Implemented,
Invalid method in request Get /1/1/car29.MTX HTTP/1.1

Так всё-таки подскажите!!!

1.8K
08 сентября 2003 года
2NetFly
132 / / 01.09.2003
Читай.
http://forum.codenet.ru/showthread.php?s=&threadid=12475
4.5K
11 сентября 2003 года
Kasper1985
18 / / 06.09.2003
Цитата:
Originally posted by 2NetFly
Читай.
http://forum.codenet.ru/showthread.php?s=&threadid=12475



Привет! Наверное, я что-то не так объяснил. Вот всё, что есть:

ЗАДАЧА

Клиент запрашивает сценарий на PHP с сервера 1, передаёт в него параметр — имя файла.

Сценарий подключается к серверу 2 и запрашивает с него нужный файл, после чего возвращает его клиенту в отклике вместе с пришедшими заголовками (content-type, content-length и другими).

То есть, получается что-то вроде веб-менеджера закачек, такой себе «байтопровод».


ПРОБЛЕМА

При загрузке файлов по HTTP с сервера 2 и возврате их клиенту в файлах происходят изменения. Например, картинки не выводятся.

Для проверки одновременно с возвратом данных в отклике я записываю их в файл на диске. В файл всё записывается нормально, а в отклике есть какие-то ошибки.

Предположительно, проблема возникает из-за того, что сценарий на PHP не закрывает подключение, и браузер считает, что связь прервалась и данные не догружены.

До того, как стал указывать Content-Length, в конце файла появлялась строчка «Maximum script execution time exceded».

Пробывал добавлять в конец сценария die(), но ничего не меняется.

From Kasper UA

250
11 сентября 2003 года
Joker
1.4K / / 20.02.2000
Цитата:
Originally posted by Kasper1985



При загрузке файлов по HTTP с сервера 2 и возврате их клиенту в файлах происходят изменения. Например, картинки не выводятся.

From Kasper UA



А что за место картинки путь какой ?

А для чего все это надо ? (ты реализуешь аналог echo file("http:\\что то ");

4.5K
11 сентября 2003 года
Kasper1985
18 / / 06.09.2003
Цитата:
Originally posted by Joker


А что за место картинки путь какой ?

А для чего все это надо ? (ты реализуешь аналог echo file("http:\\что то ");



Получение какртинки идёт через запрос:
GET /бла-бла-бла /HTTP1.1\r\nHOST: бла-бла-бла\r\n...\r\n\r\n.

Я написал раньше это что-то вроде «байтопровода».
Т. е. сценарий берёт большой файл с сервера и по кускам передает клиенту, через промежуточный сервер.

250
11 сентября 2003 года
Joker
1.4K / / 20.02.2000
Цитата:
Originally posted by Kasper1985


Получение какртинки идёт через запрос:
GET /бла-бла-бла /HTTP1.1\r\nHOST: бла-бла-бла\r\n...\r\n\r\n.

Я написал раньше это что-то вроде «байтопровода».
Т. е. сценарий берёт большой файл с сервера и по кускам передает клиенту, через промежуточный сервер.


А можешь сюда кусок кода закинуть ?
Или прикрепи хочу заценить, а то так тяжело обсуждать.

4.5K
11 сентября 2003 года
Kasper1985
18 / / 06.09.2003
Цитата:
Originally posted by Joker

А можешь сюда кусок кода закинуть ?
Или прикрепи хочу заценить, а то так тяжело обсуждать.



Вот, любуйся:

<?php
//error_reporting (E_ALL);
error_reporting (0);
//header('Content-Type: text/plain');
header('Content-Type: image/jpeg');

$service_port = 80;
$address = '192.168.0.1';

//Создание нового сокета, для отсылани запроса
$socket = socket_create (AF_INET, SOCK_STREAM, getprotobyname("TCP"));
if (!$socket)
{
header('Content-Type: text/html');
die('Creating socket failed:
Reason: '.socket_strerror(socket_last_error($socket)).'
');
}

//Соединение с сервером через созданый сокет
$result = socket_connect ($socket, $address, $service_port);
if (!$result)
{
header('Conten-Type: text/html');
die('Connecting socket failed.
Reason: '.socket_strerror(socket_last_error($socket)).'
');
}

//Передача запроса
$request="GET /1/stone.jpg HTTP/1.1\r\nHost: studio_server\r\n\r\n";
socket_write ($socket, $request, strlen ($request));

/*
Далее я делаю проверку на первое чтение 256 байт,
после чего я определяю длину файла.
По мере скаченого куска файла, яизменяю размер того,
сколько ещё осталось скачать, после чего заканчиваю чтение.
Каждый последующий скаченый кусок я одновременно записываю в
файл и хтмл страницу.
В итоге при просмотре файла всё нормально, а при просмотре
на странице искажёная картинка!!!
*/
$flag=true;
$flag_file=false;
$size=0;
$first=false;
$file=fopen('C:\\file_get.jpg', 'w');
while ($flag)
{
if(!$first)
$out=socket_read($socket, 256, PHP_BINARY_READ);
else
$out=socket_read($socket, 32, PHP_BINARY_READ);

if($flag_file)
{
fwrite($file, $out);
echo $out;
$size-=32;
if($size<=0)
{
$out=socket_read($socket, 64, PHP_BINARY_READ);
fwrite($file, $out);
echo $out;
$flag=false;
}
}

if(!$first&&$pos_begin=strpos($out, 'Content-Length: ')+16)
{
$length=strpos($out, "\n", $pos_begin)-$pos_begin;
$length=substr($out, $pos_begin, $length);
// header('Content-Length: '.$length);
$size=$length-256;
$pos=strpos($out, "\n\r\n")+3;
fwrite($file, substr($out, $pos));
echo substr($out, $pos);
$flag_file=true;
$first=true;
}

if(substr($out, strlen($out)-8)!="\n\r\n0\r\n\r\n"&&!$flag_file)
echo $out;
else if(!$flag_file)
{
echo substr($out, 0, strlen($out)-8);
$flag=false;
}
}
fclose($file);

socket_close ($socket);

//die("\n\r\n0\r\n\r\n");
?>

250
11 сентября 2003 года
Joker
1.4K / / 20.02.2000
вот эту строчку вообще не понял:
if(!$first&&$pos_begin=strpos($out, 'Content-Length: ')+16)

особенно это: $pos_begin=strpos($out, 'Content-Length: ')+16 а почему 16 ? и что это вообще ?

заодно и этот иф непонял:

if(substr($out, strlen($out)-8)!="\n\r\n0\r\n\r\n"&&!$flag_file)

если не трудно объясни :)
4.5K
12 сентября 2003 года
Kasper1985
18 / / 06.09.2003
Поясняю:

В «вайле» я предусматриваю вывод списка файлов и передачу самого файла.

Флаг $flag отвечает за конец передачи файла. Как он изменяется, я объясню позже.
Флаг $file_flag устанавливается в true, если передаётся файл. Как это происходит?

В этой самой строке

if(!$first&&$pos_begin=strpos($out, 'Content-Length: ')+16)

я функцией strpos определяю, передаётся ли Content-Length. Если да, то это значит, что передаёться файл. Чтобы определить его длину, а следовательно и количество итераций «вайла» и не вызывать повторно strpos я сразу записываю в $pos_begin позицию начала информации о длине. +16 это необходимое смещение, чтобы не получать 'Content-Length: ххх', а получить номер первого символа длины. После этого я нахожу символ перехода на следующую строку, а значит и конец числа. Таким образом я получаю длину файла, после чего я записываю её в переменную $size.

Флаг $first у меня стоит в положении false только одну итерацию, после чего меняется на true, что позволяет мне единыжды прочитать 256 байт, для того чтобы захватить заголовок, но это только сейчас как черновой вариан, потому что заголовок может меняться как угодно и это не универсальный код.

После я нахожу "\n\r\n", что говорит мне о том что начался сам файл. Далее я начинаю уменьшать $size на количество прочитанных байт и когда значение этой переменной станет меньше либо равно 0, я устанавливаю флаг $flag в положение ложь, что свидетельствует об окончании чтения.

Если же передаётся список файлов, то в заголовке уже не указывается Content-Length, а значит я должен каким либо другим образом фиксировать конец передачи.

При передаче списка файлов, конец передачи передаётся таким набором символов "\n\r\n0\r\n\r\n".
Этим ифом
if(substr($out, strlen($out)-8 )!="\n\r\n0\r\n\r\n"&&!$flag_file)

я, опять таки, пытаюсь фиксировать конец передачи информации, что позволяет мне изменить значение $flag.
4.5K
12 сентября 2003 года
Kasper1985
18 / / 06.09.2003
Люди, есть небольшой успех.
После того как я немного усовершенствовал код, т. е. сделал его более понятным и уже менее черновым, то получил новые результаты. Теперь картинка, которую я получаю, отображается нормально в броузере, н при условии, что я её передаю всю целиком и сразу. Вот преобразованный код считывания файла:

$file_begin=false;
$response='';
$header='';
$file_size=0;

do
{
$response.=socket_read($socket, 32, PHP_BINARY_READ);//Считываем по 32 байта
if($pos=strpos($response, "\n\r\n"))//Если закончена передача заголовка
{
$pos+=3;//Смещение на начало данных самого файла
$length_begin=strpos($response, 'Content-Length: ')+16;//Нахождение начала инфы о длине
$length_end=strpos($response, "\n", $length_begin);//Нахождение конца инфы о длине
$length_count=$length_end-$length_begin;//Получение длины строки инфы о размере файла
$length=substr($response, $length_begin, $length_count);//Получение размера файла
$file_size=$length;//Сохранение размера файла в глобальную переменную
$header=substr($response, 0, $pos-3);//Сохранение содержимого заголовка
$response=substr($response, $pos);//Содержимое самого файла
// echo $response; //Вывод содержимого файла на экран
$file_size-=strlen($header);//Подсчет оставшихся байт файла
$file_begin=true;
}
} while(!$file_begin); //Заголовок прочитан и отделён от содержимого файла

while($file_size>0)//Читать пока ещё что-то не прочитано
{
$data=socket_read($socket, 32, PHP_BINARY_READ);//Считываем по 32 байта
$response.=$data;//Записываем как общее содержимое
$file_size-=32;//Подсчет оставшихся байт файла
// echo $data;//Вывод на экран куска файла, размером в 32 байта
}

socket_close ($socket);

echo $response;

Тут помоему всё должно быть понятно!
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог