所以我正在制作一些东西,用户需要使用Wordpress内置的Media Upload API从canvas元素(在前端)上传图像。
我已成功使用API从文件输入中上传图像:
<input type="file" name="async-upload" id="async-upload" size="40" />
...
<?php $new_attach_id = media_handle_upload( 'async-upload', $new_id ); ?>
我使用自己的脚本从画布中保存了图像:
<script type="text/javascript">
...
var img = canvas.toDataURL("image/png");
...
ajax.send(img );
</script>
...
<?php
$imageData=$GLOBALS['HTTP_RAW_POST_DATA'];
$filteredData=substr($imageData, strpos($imageData, ",")+1);
$unencodedData=base64_decode($filteredData);
$fp = fopen( 'saved_images/canv_save_test.png', 'wb' );
fwrite( $fp, $unencodedData);
...
?>
问题是,Wordpress的media_handle_upload()只接受$ _FILES数组的索引以进行上传。
所以问题是:如何将图像数据从HTTP_RAW_POST_DATA传递给它?我可以以某种方式让$ _FILES ['tmp-name']指向它吗?我能以某种方式使用另一个脚本作为中间步骤吗?我可以释放打字机上的猴子,直到他们拿出答案吗?
非常感谢任何帮助!
谢谢, 凯恩
编辑:解决了
感谢@alex提出的file_put_contents建议,以及我发布的另一个相关问题的答案here我现在有了这个工作。解决方案:在HTTP请求中发送未更改的base64图像数据,覆盖PHP生成的tmp_file并关闭WP的一些安全检查。不知道那是多么安全,但这里是任何遇到同样问题的人的代码:
<script type="text/javascript">
$('#save').click(function() {
// get image data from cavas
var img = canvas.toDataURL("image/png");
// open ajax request
var ajax = new XMLHttpRequest();
ajax.open("POST",script_url,false);
//ajax.open("POST","/dumpvars.php",false); // testing
// set headers
boundary_str = "AJAX-------------" + (new Date).getTime();
ajax.setRequestHeader('Content-Type', "multipart/form-data; boundary=" + boundary_str);
// callback for completed request
ajax.onreadystatechange=function()
{
if (ajax.readyState == 4)
{
// Write out the filename.
$("#ajax_out").html("Response: "+ajax.responseText+" End Response");
}
}
// BUILD REQUEST
var boundary = '--' + boundary_str;
var request_body = boundary + '\n'
// print all html form fields
$('#save_form input').each(function(){
request_body += 'Content-Disposition: form-data; name="'
+ $(this).attr('name') + '"' + '\n'
+ '\n'
+ $(this).val() + '\n'
+ '\n'
+ boundary + '\n';
});
// make filename
var filename = $('#save_form input[name="title"]').val();
filename = filename.replace(/\s+/g, '-').toLowerCase(); // hyphenate + lowercase
filename = encodeURIComponent(filename) + (new Date).getTime() + ".png";
// add image
request_body += 'Content-Disposition: form-data; name="async-upload"; filename="'
+ filename + '"' + '\n'
+ 'Content-Type: image/png' + '\n'
+ '\n'
+ img
+ '\n'
+ boundary;
// Send request
ajax.send(request_body);
});
</script>
...
<?php
// Get transmitted image data
$loc = $_FILES['async-upload']['tmp_name'];
$file = fopen($loc, 'rb');
$contents = fread($file, filesize($loc));
fclose($file);
// Decode image data
$filteredData=substr($contents, strpos($contents, ",")+1);
$unencodedData=base64_decode($filteredData);
// Overwrite temp file
file_put_contents($loc, $unencodedData);
// Pass image data to WP Upload (attach to post)
$override['test_upload'] = false; // Override WP's upload security test (rewriting tmp_name made it fail)
$override['test_form'] = false;
$new_attach_id = media_handle_upload( 'async-upload', $new_id, array() , $override );
?>
答案 0 :(得分:1)
您可以file_put_contents()
某处的数据,然后创建自己的虚假$_FILES
数组来欺骗WordPress函数。
答案 1 :(得分:0)
我将更新这篇文章,以及我是如何做到这一点的,以防其他人正在努力将Canvas数据保存到Wordpress作为帖子附件。
我没有使用media_handle_upload而是必须使用$ _FILES数组,而是使用了media_sideload_image函数。为了做到这一点,您只需将画布图像保存到服务器上的文件夹中,然后将该URL传递给media_sideload_image和帖子ID即可。它会将该文件附加到您的帖子并将图像复制到您的上传文件夹。您可以在服务器上创建一个TEMP_UPLOADS文件夹来存储上传的文件,然后成功将其附加到手动删除它的帖子。
define('UPLOAD_DIR', 'path/to/termp-folder/');
$img = $_POST['img'];
$post_id = $_POST['postId'];
$post_id = (int) $post_id;
$img = str_replace('data:image/jpeg;base64,', '', $img);
$img = str_replace(' ', '+', $img);
$data = base64_decode($img);
$file = UPLOAD_DIR . uniqid() . '.jpg';
$success = file_put_contents($file, $data);
$fullURL = $file;
$val = media_sideload_image($fullURL, $post_id, 'none');
echo $val;
上面的示例不会删除旧的临时文件,但您可以轻松地弄清楚如何执行此操作。我觉得这个解决方案更简单,效果更好。