Help me! file_put_contents & stream_context_create
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 лет назад
А места точно хватает на сервере? 
12 сообщений
#14 лет назад
Hungry_Hunter, да, памяти хватает. Темболее тестировал с несколькими серверами.
Работаю с маленькими файлами (5-30 Кб)
12 сообщений
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);
Вот очень простой пример, без проверок ошибок и т.д. Демонстрация параллельных закачек, с возможностью выполнения некоторого кода в текущем скрипте.