Server based PHP codeigniter,android based on volley for multi-file/image upload (including server, Web version and Android client complete code)

Source: Internet
Author: User
Tags codeigniter

Issue background: When uploading images, the app also passes the parameters, supporting the delivery of multiple images. The environment in this article already has the CodeIgniter framework of the server in place by default. In fact, it is possible not to use this framework.



One, the server section
1, helpers new file under Controllers upload_helper.php

<?php
/**
 * Make multifile array input complaint with CI_Upload.<br>
 * For use files[ ] input name you must use it method.
 *
 * @author porquero
 *
 * @example
 * In Controller<br>
 * $this->load->helper(‘upload‘);<br>
 * multifile_array();<br>
 * foreach ($_FILES as $file => $file_data) {<br>
 *    $this->upload->do_upload($file);
 * ...
 *
 * @link http://porquero.blogspot.com/2012/05/codeigniter-multifilearray-upload.html
 */
function multifile_array()
{
    if(count($_FILES) == 0)
        return;

    $files = array();
    $all_files = $_FILES[‘f_file‘][‘name‘];
    $i = 0;

    foreach ((array)$all_files as $filename) {
        $files[++$i][‘name‘] = $filename;
        $files[$i][‘type‘] = current($_FILES[‘f_file‘][‘type‘]);
        next($_FILES[‘f_file‘][‘type‘]);
        $files[$i][‘tmp_name‘] = current($_FILES[‘f_file‘][‘tmp_name‘]);
        next($_FILES[‘f_file‘][‘tmp_name‘]);
        $files[$i][‘error‘] = current($_FILES[‘f_file‘][‘error‘]);
        next($_FILES[‘f_file‘][‘error‘]);
        $files[$i][‘size‘] = current($_FILES[‘f_file‘][‘size‘]);
        next($_FILES[‘f_file‘][‘size‘]);
    }
    $_FILES = $files;
}


Description:
A. Note that the key inside is ' f_file ', which requires the app or the Web to match this value when uploading and building the form.

B. The file is mainly traversing the $_files, which is transferred to the array by current file information, and then returned. Note that the post-rollover index starts at 1. The dump field has name/type/tmp_name/error/size, using next to move the pointer to $_files[' f_file ' [' key '].



New upload_form.php in 2.views to simulate the success of a test upload on the Web:

Note: 
A, the form_open_multipart of the CI framework is used to create a new multipart form that accesses the Web_upload method in the controller upload, and the third parameter $data to simulate the post request parameters passed to the server . Of course you can also add a few <input> below; 

B,input name corresponds to the f_file[], this is with the server side of the unified good. 

C, to support multi-file upload plus multiple= "multiple", do not add the words can only upload one file at a time. 

3,views new upload_success.php, display the interface after the successful upload. 

<html>
<head>
    <title>Upload Form</title>
</head>
<body>

<h3>Your file was successfully uploaded!</h3>

<ul>
    <?php foreach ($upload_data as $item => $value):?>
        <li><?php echo $item;?>: <?php echo $value;?></li>
    <?php endforeach; ?>
</ul>

<p><?php echo anchor(‘upload‘, ‘Upload Another File!‘); ?></p>

</body>
</html>

Note: The $upload_data here is the data passed to view when the controller uploads successfully. 
4, Next is the most critical of a class, in the Controllers folder under the new upload.php, this is a controller, upload the most core. 


<?php

require_once APPPATH . ‘controllers/base/BASE_CI_Controller.php‘;
class Upload extends BASE_CI_Controller{
    private $m_type = ‘‘;
    private $m_id = ‘‘;
    private $m_path = ‘./application/cache/image‘;
    private $m_error = array();
    public function __construct()
    {
        parent::__construct();
        $this->load->helper(array(‘form‘, ‘url‘, ‘upload‘));
        //$this->load->model(‘picture_model‘);
    }

    public function index()
    {
        $this->load->view(‘upload_form‘, array(‘error‘ => ‘ ‘ ));
    }

    public function app_upload(){
        $this->init_argc();
        multifile_array();
        foreach ($_FILES as $file => $file_data){
            $this->do_upload($file);
        }
        if($this->m_error == NULL || count($this->m_error) == 0){
            $this->output->set_output(json_encode(array(‘msg‘=>‘上传成功‘)));
        }else{
            $this->output->set_output(json_encode($this->m_error));
        }
    }


    public function do_upload($file)
    {
        $config[‘upload_path‘]      =  $this->m_path;
        $config[‘allowed_types‘]    = ‘gif|jpg|png|jpeg‘;
        $config[‘max_size‘]     = 10240;
        $config[‘max_width‘]        = 2000;
        $config[‘max_height‘]       = 2000;
        $config[‘file_name‘] = Util::random_str();

        $this->load->library(‘upload‘, $config);

        if ( ! $this->upload->do_upload($file)){
            $this->on_upload_error($this->upload->display_errors());
        }
        else{
            $upload_data = $this->upload->data();
            $this->on_upload_success($upload_data[‘file_name‘]);
        }
    }

    public function do_upload2($file)
    {
        $config[‘upload_path‘]      =  $this->m_path;
        $config[‘allowed_types‘]    = ‘gif|jpg|png|jpeg‘;
        $config[‘max_size‘]     = 10240;
        $config[‘max_width‘]        = 2000;
        $config[‘max_height‘]       = 2000;
        $config[‘file_name‘] = Util::random_str();

        $this->load->library(‘upload‘, $config);

        if ( ! $this->upload->do_upload($file))
        {
            $error = array(‘error‘ => $this->upload->display_errors());
            $this->load->view(‘upload_form‘, $error);
        }
        else
        {
            $data = array(‘upload_data‘ => $this->upload->data());

            $this->load->view(‘upload_success‘, $data);
        }
    }

    public function web_upload()
    {
        multifile_array();
        foreach ($_FILES as $file => $file_data){
            $this->do_upload2($file);
        }
    }

    private function init_argc() {
        $this->m_type = $this->getPost(‘type‘);
        $this->m_id = $this->getPost(‘id‘);
        $this->m_path = $this->getPath($this->m_type);
    }

    private function getPath($type){
        $path = ‘./application/cache/image/shop‘;
        if($type == "shop"){
            $path =  ‘./application/cache/image/shop‘;
        }
        return $path;

    }

    private function on_upload_success($name){
        if($this->m_type == ‘shop‘){
            //$this->picture_model->add_shop_picture($this->m_id, $this->m_type, $name);
        }else if($this->m_type == ‘avatar‘){
            //$this->picture_model->add_user_avatar($this->m_id, $this->m_type, $name);
        }
    }
    private function on_upload_error($error){
        $this->m_error[‘msg‘] = $error;
    }

}
?>


The explanations are as follows: 

A, here upload is inherited Base_ci_controller, can also be replaced with Ci_controller, in their own base_ci_controller encapsulated in their own project  

some common security check logic; 

B, I define the type of M_type record upload picture, m_id is the Id,m_path of the object to which the picture belongs, it can be differentiated according to  

the different path of type. M_error record error. In the constructor, be careful to load a few helpers in. Besides I also wrote a picture_model used to  

manipulate the image related database, if you do not need this model, can be commented out. 

C,app_load () is a variety of parameters exposed to the app for uploading, INIT_ARGC () initializing post. Then the Multifile_array () is adjusted and then  

the upload is traversed. After the upload is complete according to whether the M_error is empty, judging is what message to show to the app. The  

Util::random_str () in Do_upload () is a very simple timestamp MD5, which prevents the name of the image: 



The code in Util: 

/**
      * Generate a new token
      * @return string
      */
     Public static function token(){
         $curr = Util::time();
         Return md5($curr);
     }

     Public static function random_str(){
         Return Util::token();
     }


After each upload success, on_upload_success () On_upload_error () to update the database and so on. where On_upload_success () to  

receive $upload_data[' file_name '), indicates the name of the file after the successful upload. 

D,web_upload is to upload images for the web, through Do_upload2 () upload a view to display the uploaded information.  PS: Make sure you have 

writable permissions to the destination folder.  



First use the web to test the effect: http://localhost/~yanzi/city52/index.php/upload 

Two, client: Volley-based multi-file/image upload class encapsulation 
This is relatively simple, based on the volley package, Multipartrequest.java 


Package com.android.nomnom.volley;

Import android.util.Log;

Import com.android.volley.AuthFailureError;
Import com.android.volley.NetworkResponse;
Import com.android.volley.Request;
Import com.android.volley.Response;
Import com.android.volley.VolleyLog;
Import com.android.volley.toolbox.HttpHeaderParser;

Import org.apache.http.entity.mime.MultipartEntity;
Import org.apache.http.entity.mime.content.FileBody;
Import org.apache.http.entity.mime.content.StringBody;

Import java.io.ByteArrayOutputStream;
Import java.io.File;
Import java.io.IOException;
Import java.io.UnsupportedEncodingException;
Import java.nio.charset.Charset;
Import java.util.ArrayList;
Import java.util.Collections;
Import java.util.HashMap;
Import java.util.List;
Import java.util.Map;

/**
 * Features:
 *
 * @author yanzi E-mail: yanzi1225627@163.com
 * @version Creation time: 2015-08-09 4:32 PM
 */
Public class MultipartRequest extends Request<String>{

    Private MultipartEntity entity = new MultipartEntity();

    Private Response.Listener<String> mListener;

    Private List<File> mFileParts;
    Private String mFilePartName;
    Private Map<String, String> mParams;

    /**
     * Single file + parameter upload
     * @param url
     * @param listener
     * @param errorListener
     * @param filePartName
     * @param file
     * @param params
     */
    Public MultipartRequest(String url, Response.Listener<String> listener, Response.ErrorListener errorListener,
                            String filePartName, File file, Map<String, String> params){
        Super(Method.POST, url, errorListener);
        mFileParts = new ArrayList<File>();
        If(file != null && file.exists()){
            mFileParts.add(file);
        }else{
            VolleyLog.e("MultipartRequest---file not found");
        }
        mFilePartName = filePartName;
        mListener = listener;
        mParams = params;
        buildMultipartEntity();

    }

    /**
     * Multiple files + parameter upload
     * @param url
     * @param listener
     * @param errorListener
     * @param filePartName
     * @param files
     * @param params
     */
    Public MultipartRequest(String url,Response.Listener<String> listener,Response.ErrorListener errorListener
                            , String filePartName,List<File> files, Map<String, String> params) {
        Super(Method.POST, url, errorListener);
        mFilePartName = filePartName;
        mListener = listener;
        mFileParts = files;
        mParams = params;
        buildMultipartEntity();
    }

    @Override
    Protected Response<String> parseNetworkResponse(NetworkResponse response) {
        String parsed;
        Try {
            Parsed = new String(response.data,
                    HttpHeaderParser.parseCharset(response.headers));
        } catch (UnsupportedEncodingException e) {
            Parsed = new String(response.data);
        }
        Return Response.success(parsed,
                HttpHeaderParser.parseCacheHeaders(response));
    }

    @Override
    Protected void deliverResponse(String response) {
        mListener.onResponse(response);
    }

    @Override
    Public Map<String, String> getHeaders() throws AuthFailureError {
        Map<String, String> headers = super.getHeaders();

        If (headers == null || headers.equals(Collections.emptyMap())) {
            Headers = new HashMap<String, String>();
        }
        Return headers;
    }

    @Override
    Public String getBodyContentType() {
        Return entity.getContentType().getValue();
    }

    @Override
    Public byte[] getBody() throws AuthFailureError {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        Try{
            entity.writeTo(bos);
        } catch (IOException e) {
            VolleyLog.e("IOException writing to ByteArrayOutputStream");
        }
        Return bos.toByteArray();
    }

    Private void buildMultipartEntity() {
        If (mFileParts != null && mFileParts.size() > 0) {
            For (File file : mFileParts) {
                entity.addPart(mFilePartName, new FileBody(file));
            }
            Long l = entity.getContentLength();
            Log.i("YanZi-volley", mFileParts.size() + ", length: " + l);
        }

        Try {
            If (mParams != null && mParams.size() > 0) {
                For (Map.Entry<String, String> entry : mParams.entrySet()) {
                    entity.addPart(
                            entry.getKey(),
                            New StringBody(entry.getValue(), Charset
                                    .forName("UTF-8")));
                }
            }
        } catch (UnsupportedEncodingException e) {
            VolleyLog.e("UnsupportedEncodingException");
        }
    }
}

If you use a new request and add it to the queue, I won't write an example. Next introduction android upload/download file with progress bar 

implementation.  



Reference: CodeIgniter http://codeigniter.org.cn/ 

Server based PHP codeigniter,android based on volley for multi-file/image upload (including server, Web version and Android client complete code) 


 





Related Article

E-Commerce Solutions

Leverage the same tools powering the Alibaba Ecosystem

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.