<form action="php.php" method="post" enctype="multipart/form-data">
Send these files:<br />
<input name="img[]" type="file" multiple="multiple" /><br />
<input type="submit" value="Send files" />
</form>
<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
foreach ($_FILES['img']['tmp_name'] as $index => $tmpName) {
if( !empty( $tmpName ) && is_uploaded_file( $tmpName ) )
{
$handle = fopen($tmpName, "r");
$data = fread($handle, filesize($tmpName));
$client_id = "d5f419ef9aedf16";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.imgur.com/3/image.json');
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Client-ID ' . $client_id));
curl_setopt($ch, CURLOPT_POSTFIELDS, array('image' => base64_encode($data)));
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_STDERR, fopen('php://stderr', 'w'));
$reply = curl_exec($ch);
$info = curl_getinfo($ch);
var_dump($info);
if(curl_errno($ch))
echo 'Curl error: '.curl_error($ch);
curl_close($ch);
$reply = json_decode($reply);
printf('<img height="180" src="%s" >', $reply->data->link);
}
}
?>
我创建了这个页面,在localhost上完美运行但是当我从服务器运行它时它不起作用,问题是我根本没有输出,甚至没有curl_getinfo或错误。不知道如何调试这个,因为我无法获得任何信息。
答案 0 :(得分:0)
你做错了几件事。
此代码:
即使在没有文件的GET请求中也会执行foreach ($_FILES['img']['tmp_name'] as $index => $tmpName) {
,因此$_FILES['img']
不存在,并且您收到Undefined index: img
错误。此外,在GET请求中,这个未定义的索引错误会返回NULL给foreach,当你告诉foreach()循环NULL时,它会给你这个错误:Invalid argument supplied for foreach()
。你还没有意识到这一点,证明你没有检查php错误日志。这是调试故障php脚本时应该做的第一件事。 - 修复这两个问题,将foreach包装在if(!empty($_FILES['img']['tmp_name']){}
中 - 接下来,找到PHP错误日志,并阅读这些错误报告。 (通常你可以在error_log
下的phpinfo()中找到它 - 或者它的emptystring,它的你的web服务器&#39;错误日志,例如对于nginx有一个空的php error_log php设置,它在nginx&#39;错误日志(如/var/log/nginx/error.log)
下一期,$handle = fopen($tmpName, "r");
这将破坏某些系统(着名的是Windows)上的二进制数据(如图像),将其更改为rb
以安全读取二进制数据(图像格式为二进制)< / p>
下一期,您认为fread()会读取您请求读取的字节数,这是不正确的。 fread将读取UP TO
所请求的字节数,但在读取所请求的字节数之前可能会因多种原因而停止。你要么必须循环调用fread直到它已经读取了所有字节,或者更好的是,使用stream_get_contents,这将基本上为你执行fread()循环。
下一期,这一行curl_setopt($ch, CURLOPT_STDERR, fopen('php://stderr', 'w'));
完全没必要,PHP的STDERR无论如何都是libcurl的默认STDERR。
下一期,你不要fclose()$ handle。这对于短脚本运行脚本来说是可以的(因为脚本完成时你的操作系统fclose()),但是你的代码越大,资源泄漏的时间越长,它总是关闭它的编程习惯,所以那样做。
下一期,我不能相信imgur实际上想要一个base64编码的图像副本,就是这样一个cpu&amp;带宽和ram waste ...他们正在使用的POST编码,multipart/form-data
是完全二进制安全的,因此没有理由对它进行base64编码...你确定他们想要base64编码吗?你和他们可以通过不使用base64编码来节省大约33%的带宽。
鉴于你在文件操作中所做的所有事情,最好使用file_get_contents
函数 - 它读取整个文件,它以二进制读取模式打开文件(相反)到您的代码,在TEXT模式下打开它,在读取时可能会破坏图像),它会读取整个文件,而不仅仅是第一个fread()调用将读取的块(如果你&# 39;幸运的是,整个文件,但如果你不幸运,只是它的第一块),它会为你做fclose()(你忘了做)
答案 1 :(得分:0)
感谢hans的建议,你是对的,使用base64不是强制性的,不是在V3 API中,它是以前的版本,不再是。现在它要快得多。这是我的最终代码
if(!empty($_FILES['img']['tmp_name'])){
foreach ($_FILES['img']['tmp_name'] as $index => $tmpName) {
if( !empty( $tmpName ) && is_uploaded_file( $tmpName ) )
{
if ($handle = fopen($tmpName, "rb")) {
$data = stream_get_contents($handle, filesize($tmpName));
$client_id = "d5f619ef9aedf16";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.imgur.com/3/image.json');
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: Client-ID ' . $client_id));
curl_setopt($ch, CURLOPT_POSTFIELDS, array('image' => $data));
curl_setopt($ch, CURLOPT_VERBOSE, true);
$reply = curl_exec($ch);
if(curl_errno($ch))
echo 'Curl error: '.curl_error($ch);
curl_close($ch);
$reply = json_decode($reply);
$screens .= $reply->data->link . " ";
fclose($handle);
}
}
}
}
没有上传图片的原因是upload_max_filesize和max_post_size,我已经增加了它们,我没有遇到任何问题。
答案 2 :(得分:0)
为什么不使用imgur php sdk并通过以下代码简单地实现它:
require_once APPPATH."/third_party/imgur/vendor/autoload.php";
$pathToFile = '../path/to/file.jpg';
$imageData = [
'image' => $pathToFile,
'type' => 'file',
];
$client->api('image')->upload($imageData);