PHP*_*ver 10 php file-upload filepicker input-type-file filepicker.io
我的表单上有简单的HTML文件控件.它本质上是动态的,意味着用户可以上传一个或多个文件.它的HTML如下:
<input type="file" id="image_book" class="image_book upload" name="image[]" accept="image/*" value=""/>
Run Code Online (Sandbox Code Playgroud)
如果我使用上面的HTML文件控件上传两个图像并提交表单,我会得到以下$_FILES数组(输出print_r($_FILES);):
Array
(
[image] => Array
(
[name] => Array
(
[0] => Aurbd-b3582991-large.jpg
[1] => BL_Miller_GD_Square_KV_300dpi_A2.jpg
)
[type] => Array
(
[0] => image/jpeg
[1] => image/jpeg
)
[tmp_name] => Array
(
[0] => /tmp/phpSt8CJJ
[1] => /tmp/phpibFjR2
)
[error] => Array
(
[0] => 0
[1] => 0
)
[size] => Array
(
[0] => 519179
[1] => 86901
)
)
)
Run Code Online (Sandbox Code Playgroud)
现在根据新的要求,我将使用Filepicker而不是简单的HTML文件控件来将文件上传到服务器.但我面临的问题是考虑到上面的数组($_FILES)内容,已经编写了进一步的代码逻辑和操作.
因此,我想将通过Filepicker发出的请求转换为与数组相同的格式,$_FILES这样就不需要对已编写的代码逻辑和操作进行任何更改.
让我更清楚地向您解释一下这个场景,如果用户通过Filepicker从Google Drive中选择一个或多个图像文件并提交表单,请求将包含由Filepicker生成的图像的URL和文件名.
我想使用这些数据并形成上面数组($_FILES)的数组.
假设你使用的是PHP 5.2.1或更高版本,可以在使用HTTPS流包装copy()和file_get_contents(),这个功能应该是所有您需要:
function getFilepickerFiles($tokens)
{
$files = array('name' => array(),
'type' => array(),
'tmp_name' => array(),
'error' => array(),
'size' => array());
$tmpdir = sys_get_temp_dir();
foreach($tokens as $token)
{
$files['tmp_name'][] = $tmp = $tmpdir.'/php'.$token;
$files['error'][] = copy('https://www.filepicker.io/api/file/'.$token, $tmp) ? UPLOAD_ERR_OK : UPLOAD_ERR_NO_FILE;
$files['size'][] = filesize($tmp);
$meta = json_decode(file_get_contents('https://www.filepicker.io/api/file/'.$token.'/metadata?filename=true&mimetype=true'), TRUE);
$files['name'][] = $meta['filename'];
$files['type'][] = $meta['mimetype'];
}
return array('image' => $files);
}
Run Code Online (Sandbox Code Playgroud)
此函数将一组标记(例如hFHUCB3iTxyMzseuWOgG)作为参数.
你可以这样称呼它
getFilepickerFiles(array('hFHUCB3iTxyMzseuWOgG'));
Run Code Online (Sandbox Code Playgroud)
我不确切知道Filepicker传递给您的服务器,但如果它是一个完整的文件URL,如
https://www.filepicker.io/api/file/hFHUCB3iTxyMzseuWOgG
Run Code Online (Sandbox Code Playgroud)
那么你可以像这样提取标记:
$tokens = array();
foreach($urls as $url)
{
$matches = array();
preg_match('# ^https://www\\.filepicker\\.io/api/file/([^/]*)/?', $url, $matches);
$tokens[] = $matches[1];
}
// Pass $tokens to getFilepickerFiles()
Run Code Online (Sandbox Code Playgroud)
您也可以将其放入getFilepickerFiles()以使其采用一系列文件URL:
function getFilepickerFiles($urls)
{
$files = array('name' => array(),
'type' => array(),
'tmp_name' => array(),
'error' => array(),
'size' => array());
$tmpdir = sys_get_temp_dir();
foreach($urls as $url)
{
$matches = array();
preg_match('# ^https://www\\.filepicker\\.io/api/file/([^/]*)/?', $url, $matches);
$token = $matches[1];
$files['tmp_name'][] = $tmp = $tmpdir.'/php'.$token;
$files['error'][] = copy('https://www.filepicker.io/api/file/'.$token, $tmp) ? UPLOAD_ERR_OK : UPLOAD_ERR_NO_FILE;
$files['size'][] = filesize($tmp);
$meta = json_decode(file_get_contents('https://www.filepicker.io/api/file/'.$token.'/metadata?filename=true&mimetype=true'), TRUE);
$files['name'][] = $meta['filename'];
$files['type'][] = $meta['mimetype'];
}
return array('image' => $files);
}
Run Code Online (Sandbox Code Playgroud)
我觉得上面的代码很简单,但是这里的getFilepickerFiles()工作原理(你应该在阅读之前阅读Rest API文档):
$files = array('name' => array(),
'type' => array(),
'tmp_name' => array(),
'error' => array(),
'size' => array());
Run Code Online (Sandbox Code Playgroud)
初始化$files为不$_FILES包含文件的数组.
$tmpdir = sys_get_temp_dir();
Run Code Online (Sandbox Code Playgroud)
获取存储临时文件的目录,因为我们要将文件下载到那里(此函数需要PHP 5.2.1或更高版本).
foreach($urls as $url)
Run Code Online (Sandbox Code Playgroud)
foreach应该清楚什么.
$files['tmp_name'][] = $tmp = $tmpdir.'/php'.$token;
Run Code Online (Sandbox Code Playgroud)
按照模式$_FILES(即临时文件夹的路径,字符串"php"和一些随机字符)构建我们的临时文件路径.
我们分配的名称$tmp(以便以后使用),我们将其添加到文件路径列表中.
$files['error'][] = (int)(!copy('https://www.filepicker.io/api/file/'.$token, $tmp));
Run Code Online (Sandbox Code Playgroud)
尝试$tmp使用copy()URL作为源来下载文件.
返回的值copy()是TRUE成功和FALSE失败.
存在的错误值$_FILES是UPLOAD_ERR_OK成功的,否则是任何其他值(来源,我在UPLOAD_ERR_NO_FILE这里遇到失败).
因此,为了分配有意义的错误值,我们使用三元运算符添加UPLOAD_ERR_OK到错误代码列表(如果copy()返回)TRUE,UPLOAD_ERR_NO_FILE否则.
$files['size'][] = filesize($tmp);
Run Code Online (Sandbox Code Playgroud)
查询文件的大小并将其添加到文件大小列表中.
$meta = json_decode(file_get_contents('https://www.filepicker.io/api/file/'.$token.'/metadata?filename=true&mimetype=true'), TRUE);
Run Code Online (Sandbox Code Playgroud)
通过使用URL作为参数来获取文件元数据file_get_contents(),这应返回我们使用解码为关联数组的JSON数组json_decode(/*...*/, TRUE).
由于我们追加&filename=true&mimetype=true到URL的末尾,我们只得到了价值filename和mimetype-我们并不需要所有的休息.
我们分配的解码数组$meta;
$files['name'][] = $meta['filename'];
$files['type'][] = $meta['mimetype'];
Run Code Online (Sandbox Code Playgroud)
将值filename和mimetype刚刚解码的JSON数组分别添加到文件名和mime类型列表中.
return array('image' => $files);
Run Code Online (Sandbox Code Playgroud)
返回一个数组,其中image键指向我们创建的文件数组.
我们已经完成了.
我不会为此构建一个完整的文件托管网站,因为它需要花费我写这个答案所需时间的五倍.
所以我担心我无法为您提供完整的现场演示.
不幸的是,3v4l也不键盘已启用了HTTPS流包装,所以我甚至无法为您提供概念演示的"见换自己的"证明.
我能做的最好的可能就是终端窗口的截图(点击放大):
| 归档时间: |
|
| 查看次数: |
808 次 |
| 最近记录: |