php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #51507 Setting filename for @... multipart uploads
Submitted: 2010-04-08 11:47 UTC Modified: 2013-03-02 18:46 UTC
Votes:4
Avg. Score:3.8 ± 1.3
Reproduced:4 of 4 (100.0%)
Same Version:1 (25.0%)
Same OS:1 (25.0%)
From: david at frankieandshadow dot com Assigned: reeze (profile)
Status: Closed Package: cURL related
PHP Version: 5.2.13 OS: n/a
Private report: No CVE-ID: None
 [2010-04-08 11:47 UTC] david at frankieandshadow dot com
Description:
------------
Using curl_setopt, you can make a multipart POST by passing an array of parameters, and if preceded by an @, a file upload is created from the path following the @.
  curl_setopt(CURLOPT_POSTFIELDS, array('myfile'=>"@{$pathname}"));
However, I haven't been able to find a way to set the filename part of the multipart description, so that it generates e.g.
  Content-disposition: form-data; name="myfile"; filename="desiredfilename"
  Content-Type: text/plain
That is, there isn't a way to get "desiredfilename" in there. The only option seems to be for the filename part appears to come from the name of the file within the path. The cURL command line interface seems to support explicitly setting the filename different from the name of the source file with 
'-F "@path ; filename=whatever'
so presumably it is possible in the library, but not exposed through the PHP binding.

In case it was merely passing on the string to the cURL library verbatim, I tried:
 curl_setopt(CURLOPT_POSTFIELDS, array('myfile'=>"@{$pathname}; filename=\"desiredfilename\""));
but that gives an error.

The problem is that the files I have are stored with simple numeric names and the file names which an external user would know them by are in the database that indexes the disk files. I have a workround which is to make a temporary hard link to the file by its user name and give that to cURL, but I don't think I should really need to do that.

Test script:
---------------
    $now = time(); $tmpdirpath = "/tmp/enspub-{$now}-{$version->id}";
    mkdir($tmpdirpath);
    $tmpfilepath = "{$tmpdirpath}/" . mb_ereg_replace('[/\\\\?%*:|"<>@~=+]', '_', $version->name); // replace disallowed characters
    link($version->pathname(), $tmpfilepath);
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); /* tell me, not echo */
    curl_setopt($ch, CURLOPT_POST, TRUE);
    $post['file'] = "@{$tmpfilepath}"; 
    /* ... and other $post settings ... */
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post); 
    $data = curl_exec($ch);
    /* ... error checking ... */
    curl_close($ch);
    @unlink($tmpfilepath);
    @rmdir($tmpdirpath);



Expected result:
----------------
It works, but I'd like to be able to set the filename explicitly without copying the file.

Actual result:
--------------
n/a

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2011-11-22 09:20 UTC] pierrick@php.net
This bug has been fixed in SVN.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.
 
Thank you for the report, and for helping us make PHP better.

This functionality is implemented but you need to remove the space beetween the 
";" and the "filename". You can even put the type :

curl_setopt(CURLOPT_POSTFIELDS, array('myfile'=>"@{$pathname};type=image/jpeg; 
filename=name.jpg"));
 [2011-11-22 09:20 UTC] pierrick@php.net
-Status: Open +Status: To be documented
 [2013-03-02 18:46 UTC] reeze@php.net
As pierrick said, implemented. close
 [2013-03-02 18:46 UTC] reeze@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: reeze
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu May 02 12:01:29 2024 UTC