清风徐来
Michael's Blog
Codeigniter里的无刷新上传

好久没有更新了,写点吧算是翻译吧,纯原创没空啊XD Codeigniter还是很好用的,淡水一直很推崇。说是codeigniter里的无刷新上传吧,fashion 一点的说法就是利用AJAX技术上传。其中用到了Jquery和 AjaxFileUpload 。

先建个表 CREATE TABLE files (   id int NOT NULL AUTO_INCREMENT PRIMARY KEY,   filename varchar(255) NOT NULL,   title varchar(100) NOT NULL ); 文件的目录结构如下:

第一步,建立表单

看上去就一个title文本字段,一个文件框,一个提交按钮,还有一个files的div。 控制器部分 首先,我们要建一个上传的表单和一个upload的Controller。在index方法里渲出upload的视图。如下: class Upload extends CI_Controller {    public function __construct()    {       parent::__construct();       $this->load->model(‘files_model’);       $this->load->database();       $this->load->helper(‘url’);    }      public function index()    {       $this->load->view(‘upload’);    } } 我们已经在构造里加载了files_model,所以可以使用files_model里的方法。

建立表单视图

视图文件upload.php,包含了我们的上传表单。

<!doctype html>

一些简单的css

在css下建立style.css

h1, h2 { font-family: Arial, sans-serif; font-size: 25px; } h2 { font-size: 20px; }   label { font-family: Verdana, sans-serif; font-size: 12px; display: block; } input { padding: 3px 5px; width: 250px; margin: 0 0 10px; } input[type=“file”] { padding-left: 0; } input[type=“submit”] { width: auto; }   #files { font-family: Verdana, sans-serif; font-size: 11px; } #files strong { font-size: 13px; } #files a { float: right; margin: 0 0 5px 10px; } #files ul { list-style: none; padding-left: 0; } #files li { width: 280px; font-size: 12px; padding: 5px 0; border-bottom: 1px solid #CCC; }

第二步,Javascript

在js下建立site.js

$(function() {    $('#upload_file').submit(function(e) {       e.preventDefault();       $.ajaxFileUpload({          url         :'./upload/upload_file/',          secureuri      :false,          fileElementId  :‘userfile’,          dataType    : ‘json’,          data        : {             ‘title’           : $('#title').val()          },          success  : function (data, status)          {             if(data.status != ‘error’)             {                $('#files').html('Reloading files…');                refresh_files();                $('#title').val('');             }             alert(data.msg);          }       });       return false;    }); }); Javascript劫持了表单的提交,并由ajaxfileupload接管。其实是在后台创建了一个iframe并提交了数据。 我只是ajax提交了#title的值,可以通过参数提交更多的字段。 检查返回的json数据,如果没有错误,就刷新文件列表(下文有),清除title字段。不管怎样,都alert出返回的数据。

第三步,上传文件

控制器部分

现在开始上传文件了。我们的URL是这样的 /uplaod/upload_file/,所以,我们在uoload的控制器里建立upload_file方法。

public function upload_file() {    $status = “";    $msg = “";    $file_element_name = ‘userfile’;      if (empty($_POST[‘title’]))    {       $status = “error”;       $msg = “Please enter a title”;    }      if ($status != “error”)    {       $config[‘upload_path’] = ‘./files/';       $config[‘allowed_types’] = ‘gif|jpg|png|doc|txt’;       $config[‘max_size’]  = 1024 * 8;       $config[‘encrypt_name’] = TRUE;         $this->load->library(‘upload’, $config);         if (!$this->upload->do_upload($file_element_name))       {          $status = ‘error’;          $msg = $this->upload->display_errors('’, ‘');       }       else       {          $data = $this->upload->data();          $file_id = $this->files_model->insert_file($data[‘file_name’], $_POST[‘title’]);          if($file_id)          {             $status = “success”;             $msg = “File successfully uploaded”;          }          else          {             unlink($data[‘full_path’]);             $status = “error”;             $msg = “Something went wrong when saving the file, please try again.";          }       }       @unlink($_FILES[$file_element_name]);    }    echo json_encode(array(‘status’ => $status, ‘msg’ => $msg)); } 我们对title字段做了个简单的数据检查,看看他是否为空。不为空就加载codeigniter的upload库。这个类库为我们处理了很多的数据验证。 接着,我们上传文件了。如果成功我们保存title和file_name。然后我们删除了临时文件,最后,json方法返回了状态和信息,来告诉我们结果。

模型部分

按大多数人的MVC模式理念,我们应该在模型里处理数据库交换。 建立files_model.php

class Files_Model extends CI_Model {      public function insert_file($filename, $title)    {       $data = array(          ‘filename’     => $filename,          ‘title’        => $title       );       $this->db->insert(‘files’, $data);       return $this->db->insert_id();    }   } 保存上传文件的文件夹 不要忘记在根目录建立个files文件夹,并给他写入权限。

第四步,文件列表

成功上传后,我们需要更新文件列表,方便修改。

Javascript部分

打开site.js,在后面追加:

function refresh_files() {    $.get(’./upload/files/')    .success(function (data){       $('#files').html(data);    }); } Jquery的简单应用。Ajax取得指定url的内容,填充到#files的div里。

控制器部分

不多说了。

public function files() {    $files = $this->files_model->get_files();    $this->load->view(‘files’, array(‘files’ => $files)); } 调用模型的方法取得数据,再加载到files视图里显示。

模型部分

public function get_files() {    return $this->db->select()          ->from(‘files’)          ->get()          ->result(); }

视图部分

新建files.php视图

                <?php          foreach ($files as $file)          {             ?>                             Delete                                                                          <?php          }          ?>               <?php } else {    ?>    No Files Uploaded    <?php } ?>

删除文件

Javascript部分

$('.delete_file_link').live(‘click’, function(e) {    e.preventDefault();    if (confirm(‘Are you sure you want to delete this file?'))    {       var link = $(this);       $.ajax({          url         : ‘./upload/delete_file/’ + link.data(‘file_id’),          dataType : ‘json’,          success     : function (data)          {             files = $(#files);             if (data.status === “success”)             {                link.parents(‘li’).fadeOut(‘fast’, function() {                   $(this).remove();                   if (files.find(‘li’).length == 0)                   {                      files.html('No Files Uploaded');                   }                });             }             else             {                alert(data.msg);             }          }       });    } });

控制器部分

public function delete_file($file_id) {    if ($this->files_model->delete_file($file_id))    {       $status = ‘success’;       $msg = ‘File successfully deleted’;    }    else    {       $status = ‘error’;       $msg = ‘Something went wrong when deleteing the file, please try again’;    }    echo json_encode(array(‘status’ => $status, ‘msg’ => $msg)); }

模型部分

public function delete_file($file_id) {    $file = $this->get_file($file_id);    if (!$this->db->where(‘id’, $file_id)->delete(‘files’))    {       return FALSE;    }    unlink(’./files/' . $file->filename);    return TRUE; }   public function get_file($file_id) {    return $this->db->select()          ->from(‘files’)          ->where(‘id’, $file_id)          ->get()          ->row(); }

嗯,简单的应用。没有涉及的权限、上传的进度条等。


最后修改于 2011-09-15