I checked over some other answers before I came here to publish a question, I'm having trouble with the following script, no matter what i've tried it will not download a file from the FTP even after listing the files that are in directory (obviously)
Because I'm organised I like to simplify everything into a class,
class FTPHandler
{
private $connection;
public function FTPConnect($host, $user, $pass)
{
$ftp = ftp_connect($host);
$login = ftp_login($ftp, $user, $pass) or die("FTP: Login Failed");
if ($login) {
$this->connection = array("host" => $host, "user" => $user, "pass" => $pass);
return $ftp;
}
echo "FTP Login Failed";
}
public function ListAllFiles($stream, $dir)
{
ftp_pasv($stream, true);
$ls = ftp_nlist($stream, $dir);
return $ls;
}
public function get_conx_info() {
return $this->connection;
}
}
Using the following code:
define("APP_DIR", "./app/");
$ftp = new FTPHandler();
$handle = $ftp->FTPConnect("ftp.example.com.au", "exampleuser", "examplepass");
$files = $ftp->ListAllFiles($handle, APP_DIR);
foreach ($files as $val)
{
if ($val != "." && $val != ".." && $val != "processed") {
$local_file = $val;
$remote_file = APP_DIR.$val;
if (ftp_get($handle, $local_file, $remote_file)) {
echo "Successfully retrieved: $remote_file <br/>";
}
else
{
echo "Failed retrieving file: $remote_file <br/>";
}
}
}
My return is always:
Failed retrieving file: ./app/adsl-1989-csv.csv
Failed retrieving file: ./app/adsl-1989-sig.png
Failed retrieving file: ./app/dd-1964-csv.csv
Failed retrieving file: ./app/dd-1964-sig.png
Failed retrieving file: ./app/dd-1967-csv.csv
Failed retrieving file: ./app/dd-1967-sig.png
Failed retrieving file: ./app/dd-1972-csv.csv
Failed retrieving file: ./app/dd-1972-sig.png
Failed retrieving file: ./app/dd-1973-csv.csv
Failed retrieving file: ./app/dd-1973-sig.png
Failed retrieving file: ./app/dd-1974-csv.csv
Failed retrieving file: ./app/dd-1974-sig.png
Failed retrieving file: ./app/dd-1975-csv.csv
Failed retrieving file: ./app/dd-1975-sig.png
Failed retrieving file: ./app/dd-1978-csv.csv
Any assistance is highly appreciated as I have to have this automated to alleviate a few thousand per week off the employee budget.
I ended up discovering that the FTP server itself was at fault.
The error was fixed by changing from the default Active Ports as it was dropping majority of packets.
So if anyone out there is experiencing the same issue, worth taking a look at doing the same.
Thank you to Fred -ii- for your attempt in assisting me.
Related
I am trying to download a previously uploaded file, form database and uploads folder in php codeigniter. I am using code below but downloading empty file.
controller.php
public function downloadFile($incidents_id)
{
$file = $this->incidents_model->getfile($incidents_id);
//echo $file; die;
$this->load->helper('download');
$path = file_get_contents(base_url()."uploads/".$file); //(the error shows on this line)
// echo $path; die;
$name = $file; // new name for your file
// echo $name ; die;
force_download($name, $path); // start download`
}
incidents_model.php
function getfile($Incident_id )
{
$file = $this->db->select('file');
$this->db->from('incidents');
$this->db->where('incidents_id' , $Incident_id );
$query = $this->db->get();
// return $query->row();
if ($query->num_rows() > 0) {
return $query->row()->file;
}
return false;
}
view.php
<div class="form-group col-md-4">
Download file
</div>
so running this code download an empty file.
echo $file; die; displays the file name which been saved in db and in uploads folder
echo $path; die; generates an error:
Severity: Warning
Message:
file_get_contents(http://localhost:8080/ticketing_tool_v2/uploads/Screenshot
2021-03-04 at 5.59.38 PM.png): failed to open stream: Connection
refused
Filename: admin/Incidents.php
Line Number: 380
Reviewing the documentation for file_get_contents you'll observe there's many different ways you can use it. For your purposes you would need to allow inbound connections to the filesystem.
The other way you could do this for better future proofing is to use the CodeIgniter file helper - https://codeigniter.com/userguide3/helpers/file_helper.html
Before reading the file from path, please check whether a path points to a valid file.
public function downloadFile($incidents_id) {
try {
$this->load->helper('download');
$file = $this->incidents_model->getfile($incidents_id);
$data = file_get_contents(base_url("uploads/" . $file));
$name = $file; // new name for your file
force_download($name, $data); // start download`
} catch (Exception $e) {
//exception handling code goes here
print_r($e);
}
}
I have worked out the PHP code required to upload data from a .csv file to a database, not using CakePHP3.x, but I am struggling integrating this into my framework. I don't want to upload the file to the database, only read the data from the CSV file.
This is my code that works on the localhost to upload the data to my database.
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$fp = fopen("CSV_Upload_Test.csv", "r");
while( !feof($fp)) {
if( !$line = fgetcsv($fp, 1000, ',', '"')) {
continue;
}
$mysqlimport = "INSERT INTO divisiontwosix.csvtestsystems VALUES('".$line[0]."','".$line[1]."','".$line[2]."','".$line[3]."','".$line[4]."')";
mysql_query($mysqlimport) or die(mysql_error());
}
fclose($fp);
This is my code for the CakePHP installation on my server, but I can't seem to find (or more likely ask the correct question to find) an answer on how to implement it.
This is my Controller:
public function upload()
{
$system = $this->Systems->newEntity();
//Check if file has been uploaded.
if(!empty($this->request->data['Systems']['upload']['name']))
{
$file = $this->request->data['Systems']['upload'];
}
if ($this->request->is('post')) {
$system = $this->Systems->patchEntity($system, $this->request->data);
// add upload data to controller function upload
$file = $_REQUEST['text'];
$fp = fopen("$file","r");
while( !feof($fp)) {
if( !$line = fgetcsv($fp, 1000, ',', '"')) {
continue;
}
$mysqlimport = "INSERT INTO divtwosix.systems VALUES('".$line[0]."','".$line[1]."','".$line[2]."','".$line[3]."','".$line[4]."')";
mysql_query($mysqlimport) or die(mysql_error());
}
fclose($fp);
if ($this->Systems->save($system)) {
$this->Flash->success(__('The system has been saved.'));
return $this->redirect(['action' => 'index']);
} else {
$this->Flash->error(__('The system could not be saved. Please, try again.'));
}
}
$estimates = $this->Systems->Estimates->find('list', ['limit' => 200]);
$this->set(compact('system', 'estimates'));
$this->set('_serialize', ['system']);
}
And this is my form (upload.ctp) as you can see I have tried a couple of things:
<?= $this->Form->create($system) ?>
<fieldset>
<legend><?= __('Upload System') ?></legend>
<?php
echo $this->Form->create('User', array('url' => array('action' => 'create'), 'enctype' => 'multipart/form-data'));
// echo $this->Form->create($system, ['type'=>'file']);
echo $this->Form->input('estimates_id', ['label'=>'Select Estimate Name','options' => $estimates]);
// echo $this->Form->input('file', ['label'=>'Upload works with CSV files only','type' => 'file']);
echo $this->Form->input('text', ['label'=>'Input File location']);
?>
</fieldset>
<?= $this->Form->button(__('Upload')) ?>
And the error I get is
fopen(C:\Users\jrogers\Desktop\Book1.csv): failed to open stream: No such file or directory [APP/Controller/SystemsController.php, line 86]
or
fopen(Book1.csv): failed to open stream: No such file or directory [APP/Controller/SystemsController.php, line 86]
It is not my intent to add the file to the database, but only to add the data from the .csv file to the database. I realize I am probably missing something simple, but would greatly appreciate the assistance. The examples I am finding only show how to upload the file to the database and not how to read the data from the local file. Thanks in advance for your help.
In legacy php scripts uploaded files should be accessed through $_FILES array so you should modify your code like this example
$file = $_FILES['text']['tmp_name'];
$fp = fopen($file,"r");
Good luck
source: http://php.net/manual/en/features.file-upload.post-method.php
note: I'm not a cake user but IMO it should have a proper way for accessing uploaded files
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
Please find the following code. In addition to this I forget to state that I am actually running this script on magento web store but it doesn't matter since I am getting all things okay except file transfer.
<?php
require_once('app/Mage.php');
Mage::app();
$products = Mage::getModel('catalog/product')->getCollection()->addAttributeToSelect('*');
$array1=array();
$array2=array();
echo $destination_dir = dirname(__FILE__);
$remote_file = '/B303501/_Datenblatt.pdf';
$ftp_server = "*******";
$ftp_user = "************";
$ftp_pass = "******";
$local_file = '/E212002M';
$conn_id = ftp_connect($ftp_server) or die("Couldn't connect to $ftp_server");
foreach ($products as $product) {
array_push($array1,$product->getData("sku"));
array_push($array2,$product->getData("image"));
}
// try to login
if (#ftp_login($conn_id, $ftp_user, $ftp_pass)) {
//echo "Connected as $ftp_user#$ftp_server";
ftp_pasv($conn_id, true);
if(!#copy('/B303501/_Datenblatt.pdf','/media/catalog/product/demo/'))
{
$errors= error_get_last();
echo "COPY ERROR: ".$errors['type'];
echo "<br />\n".$errors['message'];
} else {
echo "File copied from remote!";
}
$i = 0;
$contents = ftp_nlist($conn_id, ".");
foreach ($contents as $cont) {
if(in_array($cont,$array1)){
echo $cont. "</br>";
$buff = ftp_rawlist($conn_id, '/'.$cont.'/');
echo "<pre>";
print_r($buff);
echo "</pre>";
$tobecopied = 'http://www.example.com/index.html';
$target = $destination_dir . '/media/catalog/product/demo/';
foreach($buff as $key){
if(!#copy('/'.$cont.'/'.$key,'/media/catalog/product/demo/'))
{
$errors= error_get_last();
echo "COPY ERROR: ".$errors['type'];
echo "<br />\n".$errors['message'];
} else {
echo "File copied from remote!";
}
}
$i++;
}
}
} else {
echo "Couldn't connect as $ftp_user\n";
}
I am getting following error while file transfer from one server to another server.
I have both live server and I am also get logged-in successfully but can't figure out what's happening while file transfer.
The following is the error.
/var/www/clients/client348/web979/web
COPY ERROR: 2
copy(/B303501/_Datenblatt.pdf): failed to open stream: No such file or directoryB303501
Any help would be highly appreciate.
Let me know if you need any further information regarding above.
Thanks
I think you should use ftp_get not copy. Also make sure that directory hierarchy exists at your destination because either ftp_get nor copy won't create missing directories for you.
I finally sort it out issue. The ftp you I am using is just normal ftp but In order to loggedin into another server you need SFTP credentials except this all above is in working mode.
Thanks for your support
I'm trying to write a script that will upload the entire contents of a directory stored on my server to other servers via ftp.
I've been reading through the documentation on www.php.net, but can't seem to find a way to upload more then one file at a time.
Is there a way to do this, or is there a script that will index that directory and create an array of files to upload?
Thanks in advance for your help!
Once you have a connection open, uploading the contents of a directory serially is simple:
foreach (glob("/directory/to/upload/*.*") as $filename)
ftp_put($ftp_stream, basename($filename) , $filename, FTP_BINARY);
Uploading all files in parallel would be more difficult.
So, I took #iYETER's code, and wrapped it as a class object.
You can call this code by these lines:
$ftp = new FtpNew("hostname");
$ftpSession = $ftp->login("username", "password");
if (!$ftpSession) die("Failed to connect.");
$errorList = $ftp->send_recursive_directory("/local/dir/", "/remote/dir/");
print_r($errorList);
$ftp->disconnect();
It recursively crawls local dir, and places it on remote dir relative. If it hits any errors, it creates a array hierarchy of every file and their exception code (I only capture 2 so far, if it's another error, it throws it default route for now)
The class this is wrapped into:
<?php
//Thanks for iYETER on http://stackoverflow.com/questions/927341/upload-entire-directory-via-php-ftp
class FtpNew {
private $connectionID;
private $ftpSession = false;
private $blackList = array('.', '..', 'Thumbs.db');
public function __construct($ftpHost = "") {
if ($ftpHost != "") $this->connectionID = ftp_connect($ftpHost);
}
public function __destruct() {
$this->disconnect();
}
public function connect($ftpHost) {
$this->disconnect();
$this->connectionID = ftp_connect($ftpHost);
return $this->connectionID;
}
public function login($ftpUser, $ftpPass) {
if (!$this->connectionID) throw new Exception("Connection not established.", -1);
$this->ftpSession = ftp_login($this->connectionID, $ftpUser, $ftpPass);
return $this->ftpSession;
}
public function disconnect() {
if (isset($this->connectionID)) {
ftp_close($this->connectionID);
unset($this->connectionID);
}
}
public function send_recursive_directory($localPath, $remotePath) {
return $this->recurse_directory($localPath, $localPath, $remotePath);
}
private function recurse_directory($rootPath, $localPath, $remotePath) {
$errorList = array();
if (!is_dir($localPath)) throw new Exception("Invalid directory: $localPath");
chdir($localPath);
$directory = opendir(".");
while ($file = readdir($directory)) {
if (in_array($file, $this->blackList)) continue;
if (is_dir($file)) {
$errorList["$remotePath/$file"] = $this->make_directory("$remotePath/$file");
$errorList[] = $this->recurse_directory($rootPath, "$localPath/$file", "$remotePath/$file");
chdir($localPath);
} else {
$errorList["$remotePath/$file"] = $this->put_file("$localPath/$file", "$remotePath/$file");
}
}
return $errorList;
}
public function make_directory($remotePath) {
$error = "";
try {
ftp_mkdir($this->connectionID, $remotePath);
} catch (Exception $e) {
if ($e->getCode() == 2) $error = $e->getMessage();
}
return $error;
}
public function put_file($localPath, $remotePath) {
$error = "";
try {
ftp_put($this->connectionID, $remotePath, $localPath, FTP_BINARY);
} catch (Exception $e) {
if ($e->getCode() == 2) $error = $e->getMessage();
}
return $error;
}
}
Do it in a loop, iterating through all the files in the folder
$servername = $GLOBALS["servername"];
$ftpUser = $GLOBALS["ftpUser"];
$ftpPass = $GLOBALS["ftpPass"];
$conn_id = ftp_connect($servername) or die("<p style=\"color:red\">Error connecting to $servername </p>");
if(ftp_login($conn_id, $ftpUser, $ftpPass))
{
$dir_handle = #opendir($path) or die("Error opening $path");
while ($file = readdir($dir_handle)) {
ftp_put($conn_id, PATH_TO_REMOTE_FILE, $file)
}
}
I coded it, the script uploads whole folder with it's subfolders and files.
I hope it will help you.
<?php
ob_start();
set_time_limit(0);
//r10.net fatal
$anadizin="uploadedeceginizdizin"; //this is the folder that you want to upload with all subfolder and files of it.
$ftpsunucu="domain.com"; //ftp domain name
$ftpusername="ftpuser"; //ftp user name
$ftppass="ftppass"; //ftp passowrd
$ftpdizin="/public_html"; //ftp main folder
$arkadaslarlabardaydik = ftp_connect($ftpsunucu);
$ictikguldukeglendik = ftp_login($arkadaslarlabardaydik, $ftpusername, $ftppass);
if((!$arkadaslarlabardaydik) || (!$ictikguldukeglendik))
{
echo "cant connect!";
die();
}
function klasoruoku($dizinadi)
{
global $nerdeyiz,$fulldizin,$ftpdizin,$arkadaslarlabardaydik,$ftpdizin;
chdir($dizinadi."\\");
$dizin = opendir(".");
while($bilgi=readdir($dizin))
{
if ($bilgi!='.' and $bilgi!='..' and $bilgi!="Thumbs.db")
{
$tamyol="$dizinadi\\$bilgi";
$lokalkla=str_replace("".$nerdeyiz."\\","",$dizinadi)."";
$lokaldosya="$lokalkla\\$bilgi";
$ftpyeyolla=str_replace(array("\\\\","\\"),array("/","/"),"$ftpdizin\\".str_replace("".$fulldizin."","",$dizinadi)."\\$bilgi");
if(!is_dir($bilgi))
{
$yükleme = ftp_put($arkadaslarlabardaydik, $ftpyeyolla, $tamyol, FTP_BINARY);
if (!$yükleme)
{
echo "$lokaldosya <font color=red>uploaded</font>"; echo "<br>"; fls();
}
else
{
echo "$lokaldosya <font color=green>not uploaded</font>"; echo "<br>"; fls();
}
}
else
{
ftp_mkdir($arkadaslarlabardaydik, $ftpyeyolla);
klasoruoku("$dizinadi\\$bilgi");
chdir($dizinadi."\\");
fls();
}
}
}
closedir ($dizin);
}
function fls()
{
ob_end_flush();
ob_flush();
flush();
ob_start();
}
$nerdeyiz=getcwd();
$fulldizin=$nerdeyiz."\\$anadizin";
klasoruoku($fulldizin);
ftp_close($arkadaslarlabardaydik);
?>
If you want to have multiple files uploaded at once, you'll need to use thread or fork.
I'm not sure of a Thread implentation in PHP, but you should take a look at the PHP SPL and/or PEAR
Edit: Thanks to Frank Farmer to let me know that there was a fork() function in PHP known as pcntl_fork()
You'll also have to get the whole content directory recursively to be able to upload all the file for a given directory.