Я пытаюсь загрузить несколько файлов на сайт SFTP из локального каталога.
Я могу заставить его работать для одного файла, но я хотел бы иметь возможность загружать несколько файлов, которые также имеют имена переменных.
$localFile_xml = "C:\xml\Race_" . $value;
chdir($localFile_xml);
//This successfully lists the files
foreach (glob("*.xml") as $filename) {
echo "$filename size " . filesize($filename) . "\n";
}
$remote_XMLfiles = "/FTP/XML/Race_" . $value;
$xmlstream = fopen("ssh2.sftp://$sftp" . $remote_XMLfiles, 'w');
foreach (glob("*.xml") as $filename) {
$xmlfile = file_get_contents($localFile_xml);
fwrite($xmlstream, $xmlfile);
fclose($xmlstream);
}
Я верю, что он есть, но я не могу правильно понять последний бит.
Огромное спасибо заранее
Спасибо за помощь, к сожалению, это не помогло.
Запутался в том, чего именно вы пытаетесь достичь. Похоже, ваш код повторно записывает одни и те же данные $xmlfile в $xmlstream. но вообще не использует $filename в итерации foreach к $xmlstream и не изменяет файлы $xmlstream. file_get_contents($localFile_xml) должен возвращать false, так как это похоже на каталог. Удаленный файл уже существует или его следует создать, если нет? Пожалуйста, обновите вопрос, указав свой функциональный код одного файла.
Привет, вы, вероятно, правы, что мой код повсюду, я новичок в кодировании и выше моих сил в том, чего я пытаюсь достичь. Итак, я пытаюсь загрузить все XML-файлы из папки на локальном сервере в уже созданную папку на безопасном FTP-сервере. Мне удалось сделать один файл одновременно, но этот подход неэффективен. Спасибо
Что вы подразумеваете под "не помогло", каков был эффект? Потому что Фырье прямо здесь. Прежде чем двигаться дальше, вы должны включить отчет об ошибках, потому что он просто предполагает обратное. Угадывание для детей.






Предполагая, что удаленное SSH-соединение допустимо и что метод, который вы использовали в своем вопросе, работает для отдельных файлов, я считаю, что ваш порядок операций необходимо исправить.
Как упоминалось в моих комментариях, ваш код пытается использовать file_get_contents в локальном каталоге, что не разрешено. Также похоже, что вы пытались сделать то же самое на $xmlstream, что должно выполняться для каждого файла, а не каталога. Предполагая, что 'C:\\xml\\Race_' . $value; — это каталог, подобный C:\\xml\\Race_1, а не файл.
Некоторые незначительные проблемы с проверкой ресурсов и специфичные для Windows проблемы, которые необходимо решить:
Разделители каталогов Windows должны быть записаны как \\ (даже если
используя одинарные кавычки), так как \ является управляющей последовательностью
это заставляет \x \t \n \r \' \" \\ рассматриваться как специальные символы.
При использовании fopen($path, $mode) рекомендуется указывать флаг b в качестве последнего символа режима, чтобы убедиться, что файл
двоично-безопасный (дословно) и во избежание двусмысленности между операционными системами. В качестве альтернативы в Windows укажите режим t для прозрачного преобразования \n в \r\n(желательно только для текстовых файлов).
$mode = 'rb'(двоично-безопасное чтение)$mode = 'rt'(перевод в текстовом режиме читать)При работе с сетевыми потоками рекомендуется проверить, что поток успешно записал все свое содержимое. Ниже я предоставил функцию fwrite_stream из руководства по PHP.
try {
//--- example purposes only ---
//use your own ssh2_connnect, ssh2_auth_password, ssh2_sftp
if (!$ssh2 = ssh2_connect('192.168.56.101', 22)) {
throw new \RuntimeException('Unable to connect to remote host');
}
if (!ssh2_auth_password($ssh2, 'root', '')) {
throw new \RuntimeException('Unable to Authenticate');
}
if (!$sftp = ssh2_sftp($ssh2)) {
throw new \RuntimeException('Unable to initialize SFTP');
}
$value = '1';
//--- end example purposes only ---
$localFile_xml = 'C:\\xml\\Race_' . $value;
if (!$localFile_xml || !is_dir($localFile_xml)) {
throw new \RuntimeException('Unable to retrieve local directory');
}
//retrieve list of XML files
$iterator = new \GlobIterator($localFile_xml . '/*.xml',
\FilesystemIterator::KEY_AS_PATHNAME |
\FilesystemIterator::CURRENT_AS_FILEINFO |
\FilesystemIterator::SKIP_DOTS
);
if (!$iterator->count()) {
throw new \RuntimeException('Unable to retrieve local files');
}
$success = [];
$remote_XMLfiles = '/FTP/XML/Race_' . $value;
$remote_XMLpath = "ssh2.sftp://$sftp" . $remote_XMLfiles;
//ensure the remote directory exists
if (!@mkdir($remote_XMLpath, 0777, true) && !is_dir($remote_XMLpath)) {
throw new \RuntimeException(sprintf('Unable to create remote directory "%s"', $remote_XMLpath));
}
/**
* @var string $filepath
* @var \SplFileInfo $fileinfo
*/
foreach ($iterator as $filepath => $fileinfo) {
$filesize = $fileinfo->getSize();
printf("%s size %d\n", $filepath, $filesize);
try {
//open local file resource for binary-safe reading
$xmlObj = $fileinfo->openFile('rb');
//retrieve entire file contents
if (!$xmlData = $xmlObj->fread($filesize)) {
//do not permit empty files
printf("No data found for \"%s\"\n", $filepath);
continue;
}
} finally {
//shortcut to close the opened local file resource on success or fail
$xmlObj = null;
unset($xmlObj);
}
try {
$remote_filepath = $remote_XMLpath . '/' . $fileinfo->getBasename();
//open a remote file resource for binary-safe writing
//using current filename, overwriting the file if it already exists
if (!$xmlstream = fopen($remote_filepath, 'wb')) {
throw new \RuntimeException(sprintf('Unable to create remote file "%s"', $remote_filepath));
}
//write the local file data to the remote file stream
if (false !== ($bytes = fwrite_stream($xmlstream, $xmlData))) {
$success[] = [
'filepath' => $filepath,
'remote_filepath' => $remote_filepath,
'bytes' => $bytes,
];
}
} finally {
//shortcut to ensure the xmlstream is closed on success or failure
if (isset($xmlstream) && is_resource($xmlstream)) {
fclose($xmlstream);
}
}
}
//testing purposes only to show the resulting uploads
if (!empty($success)) {
var_export($success);
}
} finally {
//shortcut to disconnect the ssh2 session on success or failure
$sftp = null;
unset($sftp);
if (isset($ssh2) && is_resource($ssh2)) {
ssh2_disconnect($ssh2);
}
}
/*
* Taken from PHP Manual
* Writing to a network stream may end before the whole string is written.
* Return value of fwrite() may be checked
*/
function fwrite_stream($fp, $string)
{
for ($written = 0, $writtenMax = strlen($string); $written < $writtenMax; $written += $fwrite) {
$fwrite = fwrite($fp, substr($string, $written));
if (false === $fwrite) {
return $written;
}
}
return $written;
}
NOTE
All file operations will be created using the
ssh2_auth_passworduser as the owner/group. You must ensure the specified user has read and write access to the desired directories.Use the appropriate file masks to ensure desired file/directory permissions
0777(default) allows everyone to read, write, execute!0750is typically desired for directories0640is typically desired for individual files- use
chmod($path, 0750)to change permissions on the remote file(s)- use
chown($path, 'user')to change the owner on the remote file(s)- use
chgrp($path, 'group')to change the group on the remote file(s)
C:\xml\Race_1\file1.xml size 9
C:\xml\Race_1\file2.xml size 11
array (
0 =>
array (
'filepath' => 'C:\\xml\\Race_1\\file1.xml',
'remote_filepath' => 'ssh2.sftp://Resource id #5/FTP/XML/Race_1/file1.xml',
'bytes' => 9,
),
1 =>
array (
'filepath' => 'C:\\xml\\Race_1\\file2.xml',
'remote_filepath' => 'ssh2.sftp://Resource id #5/FTP/XML/Race_1/file2.xml',
'bytes' => 11,
),
)
Привет, Fyrye ... Прежде всего, спасибо, вы помогли мне не только с моей проблемой, но и нашли время, чтобы объяснить, где я ошибся. Я очень ценю ваше время, усилия и рекомендации. еще раз спасибо.
Похоже, вы звоните
fclose, но снова неfopen. Вам нужно будет повторно открыть закрытый ресурс.