I have a code:
scandir("ssh2.sftp://" . intval($sftpHandle) . $remoteDir);
Why the same code works for one server but doesn't for another?
There is a files on both servers. I can manage them via Filezilla without problems.
The first one just returns array('.') even if there is a lot of files, another one returns array('file1', 'file2', 'file3', etc)
Even if I cannot list a files using scandir(), command ssh2_scp_recv($sshHandle, $remoteDir/file1, $localDir/file1) works fine.
Also ssh2_exec($sshHandle, "ls $remoteDir") works fine to me.
Please note that I'm using $ftpHandle for scandir() but $sshHandle for ssh2_* functions.
Using $sshHandle for scandir() cause "Segmentation fault" error.
I know that I can workaround this by parsing ssh2_exec($sshHandle, "ls $remoteDir") output, but would prefer do it right way if possible.
My PHP version is 7.0.31
This should work probably
$connection = ssh2_connect($url);
// login
if (!ssh2_auth_password($connection, $username, $password)) throw new Exception('Unable to connect server.');
// Create SFTP resource
if (!$sftp = ssh2_sftp($connection)) throw new Exception('Unable to create connection.');
$localDir = '/path/to/local/dir';
$remoteDir = '/path/to/remote/dir';
// download all the files or list all
$files = scandir('ssh2.sftp://' . $sftp . $remoteDir);
if (!empty($files)) {
foreach ($files as $file) {
if ($file != '.' && $file != '..') {
// here you can print files using $file
// or download file by uncommenting below line
//ssh2_scp_recv($connection, "$remoteDir/$file", "$localDir/$file");
}
}
}
Related
I was creating a zip archive with php 7.4 (lib-zip version 1.6.1) without any problems.
Now I try to protect these zip archive with a password. Not just for encrypting with php, but in general. I found this tutorial. It does what it should, but I could not read the files of the zip archive any more. If I doubleclick on the archive, the password prompt opens up, but it does not work with the password from the source code. I also copy and pasted it to prevent any keyboard struggle.
<?php
$zip = new ZipArchive();
$filePath = sprintf('%s/test/', __DIR__);
$fileName = 'test.zip';
$absoluteFilePath = $filePath . $fileName;
$excludeFolderNames = [
'.',
'..',
'.DS_Store',
$fileName,
];
$zipFlag = ZipArchive::CREATE;
if (file_exists($absoluteFilePath)) {
$zipFlag = ZipArchive::OVERWRITE;
}
$createFile = $zip->open($absoluteFilePath, $zipFlag);
if (true !== $createFile) {
throw new RuntimeException(sprintf('could not open file in "%s" caused by %s', $fileName, $createFile));
}
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($filePath));
$password = 'top-secret';
if (!$zip->setPassword($password)) {
throw new RuntimeException('Set password failed');
}
/** #var SplFileInfo $value */
foreach ($iterator as $key => $value) {
if (in_array($value->getFilename(), $excludeFolderNames)) {
continue;
}
$cleanFilePath = realpath($key);
if (!$cleanFilePath) {
throw new RuntimeException(sprintf('could not create real path from filepath: %s', $key));
}
$zipName = str_replace($filePath, '', $cleanFilePath);
if (!$zip->addFile($cleanFilePath, $zipName)) {
throw new RuntimeException(sprintf('Add file failed: %s', $cleanFilePath));
}
if (!$zip->setEncryptionName($zipName, ZipArchive::EM_AES_256)) {
throw new RuntimeException(sprintf('Set encryption failed: %s', $zipName));
}
}
$zip->close();
Does someone has the same problem or am I the problem?
UPDATE I:
I tought it solves my problem to save the zip-file outside the folder I want to zip. So I changed the following line:
$absoluteFilePath = sprintf('%s/%s', __DIR__, $fileName);
After a while the error occured again.
One possible reason I discovered, were .DS_Store files. In my example I exclude them. But the error occured again.
UPDATE II:
One further problem is, that there is no password prompt, if all files are empty.
UPDATE III:
Same code works with files without line break, but the error occurs, if the file has multiple lines.
I found help at the php-bugtracker. It turns out that I can extract all the files with an zip-extension like the comments tryed to tell me before. Now I wait for the new libzip version 1.7.0, where the default zip encryption is available. After this I hope I can extract my files without any extension.
The below script is working successfully.
Getting file from one server to another
if(ssh2_scp_recv($conn, '/var/www/html/captures/store/2016/04/HK/15721022890870/test/vcredist.bmp',
'/var/www/html/captures/store/2016/04/HK/15721022890870/test/vcredist.bmp')){
echo "\n recevied \n";
}else{
echo "\n not recevied\n";
}
But instead for fetching just a static file, I want to fetch folder with all its content inside.
With above example, the directory I would like to fetch to local server is "15721022890870"
/var/www/html/captures/store/2016/04/HK/15721022890870/
I have tried below code but doesn't work,
The remote server has directory, but the local server doesn't have, so I want to make directory then copy all its content inside
if(ssh2_scp_recv($conn, '/var/www/html/captures/store/2016/04/HK/15721022890870/',
'/var/www/html/captures/store/2016/04/HK/')){
echo "\n recevied done \n";
}else{
echo "\n not done \n";
}
<?php
$username = "your_username";
$password = "your_pass";
$url = 'your_stp_server_url';
// Make our connection
$connection = ssh2_connect($url);
// Authenticate
if (!ssh2_auth_password($connection, $username, $password)) throw new Exception('Unable to connect.');
// Create our SFTP resource
if (!$sftp = ssh2_sftp($connection)) throw new Exception('Unable to create SFTP connection.');
$localDir = '/path/to/your/local/dir';
$remoteDir = '/path/to/your/remote/dir';
// download all the files
$files = scandir('ssh2.sftp://' . $sftp . $remoteDir);
if (!empty($files)) {
foreach ($files as $file) {
if ($file != '.' && $file != '..') {
ssh2_scp_recv($connection, "$remoteDir/$file", "$localDir/$file");
}
}
}
?>
This is from server to computer but you can modify the $localDir
I've just discovered phpseclib for myself and would like to use it for my bit of code. Somehow I can't find out how I could copy files from one sftp directory into an other sftp directory. Would be great if you could help me out with this.
e.g.:
copy all files of
/jn/xml/
to
/jn/xml/backup/
$dir = "/jn/xml/";
$files = $sftp->nlist($dir, true);
foreach($files as $file)
{
if ($file == '.' || $file == '..') continue;
$sftp->put($dir."backup".'/'.$file, $sftp->get($dir.'/'.$file));
}
This code will copy contents from "/jn/xml/" directory to "/jn/xml/backup".
To be able to move a file correctly with PHPSeclib, you can use
$sftp->rename($old, $new);
Try this:
<?php
include('Net/SFTP.php');
$sftp = new Net_SFTP('website.com');
if (!$sftp->login('user', 'pass')) {
exit('bad login');
}
$sftp->chdir('/jn/xml/');
$files = $sftp->nlist('.', true);
foreach ($files as $file) {
if ($file == '.' || $file == '..') {
continue;
}
$dir = '/jn/xml/backup/' . dirname($file);
if (!file_exists($dir)) {
mkdir($dir, 0777, true);
}
file_put_contents($dir . '/' . $file, $sftp->get($file));
}
I think this should do what was asked.
I used composer to import phpseclib so this is not exactly the code I tested, but from the other answers, the syntax should be correct.
<?php
include('Net/SFTP.php');
// connection
$sftp = new Net_SFTP('website.com');
if (!$sftp->login('user', 'pass')) {
exit('bad login');
}
// Use sftp to make an mv
$sftp->exec('mv /jn/xml/* /jn/xml/backup/');
Notes:
if any of the directories do not exist, this will fail. do echo $sftp->exec(... to get the errormsg.
you will get a warning because /jn/xml/backup/ is inside /jn/xml/, I would advise moving the files to /jn/xml.bak/
you could use 'Net/SSH2' class, since you only do a mv, and do not transfer any files. In fact, the exec is a function from the SSH2 class, and SFTP inherits it from SSH2.
I'm trying to download images from a remote FTP server and upload them to our own rackspace account. This goes fine for about 3000 images but then it crashes and gives me the following error:
exception with message 'ftp_fget(): Transfer complete.'
We've tried changing the code to use ftp_get(), to not use a temp file to store it in, but it always resulted in the same error. It always fails on the same files, if I were to delete a couple of files that were already downloaded and run the scripts again it has no problem downloading them... it just fails again once it hits those specific images on the FTP server. I've tried downloading those images manually from the server and it worked, it seems nothing is wrong with them.
This is basically the code that does it:
$this->handle = ftp_connect($ftpurl);
$loggedIn = ftp_login($this->handle, $ftpusername, $ftppassword);
if ($loggedIn === false) {
throw new Exception('Can\'t login to FTP server');
}
if ($this->handle === false) {
throw new Exception('Could not connect to the given url');
}
ftp_pasv($this->handle, true);
$fileList = ftp_nlist($this->handle, '.');
if (count($fileList) === 0) {
throw new Exception('No files found on FTP-server');
}
foreach($fileList as $filename) {
try {
$container->getObject($filename);
// Image already exists, rackspace has no convenient hasImage() function
} catch (Exception $ex) {
$temp = tmpfile();
ftp_fget($this->handle, $temp, $filename, FTP_BINARY);
//upload $tmp to rackspace
}
}
Any ideas what could be the issue here?
While trying to list the files present in a remote sftp location using php, I get this error:
Error 324 (net::ERR_EMPTY_RESPONSE):
The server closed the connection without sending any data. On my another lamp server the same code works fine. Please point where I am missing something if you can help please. Thanks in advance.
function listBuildFiles() {
global $sftp_host, $sftp_username, $sftp_password, $sftp_path;
$connection = ssh2_connect($sftp_host);
// Authenticate
if (!ssh2_auth_password($connection, $sftp_username, $sftp_password)) {
throw new Exception('Unable to connect.');
}
// Create our SFTP resource
if (!$sftp = ssh2_sftp($connection)) {
throw new Exception('Unable to create SFTP connection.');
}
/**
* Now that we have our SFTP resource, we can open a directory resource
* to get us a list of files. Here we will use the $sftp resource in
* our address string as I previously mentioned since our ssh2://
* protocol allows it.
*/
$files = array();
$dirHandle = opendir("ssh2.sftp://$sftp$sftp_path");
$i=0;
// Properly scan through the directory for files, ignoring directory indexes (. & ..)
while (false !== ($file = readdir($dirHandle))) {
if ($file != '.' && $file != '..') {
$files[$i] = $file;
$i++;
}
}
echo '<select name="buildName">';
echo '<option>Please Select a build</option>';
foreach ($files as $filename) {
echo "<option value=\"$filename\">$filename</option>";
}
echo '</select>';
ssh2_exec($connection, "exit");
Thanks,
Ujjwal
Just to make sure there is no problem on the server side you can open a console and try a raw ssh connection in verbose mode:
ssh -v youruser#yourhost.com
this traces all the interactions between server and client, maybe gives you some clue from the server side.
With phpseclib, a pure PHP SFTP implementation, you can see the full logs of what's going on. Example:
<?php
include('Net/SFTP.php');
define('NET_SSH2_LOGGING', NET_SSH2_LOG_COMPLEX);
$sftp = new Net_SFTP('www.domain.tld');
if (!$sftp->login('username', 'password')) {
exit('Login Failed');
}
// puts a three-byte file named filename.remote on the SFTP server
$sftp->put('filename.remote', 'xxx');
echo $ssh->getLog();
print_r($ssh->getErrors());
?>
The developer of phpseclib is pretty proactive about providing support too so if you can't figure it out from the logs or error messages (s)he probably can.