3

I know I can use this syntaxt to send a file using php, post and curl.

$post = array(
    "file_box"=>"@/path/to/myfile.jpg",
);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post); 

How can I take a string, build a temp file and send it using the exact same syntax ?

Update: I would prefer using tmpfile() or php://memory so I don't have to handle file creation.

4
  • 2
    duplicate of this question: POST a file string using cURL in PHP? (you will find your answer there) Commented May 27, 2011 at 9:03
  • Not a real answer there. @emil gave a great solution so far. Commented May 27, 2011 at 9:05
  • Erm, yes it is a real answer to send a file through curl when you have its content in a string. Tatu's answer is a different solution that involves temporary files (so you're not sending a string as file, you are sending an actual file). Commented May 27, 2011 at 9:07
  • @johnlemon: You asked too early, the answer is here: PHP create random tmp file and get its full path - at least for the tmpfile() part and how to create one from string and obtain the path to it then so you can use it in the (now defunct) @ syntax. Commented Jul 12, 2023 at 9:42

4 Answers 4

15

You can create a file using tempnam in your temp directory:

$string = 'random string';

//Save string into temp file
$file = tempnam(sys_get_temp_dir(), 'POST');
file_put_contents($file, $string);

//Post file
$post = array(
    "file_box"=>'@'.$file,
);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);

//do your cURL work here...

//Remove the file
unlink($file);
Sign up to request clarification or add additional context in comments.

Comments

7

Since PHP 8.1 there's also CURLStringFile which would allow you to send it without the temporary file:

$txt = 'test content';
$file = new \CURLStringFile($txt, 'filename.txt', 'text/plain');

$ch = curl_init('https://example.com/upload');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, ['file' => $file]);
curl_exec($ch);

1 Comment

Technically not the @ syntax op asks about. Why not consider to move the answer here: stackoverflow.com/q/3085990/367456 ? It looks like a better fit for this reference to me. (you can ping me there so that I can move my +1 there, too).
0

You can create a temporary file using file_put_contents, just make sure that the target directory is writable.

$path = '/path/to/myfile.txt';    
file_put_contents($myData, $path);

$post = array(
    "file_box"=>"@".$path,
);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);

# Delete the file if you don't need it anymore
unlink($path);

Comments

0

From http://php.net/manual/en/class.curlfile.php#115161

$files = array()) {
  
             // invalid characters for "name" and "filename"
             static $disallow = array("\0", "\"", "\r", "\n");

             // build normal parameters
             foreach ($assoc as $k => $v) {
                 $k = str_replace($disallow, "_", $k);
                 $body[] = implode("\r\n", array(
                     "Content-Disposition: form-data; name=\"{$k}\"",
                     "",
                     filter_var($v),
                 ));
             }

             // build file parameters
             foreach ($files as $k => $v) {
                 switch (true) {
                     case false === $v = realpath(filter_var($v)):
                     case !is_file($v):
                     case !is_readable($v):
                         continue; // or return false, throw new InvalidArgumentException
                 }
                 $data = file_get_contents($v);
                 $v = call_user_func("end", explode(DIRECTORY_SEPARATOR, $v));
                 $k = str_replace($disallow, "_", $k);
                 $v = str_replace($disallow, "_", $v);
                 $body[] = implode("\r\n", array(
                     "Content-Disposition: form-data; name=\"{$k}\"; filename=\"{$v}\"",
                     "Content-Type: image/jpeg",
                     "",
                     $data,
                 ));
             }

             // generate safe boundary
             do {
                 $boundary = "---------------------" . md5(mt_rand() . microtime());
             } while (preg_grep("/{$boundary}/", $body));

             // add boundary for each parameters
             array_walk($body, function (&$part) use ($boundary) {
                 $part = "--{$boundary}\r\n{$part}";
             });

             // add final boundary
             $body[] = "--{$boundary}--";
             $body[] = "";

             // set options
             return @curl_setopt_array($ch, array(
                 CURLOPT_POST       => true,
                 CURLOPT_POSTFIELDS => implode("\r\n", $body),
                 CURLOPT_HTTPHEADER => array(
                     "Expect: 100-continue",
                     "Content-Type: multipart/form-data; boundary={$boundary}", // change Content-Type
                 ),
             ));
         }

$array1=array('other_post_field'=>'value');
$array2=array('file'=>'document_content_string'); $ch = curl_init();  
curl_setopt($ch, CURLOPT_URL,$url);
curl_custom_postfields($ch,$array1,$array2);//above custom function
$output=curl_exec($ch); close($ch);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.