原文: http://cakebaker.42dh.com/2006/04/15/file-upload-with-cakephp/
文章中代码经过测试: 需要代码请联系
这篇文章我将讲述如何上传以及在数据库中存储文件,是的,我说的是在数据库中存储文件.由于数据库性能的
原因不推荐在数据库中保存文件.当然这是在设计应用程序是考虑的重点.
为什么要把文件存储在数据库中有下面几个原因:
1. 所有文件存储在一个地方: 数据库
2. 易于测试
3. 易于开发,因为我不必维护数据库和文件系统的同步问题
收先定义MYSQL数据库表的结构
非常容易,是吗? 现在我将在数据库中存储文件.为了检索文件,我需要一个download()方法,把它添加到控制器中:
显示文件列表控制器方法:
/*
*
* 文件下载
*
* @param integer $id 文件id
*
* Usage: uploads/download/1
*/
function download( $id ) {
// 通过文件Id查询文件的数据
$file = $this -> Upload -> findById( $id );
header ( ' Content-type: ' . $file [ ' Upload ' ][ ' type ' ]); // MIME类型
header ( ' Content-length: ' . $file [ ' Upload ' ][ ' size ' ]); // 文件长度(字节)
header ( ' Content-Disposition: attachment; filename= ' . $file [ ' Upload ' ][ ' name ' ]); // 提示用户保存文件
echo $file [ ' Upload ' ][ ' data ' ];
exit ();
}
* 文件下载
*
* @param integer $id 文件id
*
* Usage: uploads/download/1
*/
function download( $id ) {
// 通过文件Id查询文件的数据
$file = $this -> Upload -> findById( $id );
header ( ' Content-type: ' . $file [ ' Upload ' ][ ' type ' ]); // MIME类型
header ( ' Content-length: ' . $file [ ' Upload ' ][ ' size ' ]); // 文件长度(字节)
header ( ' Content-Disposition: attachment; filename= ' . $file [ ' Upload ' ][ ' name ' ]); // 提示用户保存文件
echo $file [ ' Upload ' ][ ' data ' ];
exit ();
}
// app/views/uploads/filelist.ctp
< table >
<? php
echo $html->tableHeaders(array_keys($filelist[0]['Upload']));
foreach ($filelist as $file){
echo $html->tableCells($file['Upload'], array('bgcolor' => 'green','style'=>'color:white;'));
}
?>
</ table >
< table >
<? php
echo $html->tableHeaders(array_keys($filelist[0]['Upload']));
foreach ($filelist as $file){
echo $html->tableCells($file['Upload'], array('bgcolor' => 'green','style'=>'color:white;'));
}
?>
</ table >
/*
*
* 显示文件列表
*
* Usage: uplodas/filelist
*/
function filelist() {
$this -> set( ' filelist ' , $this -> Upload -> findAll( null , array (
' id ' ,
' name ' ,
' type ' ,
' size ' ,
' created ' ,
' updated ' , ' modified '
) , ' id DESC ' ));
}
* 显示文件列表
*
* Usage: uplodas/filelist
*/
function filelist() {
$this -> set( ' filelist ' , $this -> Upload -> findAll( null , array (
' id ' ,
' name ' ,
' type ' ,
' size ' ,
' created ' ,
' updated ' , ' modified '
) , ' id DESC ' ));
}
CREATE
TABLE
uploads (
id INT ( 11 ) NOT NULL AUTO_INCREMENT,
name VARCHAR ( 75 ) NOT NULL ,
type VARCHAR ( 255 ) NOT NULL ,
size INT ( 11 ) NOT NULL ,
data MEDIUMBLOB NOT NULL ,
created DATETIME ,
updated DATETIME ,
modified DATETIME ,
PRIMARY KEY (id)
);
id INT ( 11 ) NOT NULL AUTO_INCREMENT,
name VARCHAR ( 75 ) NOT NULL ,
type VARCHAR ( 255 ) NOT NULL ,
size INT ( 11 ) NOT NULL ,
data MEDIUMBLOB NOT NULL ,
created DATETIME ,
updated DATETIME ,
modified DATETIME ,
PRIMARY KEY (id)
);
注意: 除非你明确的知道上传的文件不会超过64K大小,否则应该使用MEDIUMBLOG或则LONGBLOB数据库类型.
模型是很直观的:
//
app/models/uploads.php
class Upload extends AppModel
{
public $name = ' Upload ' ;
}
class Upload extends AppModel
{
public $name = ' Upload ' ;
}
目前我省略了控制器的创建而直接创建视图
// app/views/uploads/add.ctp
< form action ="/uploads/add" enctype ="multipart/form-data" method ="post" >
<? php echo $form->file('uploads/File'); ?>
<? php echo $html->submit('Upload')); ?>
</ form >
< form action ="/uploads/add" enctype ="multipart/form-data" method ="post" >
<? php echo $form->file('uploads/File'); ?>
<? php echo $html->submit('Upload')); ?>
</ form >
现在我准备创建控制器并实现add方法
//
app/controllers/files_controller.php
class UploadsController extends AppController{
/* *
* 上传文件
*
* Usage: uploads/add
*/
function add() {
if ( ! empty ( $this -> data[ ' uploads ' ][ ' File ' ]) && is_uploaded_file ( $this -> data[ ' uploads ' ][ ' File ' ][ ' tmp_name ' ])) {
// 把文件存入变量
$this -> data[ ' uploads ' ][ ' File ' ][ ' data ' ] = fread ( fopen ( $this -> data[ ' uploads ' ][ ' File ' ][ ' tmp_name ' ] , " r " ) , $this -> data[ ' uploads ' ][ ' File ' ][ ' size ' ]);
// 同步数据库
$this -> Upload -> save( $this -> data[ ' uploads ' ][ ' File ' ]);
}
// debug
var_dump ( $this -> data[ ' uploads ' ][ ' File ' ]);
}
}
class UploadsController extends AppController{
/* *
* 上传文件
*
* Usage: uploads/add
*/
function add() {
if ( ! empty ( $this -> data[ ' uploads ' ][ ' File ' ]) && is_uploaded_file ( $this -> data[ ' uploads ' ][ ' File ' ][ ' tmp_name ' ])) {
// 把文件存入变量
$this -> data[ ' uploads ' ][ ' File ' ][ ' data ' ] = fread ( fopen ( $this -> data[ ' uploads ' ][ ' File ' ][ ' tmp_name ' ] , " r " ) , $this -> data[ ' uploads ' ][ ' File ' ][ ' size ' ]);
// 同步数据库
$this -> Upload -> save( $this -> data[ ' uploads ' ][ ' File ' ]);
}
// debug
var_dump ( $this -> data[ ' uploads ' ][ ' File ' ]);
}
}