通过RESTful API上传文件?

时间:2011-08-03 02:22:52

标签: php zend-framework rest architecture file-upload

我试图通过POST方法进行RESTful API调用来上传视频。我缺少的是我不知道编写这种API的最佳实践,我也没有在互联网上找到任何资源。现在我这样做:

我正在使用PHP和zend框架(Zend_Rest_Route)。

第一种方法:

在客户端使用file_get_contents并使用curl将其POST到API,在服务器端使用file_put_contents写入该数据并发送适当的响应。

第二

使用Zend_File_Treansfer在服务器端接收文件,并将我的上传api端点的地址放在zend_form中,设置方法为post。在这种情况下,文件被上传到服务器,但在提交表单后,地址栏中的URL指向api服务器,并且永远不会返回到表单。

我做得对吗?如果没有,请告诉我最佳做法是什么以及如何做到这一点。

感谢您的时间。

2 个答案:

答案 0 :(得分:2)

这样的事情对我有用:

public function postAttachment($fileName, $fileMimetype, $fileContents, $postURL, $username, $password) 
{
    $auth = base64_encode($username . ':' . base64_decode($password));
    $header = array("Authorization: Basic ".$auth);
    array_push($header, "Accept: */*");     
    $boundary =  "----------------------------".substr(md5(rand(0,32000)), 0, 12); 

    $data = ""; 
    $data .= "--".$boundary."\r\n"; 

    //Collect Filedata          
    $data .= "Content-Disposition: form-data; name=\"file\"; filename=\"".$fileName."\"\r\n"; 
    $data .= "Content-Type: ".$fileMimetype."\r\n"; 
    $data .= "\r\n";
    $data .= $fileContents."\r\n"; 
    $data .= "--".$boundary."--";
    // add more parameters or files here

    array_push($header, 'Content-Type: multipart/form-data; boundary='.$boundary);
    $params = array('http' => array( 
       'method' => 'POST', 
       'protocol_version' => 1.1, 
       'user_agent' => 'File Upload Agent',
       'header' => $header, 
       'content' => $data 
    )); 
   $ctx = stream_context_create($params); 
   $fp = fopen($postURL, 'rb', false, $ctx); 

   if (!$fp) { 
      throw new Exception("Problem with ".$postURL." ".$php_errormsg); 
   } 
   $responseBody = @stream_get_contents($fp); 
   if ($responseBody === false) { 
      throw new Exception("Problem reading data from ".$postURL.", ".$php_errormsg); 
   } 
}

如果您想发布多个文件,或添加其他多部分参数,也可以轻松地将这些参数添加到其他边界。

我在另一篇文章中发现了一些这样的代码,你可以在PHP维基中找到类似的代码(http://www.php.net/manual/en/function.stream-context-create.php#90411 )。但是......那段代码没有正确处理回车+换行,我的服务器总是拒绝该帖子。此外,旧代码也使用HTTP版本1.0 - (不会重复使用套接字)。使用HTTP 1.1时,在发布大量文件时会重复使用套接字。 (这也适用于HTTPS。)我添加了自己的用户代理 - 如果你想让某个服务器认为这是一个浏览器帖子,你可能想要更改用户代理以欺骗浏览器。

答案 1 :(得分:0)

您是否尝试过将重定向添加到处理上传的控制器操作的结尾? (如果不是你真的应该在发布后重定向的好方法)(确保你的逻辑执行后重定向)。从本质上讲,接收帖子数据的“页面”应该只处理数据,并且您希望返回给用户的有关该帖子操作的任何信息都应该在您重定向到的页面上提供给他们。

[表格] - 发布 - > ['发布'控制器操作] - 重定向(302) - > [包含成功/失败信息的页面]