如何检测图像字段的API帖子是文件,base64字符串还是图像URL?

I have a PHP Laravel app which is being used as an API for my frontend JavaScript App.

On my image fields I currently simply store an image URL in my database which would require the frontend app to handle uploading the image before posting to save it to my API.

My goal is to make all my API image fields accept any of these:

  • Binary file upload
  • Base64 Data for an image
  • URL of a remote image

My API would then detect which of the 3 types an incoming image field post is and handle it as needed. Binary file would upload the file and save the local image URL to the database, Base64 image would also save to a local image and save the URL to the DB, a remote image URL would download the image using something like cURL and save the local image URL to the DB.

What I described that I want to do is what API's like the one imgur.com has. Below are the API specs for creating a new image through their API:

Upload a new image with imgur.com API

Method  POST
Route   https://api.imgur.com/3/image

Parameters
Key        Required      Description
------------------------------------
image      required      A binary file, base64 data, or a URL for an image. (up to 10MB)

So my question now is, using PHP: How can I detect if a POST for my image field is an image file, a Base64 string, or an image URL string?

I suppose a real image file would come to you as a multi-part attachment. As such, you would detect this by sniffing out the $_FILES array: if there's an image there, a real image file was uploaded to your API. Specifically, in Laravel, you'd use $request->file

Otherwise, then you would have a string value in the request's data. You could sniff out the value: if it starts with data:image it is an encoded image.

Finally, you could look for strings starting with http or be smarter and look for a domain format, something like:

/http(?:s)?:\/\/(?:[\w-]+\.)*([\w-]{1,63})(?:\.(?:\w{3}|\w{2}))(?:$|\/)/i

Hope this helps!

Base64 doesn't allow the ':' character that you would typically find in a url, or you could check for 'http://' and 'https://' if you only intend on supporting those protocols.

Files in the post can be found in $_FILES, or using laravel you can check for a file using the hasFile() function as mentioned on https://laravel.com/docs/5.3/requests.