Yes, I know, it's hard to believe those FTP servers still exist, but they actually do. IBM iSeries machines run such servers.
I've already got an answer which involves ftp_nlist
and in_array
but, as some of you may have guessed, this is slow when a directory contains a large number of items.
Due to the lack of support of SIZE, fopen
always fails when used in read mode (remember that x
isn't supported by the FTP wrapper), while ftp_size
always returns -1
(that was expected) and file_exists
always returns false
(maybe because it uses SIZE internally?).
ftp_get
and ftp_fget
do the trick, but they download the whole file if it exists. Not very good. One possible solution involves the use of ftp_fget
passing an handler of a file opened in read mode only, and catching the raised warning. It's different when the file doesn't exist, but this solution feels uncouth, and I don't really know if it's feasible (maybe someone can give an example).
Another solution uses ftp_nb_get
/ftp_nb_fget
to try to retrieve the file. If the function returns 0
(FTP_FAILED
) then the file presumably doesn't exist. I'd still have to deal with a temporary local file, and it sucks to close and reopen the connection if FTP_MOREDATA
is returned (or else other FTP commands couldn't be issued).
Do you have any idea for this?
The ftp_size() function returns the size of a specified file on the FTP server.
PHP Create File - fopen() The fopen() function is also used to create a file. Maybe a little confusing, but in PHP, a file is created using the same function used to open files. If you use fopen() on a file that does not exist, it will create it, given that the file is opened for writing (w) or appending (a).
The file_exists() function checks whether a file or directory exists.
The SIZE
command is not required. You can simply use the function ftp_nlist()
for that because the FTP LIST
command allows to pass a directory as well as file as it's argument.
Although the PHP documentation is missing to mention that it is specified in RFC 959 (page 32) and is working. Here comes an example. (Thanks Debian!
)
$server = 'ftp.us.debian.org';
$port = 21;
$user = 'anonymous';
$pwd = '[email protected]';
$conn = ftp_connect($server);
$ret = ftp_login($conn, $user, $pwd);
foreach(array(
'debian/README.html',
'NOT_FOUND.html'
) as $file) {
$listing = ftp_nlist($conn, $file);
if(empty($listing)) {
echo "$file was not found on $server\n";
} else {
echo "$file was found on $server\n";
}
}
Or, expressed as a function:
function ftp_file_exists(
$server,
$filename,
$user = 'anonymous' ,
$pwd = '',
$port = 21
) {
$conn = @ftp_connect($server);
if($conn === FALSE) {
die("Failed to connect to $server");
}
$ret = @ftp_login($conn, $user, $pwd);
if($ret === FALSE) {
die("Failed to login at $server");
}
$listing = @ftp_nlist($conn, $file);
if($listing === FALSE) {
die("Failed to obtain LIST response from $server");
}
return !empty($listing);
}
In comments there came up a discussion how useful and reliable the results of LIST
can be. Let me say some additional sentences to that...
Creating files on server
Please be aware of the fact that you should avoid to rely on something like:
if(file_not_exists_on_server($filename)) {
create_file_on_server($filename);
}
because it is possible that the file will be created by another client between the first and second function. While this is true on local file systems as well, it can happen in distributed client server applications more easily, because of longer response times compared to a local filesystem and because of possibly many, even anonymous clients (like in the example above)
When creating files remotely I would suggest to follow a strong naming scheme in public writable folders in order to avoid collisions. When following this scheme, then just write and don't care. The worst thing which can happen is that you overwrite something which somebody other has created by accident. But who creates something like /client/id/file_name.txt
by accident?
Downloading files from server or moving, deleting files on server
When attempting one of those operations, don't care about if the files exists or not before the operation. Just do it. But if it fails, you need to handle the errors properly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With