PHP file transfer: Forget the @ - use `curl_file_create`
I just struggled uploading a file with PHP cURL. Basically, sending HTTP POST data is pretty easy. And to send a file you just needed to prefix it with an at sign (@). Adapted from the most cited example:
You see, if you add an ‘@’ sign as the first character of a post field the content will be interpreted as a file name and will be replaced by the file’s content.
At least, that is how it used to be… And how most of the examples out there show you.
However, they changed the behaviour. They recognised that this is obviously inconvenient, insecure and error prone. You cannot send POST data that starts with an @ and you always need to sanitise user-data before sending it, as it otherwise may send the contents of files on your server. And, thus, they changed that behaviour in version 5.6, see the RFC.
That means by default the
@/some/filename.ext won’t be recognized as a file – PHP cURL will literally send the @ and the filename (
@/some/filename.ext) instead of the content of that file. Took ma a while and some tcpdumping to figure that out..
Instead, they introduced a new function called
curl_file_create that will create a proper
CURLFile object for you. Thus, you should update the above snippet with the following:
Note that the contents of the
file_contents field of the
$post data differs.
So you can also define a mime type and some file name that will be sent.
That of course makes it a bit tricky to develop for different platforms, as you want your code to be valid on both PHP 5.4 and PHP 5.6 etc. Therefore you could introduce the following as a fallback:
as suggested by mipa on php.net. This creates a dummy function that is compliant with the old behaviour if there is no