Я пытаюсь записать значительный кусок данных в файл, который открывается через fopen() в php. Оболочка протокола, которую я использую, — это ftp, поэтому файл удален от сервера, на котором запущен php-код. Файл, в который я пишу, находится на сервере Windows.
Я убедился, что файл на самом деле создается моим php-кодом, но проблема в том, что данные в файле либо не существуют (0 КБ), либо запись в файл останавливается преждевременно. Не уверен, почему это так.
Вот код, который я использую для обработки операции:
$file_handle = fopen($node['ftp'].$path_to_lut, "wb", 0, $node['ftp_context']);
include_once($file);
if ($file_handle)
{
fwrite($file_handle, $string); //$string is inside included $file
fclose($file_handle);
} else {
die('There was a problem opening the file.');
}
Этот код отлично работает, когда я размещаю его на своем локальном компьютере, но когда я загружаю его на свой веб-хост (Rackspace Cloud), он не работает. Это заставляет меня поверить, что это проблема, связанная с конфигурацией моего сервера в Rackspace, но я хочу знать, могу ли я что-нибудь сделать с моим php-кодом, чтобы сделать его более надежным.
Есть идеи, как убедиться, что fwrite действительно заканчивает запись строки на удаленную машину?
Спасибо!
Хорошо, я изменил код, который записывает в файл, вот так:
if ($file_handle)
{
if ($bytesWritten = fwrite($file_handle, $string) ) {
echo "There were " . $bytesWritten . " bytes written to the text file.";
}
if (!fflush($file_handle)) {
die("There was a problem outputting all the data to the text file.");
}
if (!fclose($file_handle)) {
die("There was a problem closing the text file.");
}
} else {
die("No file to write data to. Sorry.");
}
Странно то, что инструкция echo показывает следующее:
В текстовый файл было записано 10330 байт.
И все же, когда я проверяю размер текстового файла через FTP, он показывает, что он равен 0 КБ, а данные внутри файла фактически усекаются. Я не могу представить, что это связано с самим FTP-сервером, потому что он работает, если PHP размещен на машине, отличной от той, что находится в Rackspace Cloud.
** ОБНОВЛЕНИЕ ** Я разговаривал с представителем Rackspace Cloud, который упомянул, что им требуется пассивный ftp, если вы собираетесь использовать ftp с их серверов. Я настроил удаленный сервер для обработки пассивных ftp-соединений и убедился, что пассивный ftp теперь работает на удаленном сервере через ftp-клиент OSX Transmit. Я добавил:
ftp_pasv($file_handle, true);
Сразу после оператора fopen() я получаю сообщение об ошибке от PHP, говорящее, что я не предоставил действительный ресурс для ftp_pasv(). Как я могу гарантировать, что соединение с ftp-сайтом, которое делает PHP, является PASV, а не ACTIVE, и по-прежнему использовать fwrite()? Между прочим, я заметил, что Windows-машина сообщает, что файл, записываемый моим PHP-кодом, имеет размер 4096 байт на диске. Больше этой суммы никогда не бывает. Это заставило меня изменить значение php output_buffering на 65536 только для устранения неполадок, но это также не решило проблему. . .
** ОБНОВЛЕНИЕ ЧАСТИ DUEX **
Устранение неполадок на моем виртуальном сервере в продукте Rackspace Cloud Sites оказалось слишком сложным, поскольку они не предлагают достаточных прав администратора. Я создал очень маленький облачный сервер на продукте Rackspace Cloud Server и настроил все так, что все еще вижу ту же ошибку с fwrite(). Чтобы убедиться, что я могу записать файл с этого сервера на удаленный сервер, я использовал основные команды ftp в моей оболочке bash на облачном сервере. Это работало нормально. Итак, я предполагаю, что в php-реализации fwrite() есть ошибка, и что это, вероятно, связано с какой-то проблемой регулирования данных. Когда я пишу на удаленный сервер из своей локальной среды, которая имеет медленную скорость по сравнению с тем, что предлагается на сервере Rackspace Cloud, все работает нормально. Есть ли способ эффективно снизить скорость записи? Просто спрашиваю :)
** ОБНОВЛЕНИЕ ЧАСТИ III *
Итак, я воспользовался предложением @a sad dude и реализовал функцию, которая может помочь кому-то, пытающемуся записать новый файл, и полностью отправить его по ftp:
function writeFileAndFTP($filename=null, $data=null, $node=null, $local_path=null, $remote_path=null)
{
// !Determin the path and the file to upload from the webserver
$file = $local_path.'/'.$filename;
// !Open a new file to write to on the local machine
if (!($file_handle = fopen($file, "wb", 0))) {
die("There was a problem opening ".$file." for writing!");
}
// !Write the file to local disk
if ($bytesWritten = fwrite($file_handle, $data) ) {
//echo "There were " . $bytesWritten . " bytes written to " . $file;
}
// !Close the file from writing
if (!fclose($file_handle)) {
die("There was a problem closing " . $file);
}
// !Create connection to remote FTP server
$ftp_cxn = ftp_connect($node['addr'], $node['ftp_port']) or die("Couldn't connect to the ftp server.");
// !Login to the remote server
ftp_login($ftp_cxn, $node['user'], getPwd($node['ID'])) or die("Couldn't login to the ftp server.");
// !Set PASV or ACTIVE FTP
ftp_pasv($ftp_cxn, true);
// !Upload the file
if (!ftp_put($ftp_cxn, $remote_path.'/'.$filename, $file, FTP_ASCII)) {
die("There was an issue ftp'ing the file to ".$node['addr'].$remote_path);
}
// !Close the ftp connection
ftp_close($ftp_cxn);
}
include_once($file);
- где этот код? - person hakre   schedule 28.02.2012$string = "a string about 20 lines long";
- person ariestav   schedule 28.02.2012var_dump($node['ftp_context']);
? (удалить логин/пароль). - person hakre   schedule 28.02.2012var_dump(stream_get_meta_data($file_handle));
выводит:array(10) { ["wrapper_data"]=> NULL ["wrapper_type"]=> string(3) "ftp" ["stream_type"]=> string(14) "tcp_socket/ssl" ["mode"]=> string(2) "r+" ["unread_bytes"]=> int(0) ["seekable"]=> bool(false) ["uri"]=> string(119) "ftp://user:[email protected]:21/vars.txt" ["timed_out"]=> bool(false) ["blocked"]=> bool(true) ["eof"]=> bool(false) }
- person ariestav   schedule 28.02.2012fflush($file_handle);
над закрытием. Также вам нужно проверить возвращаемые параметры всех этих функций, потому что они сообщат вам, если они потерпели неудачу, например. еслиfclose
не удалось успешно закрыть. См. руководство для каждой функции и их возвращаемых значений. - person hakre   schedule 28.02.2012