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.
First, 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:
<html>
<head>
<title>Upload Form</title>
</head>
<body>
<?php echo $error;?>
<?php $data = array(‘type‘=>‘shop‘, ‘id‘=>‘1‘);?>
<?php echo form_open_multipart(‘upload/web_upload‘, ‘‘, $data);?>
<input type="file" name="f_file[]" multiple="multiple" size="20" />
<br /><br />
<input type="submit" value="upload" />
</form>
</body>
</html>
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
Second, 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)