使用Codeigniter无法上传base64编码的图像

4
我需要上传从安卓应用接收到的base64编码图像。我正在使用php codeigniter框架。在浏览论坛时,我发现这个链接中的问题与我的相同:如何在codeigniter中上传base64编码的图像,但那里的解决方案对我不起作用。
以下是我编写的代码:
private function _save_image() {
    $image = base64_decode($_POST['imageString']);
    #setting the configuration values for saving the image
    $config['upload_path'] = FCPATH . 'path_to_image_folder';
    $config['file_name'] = 'my_image'.$_POST['imageType'];
    $config['allowed_types'] = 'gif|jpg|jpeg|png';
    $config['max_size'] = '2048';
    $config['remove_spaces'] = TRUE;
    $config['encrypt_name'] = TRUE;


    $this->load->library('upload', $config);
    if($this->upload->do_upload($image)) {
        $arr_image_info = $this->upload->data();
        return ($arr_image_info['full_path']);
    }
    else {
        echo $this->upload->display_errors();
        die();
    }
}

我遇到了“您没有选择要上传的文件”错误提示。
感谢您的时间。
2个回答

5
错误是因为codeigniter的上传库会查找do_upload()调用时给定的索引,从而查找$_FILES超全局变量中的内容。
此外(至少在2.1.2版本中),即使您设置了$_FILES超全局变量以模拟文件上传的行为,它也不会通过,因为上传库使用is_uploaded_file来检测超全局变量被篡改。您可以追踪system/libraries/Upload.php:134中的代码。
恐怕您要重新实现大小检查,文件重命名和移动(我会这样做),或者您可以修改codeigniter以省略该检查,但这可能会使将来升级框架更加困难。
  1. Save the $image variable's content to a temporary file, and set up the $_FILES to look like this:

     $temp_file_path = tempnam(sys_get_temp_dir(), 'androidtempimage'); // might not work on some systems, specify your temp path if system temp dir is not writeable
     file_put_contents($temp_file_path, base64_decode($_POST['imageString']));
     $image_info = getimagesize($temp_file_path); 
     $_FILES['userfile'] = array(
         'name' => uniqid().'.'.preg_replace('!\w+/!', '', $image_info['mime']),
         'tmp_name' => $temp_file_path,
         'size'  => filesize($temp_file_path),
         'error' => UPLOAD_ERR_OK,
         'type'  => $image_info['mime'],
     );
    
  2. Modify the upload library. You can use codeigniter's built in way of Extending Native Libraries, and define a My_Upload (or your prefix) class, copy-paste the do_upload function and change the following lines:

    public function do_upload($field = 'userfile')
    

    to:

    public function do_upload($field = 'userfile', $fake_upload = false)
    

    and the:

    if ( ! is_uploaded_file($_FILES[$field]['tmp_name']) )
    

    to:

    if ( ! is_uploaded_file($_FILES[$field]['tmp_name']) && !$fake_upload )
    

    and in your controller, call do_upload() with the flowing parameters:

    $this->upload->do_upload('userfile', true);
    

嗨,谢谢你的回复。我按照你的指示进行了更改,但是我遇到了以下错误:
  1. 在第86行出现未定义索引的错误,代码如下:$this->file_name = $this->_prep_filename($_FILES[$field]['name']);,这段代码是我在MY_Upload类中复制并粘贴的do_upload函数。
  2. 你尝试上传的文件类型不允许。这是print_r的输出结果:Array ( [userfile] => Array ( [tmp_name] => C:\Windows\Temp\and15BC.tmp [size] => 354129 [error] => 0 [type] => image/png ) )
- Parth
我忘记了$_FILES中的“name”键,已经更新了示例,这应该可以修复两个错误。 - complex857
嗨,complex857, 在我的系统上(Windows 7,WAMP),图像上传功能正常工作。但是今天我将其上传到服务器上,代码在那里无法正常工作。我收到“您没有选择要上传的文件”这个消息。我回显了file_put_contents()函数的输出,并根据文档获得了字节数计数。请帮帮我。如果有用的话,我必须在Amazon EC2 Linux服务器上运行此服务器。 - Parth
听起来像是CI没有找到你的MY_Upload类。检查文件名中的大写/小写字符,Windows不区分大小写,而Unix系统则区分大小写。您可以通过在控制器中打印$this->upload实例的类名来检查它是否工作。 print get_class($this->upload);应该显示MY_upload - complex857
非常感谢!我把文件保存为"My_upload"而不是"MY_Upload"。现在两个地方都可以正常工作了。再次感谢您的帮助。 - Parth

1

如果您收到的是一个Base64编码的图像字符串,那么您无需使用Upload类。

相反,您只需要使用base64_decode解码它,然后使用fwrite/file_put_contents保存解码后的数据即可...

$img = imagecreatefromstring(base64_decode($string)); 
if($img != false) 
{ 
   imagejpeg($img, '/path/to/new/image.jpg'); 
}  

来源:http://board.phpbuilder.com/showthread.php?10359450-RESOLVED-Saving-Base64-image


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接