Дмитрий Г.
12 сообщений
#14 лет назад
Нужно перезаписать файл на FTP сервере.
Файл перезаписывается, ошибки не выподают. Но конец файла обычно не записывается (теряется), а иногда может записаться весь!

Что это может быть? Кто-то уже решал такую проблему?
Пробывал через fopen, fwrite, fclose - результат тотже, что и с file_put_contents


$stream_options = array('ftp' => array('overwrite' => true));
$stream_context = stream_context_create($stream_options);
file_put_contents($fileName, $upContents, false, $stream_context) or
$this->logMessage .= '<h3 style="color: red;">Ошибка!</h3>';


Pls HELP MEEEE!
Артем Л.
11416 сообщений
#14 лет назад
А места точно хватает на сервере?
Вадим Т.
3240 сообщений
#14 лет назад
Попробуйте CURL:
Дмитрий Г.
12 сообщений
#14 лет назад
Hungry_Hunter,
да, памяти хватает. Темболее тестировал с несколькими серверами.

Работаю с маленькими файлами (5-30 Кб)
Дмитрий Г.
12 сообщений
#14 лет назад
tvv,

спс, когда сделаю отпишу о результатах
Дмитрий Г.
12 сообщений
#14 лет назад
Написал простую функцию (пока только загатовка) по статье
работает стабильно, тестировал много на разных серверах (файлы грузил от 1Кб до 20 Мб)



/**
* безопасная загрузка файлов на FTP сервер
*
* @var string $contents: контент который нужно записать в файл на FTP сервере
* @var string $ftpFile: синтаксис ftp://ftp_login:***/
* @return bool: false - ошибка, true - все в порядке
*/
function uploadFile($contents, $ftpFile) {
if (!empty($contents) and !empty($ftpFile)) {
$localFile = 'tepmFileUp' . time() . '.txt';
file_put_contents($localFile, $contents);

$ch = curl_init ();
$fp = fopen ( $localFile, 'r' );

curl_setopt ( $ch, CURLOPT_URL, $ftpFile );
curl_setopt ( $ch, CURLOPT_UPLOAD, 1 );
curl_setopt ( $ch, CURLOPT_INFILE, $fp );
curl_setopt ( $ch, CURLOPT_INFILESIZE, filesize ( $localFile ) );

curl_exec ( $ch );
$error_no = curl_errno ( $ch );
curl_close ( $ch );
fclose($fp);
unlink($localFile);

if ($error_no == 0) {
return true;
} else {
return false;
}
} else {
return false;
}
}


$contents = file_get_contents('tempFile.txt');
$ftpFile = 'ftp://ftp_login:***/';

if (uploadFile($contents, $ftpFile) == true) {
echo 'All right!';
} else {
echo 'Error!';
}
Вадим Т.
3240 сообщений
#14 лет назад
GeniusIsSimple, зачем же Вы создаете временный файл. И еще и возможных ошибок (вдруг временный файл не создастся?) не обрабатываете...
Просто исходный файл 'tempFile.txt' сразу отправляйте через CURL, без создания ненужного временного файла.

Кстати, CURL интересен тем, что, если захотите, с его помощью можно аплоадить несколько файлов одновременно, и более того, можно даже аплоадить параллельно выполнению текущего PHP скрипта (то есть выполнять некий PHP код параллельно с закачкой).
Николай Т.
205 сообщений
#14 лет назад
Цитата ("tvv"):
(то есть выполнять некий PHP код параллельно с закачкой).

ойли??? пример кода можно? (может я не верно понял твои слова)
Вадим Т.
3240 сообщений
#14 лет назад
Цитата ("e1it3"):
ойли??? пример кода можно? (может я не верно понял твои слова)

Пожалуйста, гуглите по слову multicurl. Там же найдете и примеры кода.

Как это работает, попробую объяснить. Сначала в общем.

Чтобы небыло недопонимания, сразу скажу, что чудес не бывает, и от PHP не стоит ждать потоков, нитей и т.д. (за исключением pcntl).
Но зато выполнять некий код между скачиванием/закачиванием курлом очередной порции данных вполне можно, и, хотя это и не абсолютно "параллельно", но условно можно считать так. Скажем, внешне это очень похоже на прерывания в однопроцессном приложении.

Это имеет смысл делать на больших долгих закачках. При этом запускается сразу большое количество скачиваний одновременно, а в основном скрипте периодически вызывается код, который эти закачки мониторит.
Самая распространенная цель - чтобы не загрузить больше, чем, например, установлен лимит (например, хотим получить файл не более чем 200 килобайт, а на вход приходит 200 мегабайт, хотя заранее мы не знаем сколько получим), или скрипт может давать пользователю возможность остановить закачку в любой момент, и т.д.

Учебный пример кода ниже.
Вадим Т.
3240 сообщений
#14 лет назад
<?php

function monitor($mh, $chs)
{
// тут может быть некий код, например проверяющий сколько чего скачалось, или
// помещающий в БД то, что успело скачаться на данный момент из параллельных закачек,
// или берущий из диспетчера тасков какие-либо мелкие таски на выполнение и т.д.
//
// если же выполнять сторонний код не нужно, а нужно только пассивно ждать завершения
// закачек, то вместо этого перед curl_multi_exec лучше вызывать curl_multi_select($mh).

foreach ($chs as $ch) {
print_r(curl_getinfo($ch));
}
}

$urls = array(
';,
';
);

$mh = curl_multi_init();

$chs = array();

foreach ($urls as $url) {
$chs = $ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
curl_multi_add_handle($mh, $ch);
}

while (true) {
$mrc = curl_multi_exec($mh, $active);
if (!$active || $mrc !== CURLM_CALL_MULTI_PERFORM && $mrc !== CURLM_OK) break;

monitor($mh, $chs);
}

foreach ($chs as $ch) {
print_r(curl_multi_getcontent($ch));

curl_multi_remove_handle($mh, $ch);
curl_close($ch);
}

curl_multi_close($mh);

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