图片上传/接收API

Posted

技术标签:

【中文标题】图片上传/接收API【英文标题】:Image upload/receive API 【发布时间】:2014-06-07 14:31:54 【问题描述】:

我想在我的网站上提供一个简单的 API,允许人们将图像上传到它(并接收 URL 以访问它)。

但我有几个问题:

如果用户必须以二进制代码发送图像会更好,还是如果用户必须以 idk ASCII 左右发送图像会更好?常规方式是什么? (我之所以这么问是因为我可以想象某些语言只有将文件作为文本文件读取的功能。)

我在服务器上的哪里存储图像以及如何存储?我可以将它们放入 mysql 数据库中,这样会表现良好吗?还是我应该把它们都放在一个文件夹里?

用户应该如何指定文件类型?在标题中还是在正文中?

如何接收数据并将其保存为文件?

我在其他地方找到了这段代码:

<?php

/* PUT data comes in on the stdin stream */
$putdata = fopen("php://input", "r");

/* Open a file for writing */
$fp = fopen("myputfile.ext", "w");

/* Read the data 1 KB at a time
   and write to the file */
while ($data = fread($putdata, 1024))
  fwrite($fp, $data);

/* Close the streams */
fclose($fp);
fclose($putdata);

?>

这适用于图像等二进制文件吗? “一次读取 1 KB 的数据”是个好主意吗?

【问题讨论】:

我只是在寻求更传统的更好的方法,而不是意见。我不认为我的问题是基于意见的。 对于存储,您可以 1. 将其作为 BLOB 数据存储在数据库中。在这种情况下,您还需要存储文件大小和文件格式(除非您只允许一种类型的图像),或者 2. 将文件存储在 Web 服务器或文件服务器等上,然后只存储数据库中文件的路径。后者更容易实现。 除了@Forivin 列出的问题之外,还有很多方法可以制作更好的文件上传处理程序,例如,如果您走得更远,如何处理与基本名称相同的文件会出现不同的问题,所以如果不在这里寻求任何意见,我建议尝试找到一些 API 我本来打算随机生成新名称。可能出现的其他问题是什么?而且我不想使用“一些”随机 API,我想告诉自己我应该如何制作 API...@kennypu 谢谢,我会选择第二个选项。 【参考方案1】:

最简单的方法是将文件存储在服务器上的文件夹中。然后将文件的 URL 存储在 MySQL 数据库中,如果用户不知道文件位置,则拉取文件 URL(假设您有登录功能)。

例如:

(UPLOAD.PHP 或您用于将文件上传到服务器的脚本)

<?php
    $connect_to_db = mysqli_connect('localhost', 'user', 'pass', 'db');

    $user = $_POST['user'];

    $allowedExts = array("gif", "jpeg", "jpg", "png");
    $temp = explode(".", $_FILES["file"]["name"]);
    $extension = end($temp);

    if ((($_FILES["file"]["type"] == "image/gif")
    || ($_FILES["file"]["type"] == "image/jpeg")
    || ($_FILES["file"]["type"] == "image/jpg")
    || ($_FILES["file"]["type"] == "image/pjpeg")
    || ($_FILES["file"]["type"] == "image/x-png")
    || ($_FILES["file"]["type"] == "image/png"))
    && in_array($extension, $allowedExts)) 

      if ($_FILES["file"]["error"] > 0) 

        echo "Error: " . $_FILES["file"]["error"] . "<br>";

       else 

        //Move the file to the uploads folder
        move_uploaded_file($_FILES["file"]["tmp_name"], "uploads/" . $_FILES["file"]["name"]);

        //Get the File Location
        $filelocation = 'http://yourdomain.com/uploads/'.$_FILES["file"]["name"];

        //Get the File Size
        $size = ($_FILES["file"]["size"]/1024).' kB';

        //Save to your Database
        mysqli_query($connect_to_db, "INSERT INTO images (user, filelocation, size) VALUES ('$user', '$filelocation', '$size')");

        //Redirect to the confirmation page, and include the file location in the URL
        header('Location: confirm.php?location='.$filelocation);
      
     else 
      //File type was invalid, so throw up a red flag!
      echo "Invalid File Type";
    
?>

现在您可以做的是在页面中创建一个表格,并让它根据谁登录列出所有上传的文件(再次,假设您使用此功能)。这将使人们知道必须保留他们上传的所有文件的日志。

以下示例是如果您使用 Ajax 发布数据,它会返回 JSON 格式的数据,因此您可以让用户不必重新加载页面。

<?php
    $connect_to_db = mysqli_connect('localhost', 'user', 'pass', 'db');

    $user = $_POST['user'];

    $allowedExts = array("gif", "jpeg", "jpg", "png");
    $temp = explode(".", $_FILES["file"]["name"]);
    $extension = end($temp);

    if ((($_FILES["file"]["type"] == "image/gif")
    || ($_FILES["file"]["type"] == "image/jpeg")
    || ($_FILES["file"]["type"] == "image/jpg")
    || ($_FILES["file"]["type"] == "image/pjpeg")
    || ($_FILES["file"]["type"] == "image/x-png")
    || ($_FILES["file"]["type"] == "image/png"))
    && in_array($extension, $allowedExts)) 

      if ($_FILES["file"]["error"] > 0) 

        echo json_encode(array('status' => 'error', 'msg' => 'File could not be uploaded.'));

       else 

        //Move the file to the uploads folder
        move_uploaded_file($_FILES["file"]["tmp_name"], "uploads/" . $_FILES["file"]["name"]);

        //Get the File Location
        $filelocation = 'http://yourdomain.com/uploads/'.$_FILES["file"]["name"];

        //Get the File Size
        $size = ($_FILES["file"]["size"]/1024).' kB';

        //Save to your Database
        mysqli_query($connect_to_db, "INSERT INTO images (user, filelocation, size) VALUES ('$user', '$filelocation', '$size')");

        //Return the data in JSON format
        echo json_encode(array('status' => 'success', 'data' => array('filelocation' => $filelocation, 'size' => $size)));
      
     else 
      //File type was invalid, so throw up a red flag!
      echo json_encode(array('status' => 'error', 'msg' => 'Invalid File Format'));
    
?>

如果你还想限制文件大小,你可以添加一个简单的代码行,它也会检查文件大小,如果它太大,就不要让它通过:

if ((($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpeg")
|| ($_FILES["file"]["type"] == "image/jpg")
|| ($_FILES["file"]["type"] == "image/pjpeg")
|| ($_FILES["file"]["type"] == "image/x-png")
|| ($_FILES["file"]["type"] == "image/png"))
&& ($_FILES["file"]["size"] < 20000) //Must be smaller than 20KB
&& in_array($extension, $allowedExts)) 

如果您需要更多帮助,请随时告诉我。 :)

【讨论】:

那么用户如何将图片发送到脚本?就像请求正文中的二进制代码一样? 取决于几件事。如果它是一个 API,它比它只是一个网站上的表单要复杂一些。你的最终目标是什么?能否让用户通过 API 或表单推送数据? 就像我在问题中提到的那样,我想编写一个 API。我希望它简单,但它也应该可以在大多数常见的编程语言中使用。网站上不会有表单,用户只能通过API上传图片。 让我在几秒钟内玩一些东西,我会告诉你的:) Forivin,您希望您的 API 支持哪些语言? PHP,JS?还是更多?【参考方案2】:

我还建议使用fileinfo 或什至像imagemagic 这样的库来确保图像是图像 - 如果将其转换为可以在页面上显示的图像。

还因为您在文件已经发送到服务器后检查文件大小,您可以检查是否可以将其大小转换为更小而不是仅仅拒绝它。

PS:http://www.plupload.com/ 这是一个库,您可以免费使用或一次性支付少量费用 - 它也有一些 php 编写的接收器。

【讨论】:

【参考方案3】:

你可以encode_base64原始的php输入-图像文件-并存储在一个mysql行中,它是ASCII BIN,LONG TEXT结构,然后从mysql中拉回数据并显示如下:

<img  src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIA..." />

【讨论】:

根据我的阅读,数据库在数据过于拥挤时会变得非常慢。所以我想我现在会置身事外。我也只有一个数据库可用。 :/ 不过还是谢谢你!【参考方案4】:

布赖恩的回答提到的上传方法是一个理想的解决方案。并且很容易存储图片。您应该在您的服务器的数据库中创建一个表并存储图片的文件名,例如“filename.+filetype”的格式。然后将图片存储在服务器的某个文件夹中。

你不需要像www.xxx.com/upload/temp/1.png那样存储图片的整个路径,尝试使用php函数为www.xxx.com/upload创建绝对路径/temp/,然后一旦你想显示图片。只需使用

<img src="<?php echo func("1.png")?>" > 

func() 是一个创建绝对路径的函数。

更多信息可以查看w3c教程PHP file upload

我在我的网站中使用这种方式。希望对你有帮助。

【讨论】:

但如果我理解正确的话,他发布的内容是用于 html 表单上传的。所以这对于使用完全不同语言的人来说并不是很理想。【参考方案5】:

你的想法太低级了

您的 API 确实应该建立在已经解决了此类表示问题的其他协议之上。

例如,通过 HTTP,只需将文件以其原始二进制形式传输——当然,可以在协议标头中指定已将编码应用于内容或传输,但几乎只支持压缩编码(导致更多二进制)。

【讨论】:

以上是关于图片上传/接收API的主要内容,如果未能解决你的问题,请参考以下文章

接收IOS上传的图片

解决小程序webview中无法上传图片问题

ckeditor5上传的图片如何用PHP接收?

Jersey后端服务接收ajax前端的图片上传

Jersey后端服务接收ajax前端的图片上传

前端批量上传图片后端怎么接收?