Writing a wrapper class for cURL/FTP in PHP. When I get or put files etc. standard ops with specific cURL options, cURL doesn't return the FTP directory index as the default response.
However: When I run custom FTP commands with CURLOPT_CUSTOMREQUEST
, CURLOPT_QUOTE
or CURLOPT_POSTQUOTE
, for example to DELE
or RNFR|RNTO
, the FTP server returns the directory index as the default response in addition to running the commands. (If the commands are successful.)
This'd be expected behavior since CURLOPT_URL
is also passed in, and without upload/download the index is what you get. (And I can't connect to the server w/o using CURLOPT_URL
, or can I?) But I really don't care to waste bandwidth/RAM for receiving the index for every command I run. Would be problematic with large directories or large amounts of individual commands.
Of course I could minimize the waste by bundling up all the ops into a single curl_exec()
call. I can minimize the response by adding in a CURLOPT_FTPLISTONLY
, but that's still a load of unnecessary data being returned. Or I could append a failing command, very hackish and gives me just a fail result although the cmds are done. Or I could finally CWD into a directory that I know is blank huh? {^_^}
Then: Is there a way to tell cURL not to bother returning the directory index? Implementing a request pooler for cURL FTP calls coming in from various times/locations in other code using the class would also prevent me from returning individual success/fail responses in real time.
So. There is an option for this after all. To exclude the response body from your cURL request:
curl_setopt($this->curl, CURLOPT_NOBODY, true);
...does the trick. The command then returns an empty string or bool false
if the command failed. Information on the last failed request is available with curl_error($this->curl)
.
Now, some cURL responses to FTP commands are on the obscure side, displaying e.g. QUOT command failed with 550
(for failed rename attempt), while the actual FTP transaction was:
> RNFR /foox/test.txt
< 550 file/directory not found
* QUOT command failed with 550
Which is a lot more informative as far as what went wrong. Then set the CURLOPT_VERBOSE
option. If you don't want to log either to a file or to stdout (= on-screen), here's a handy way to capture the response into a temporary stream. (N.B. we're working within a wrapper class/object here.)
curl_setopt(CURLOPT_VERBOSE, true);
$this->stream_log = fopen('php://temp', 'r+b');
curl_setopt(CURLOPT_STDERR, $this->stream_log);
...and something like the following in your log fetcher method:
rewind($this->stream_log);
return stream_get_contents($this->stream_log);
Makes cURL transaction debugging a lot easier. Further, if you want to get just the relevant segment of the log, here's a quick regex that helps ($cmd
being the command you sent, starting the match):
preg_match("#(> {$cmd}(.*?))\\v\*#s", $log, $m);
return $m ? $m[1] : '';
When my FTP cURL wrapper for PHP is done and dusted, will make available. Happy cURLing y'all.