Read contents of every file in FTP directory using one connection
To avoid having to connect/login for every file, use the ftp_get
and reuse your connection ID ($conn_id
):
foreach ($files as $file)
{
// Full path to a remote file
$remote_path = "DirectoryName/$file";
// Path to a temporary local copy of the remote file
$temp_path = tempnam(sys_get_temp_dir(), "ftp");
// Temporarily download the file
ftp_get($conn_id, $temp_path, $remote_path, FTP_BINARY);
// Read the contents of temporary copy
$contents = file_get_contents($temp_path);
$content[$file] = $contents;
// Discard the temporary copy
unlink($temp_path);
}
(You should add some error checking.)
Read or download 5kb of a file from FTP server in PHP or Python instead of downloading or reading whole file
If you want to read only part of the file, then just remove your while
loop and call fgets
only once.
$buffer = fgets($handle, 4096);
Though if the file is binary or if you want to read a fixes amount of bytes, you better use fread
.
$buffer = fread($handle, 4096);
Though your server is not compatible with PHP URL wrappers, see:
Getting "FTP server reports 550 Could not get file size." when using FTP URL in fopen
And PHP does not offer any other robust alternative for your needs.
Though it is doable in Python with ftplib:
ftp = FTP()
ftp.connect(host, user, passwd)
size = 4096
cmd = "RETR {}".format(filename)
f = BytesIO()
aborted = False
def gotdata(data):
f.write(data)
while (not aborted) and (f.tell() >= size):
ftp.abort()
aborted = True
try:
ftp.retrbinary(cmd, gotdata)
except:
# An exception when transfer is aborted is expected
if not aborted:
raise
f.seek(0)
The code is based on my answer to:
Get files names inside a zip file on FTP server without downloading whole archive
List and download clicked file from FTP
Your link in the generated <a>
tag points back to the web server, which does not contain the linked file.
What you need to do is to link to a PHP script, giving it a name of the file to download. The script will then download the file from an FTP server and pass the downloaded file back to the user (to the webbrowser).
echo "<a href=\"download.php?file=".urlencode($file)."\">".htmlspecialchars($file)."</a>";
A very trivial version of the download.php
script:
<?
header('Content-Type: application/octet-stream');
echo file_get_contents('ftp://username:password@ftp.example.com/path/' . $_GET["file"]);
The download.php
script uses FTP URL wrappers. If that's not allowed on your web server, you have to go the harder way with FTP functions. See
PHP: How do I read a file from FTP server into a variable?
Though for a really correct solution, you should provide some HTTP headers related to the file, like Content-Length
, Content-Type
and Content-Disposition
.
Also the above trivial example will first download whole file from the FTP server to the webserver. And only then it will start streaming it to the user (webbrowser). What is a waste of time and also of a memory on the webserver.
For a better solution, see Download file via PHP script from FTP server to browser with Content-Length header without storing the file on the web server.
You may also want to autodetect Content-Type
, unless all your files are of the same type.
A related question about implementing an FTP upload with a webpage:
Displaying recently uploaded images from remote FTP server in PHP
How to stream a file I get from an FTP without storing it locally?
Your problem consists of two parts:
Reading FTP file as a stream (see an example with
fread()
: "PHP: How do I read a .txt file from FTP server into a variable?")Streaming a Response in Symfony2
Transfer files between two remote FTP servers in PHP
Both ftp_get
and ftp_put
can operate with files only, not folders.
Use ftp_get
to download a file from the first server to a local temporary folder/file. And then use ftp_put
to upload the temporary file to the second server.
If you want to avoid using a temporary file, you can download the file to memory using ftp_fget
and re-upload to the second server using ftp_fput
.
- PHP: How do I read a .txt file from FTP server into a variable?
- Transfer in-memory data to FTP server without using intermediate file
FTP Files are not accessible using fopen or file_exists or file_get_contents
Ok, This solved my error.
$filename = "ftp://username:password@hostname/path/to/file";
Thanks.
Related Topics
Preserve Key Order (Stable Sort) When Sorting With PHP'S Uasort
Laravel - Eloquent or Fluent Random Row
Checking to See If One Array'S Elements Are in Another Array in PHP
How to Enable Curl in Wamp Server
Explode String into Array With No Empty Elements
Laravel 5 - Clear Cache in Shared Hosting Server
Return Index of Highest Value in an Array
Detect Exact Os Version from Browser
Create a Folder If It Doesn't Already Exist
PHP Get Site Url Protocol - Http VS Https
PHP: Writing a Simple Removeemoji Function
Eloquent Orm Code Hinting in PHPstorm
Set Pdo to Throw Exceptions by Default