欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

Drupal 模块开发实例之二:自定义文件上传

shiping1 的头像

Drupal 模块开发实例之二:自定义文件上传


本篇教程主要讲解如何通过 Drupal 表单系统上传文件,涉及到的主要接口在 includes/form.inc 和 includes/file.inc 文件中,核心函数即file_save_upload,该函数实现文件的移动、验证、保存、入库。

系统自带 files 表,用做存储文件相关信息,所以,这个简单的实例,就不需要另外创建数据表。如果复杂的应用,比如让文件和节点关联等等,就需要创建数据表了。

模块名称:myfile。
实现功能:定义一个页面,生成一个表单,让用户可以上传文件。
权限设置:暂不设置

第一步:模块信息,创建 myfile.info 文件
 

1// $Id$
2name = "myfile"
3description = 文件上传
4core = "6.x"


第二步:模块主文件,创建 myfile.module 文件

定义一个页面,使用 hook_menu。注意,没有验证权限,所有人均可访问该页面。

01/**
02 * @Implement of hook_menu()
03 */
04function myfile_menu() {
05  $item = array();
06   
07  $item['myfile'] = array(
08    'description' => '上传文件',
09    'page callback' => 'drupal_get_form',
10    'page arguments' => array('myfile_page_form'),
11    'access callback' => true,
12    'file' => 'myfile.page.inc',
13    'type' => MENU_CALLBACK,
14  );
15   
16  return $item;
17}


第三步:定义表单,创建 myfile.page.inc 文件

回顾一下,为什么需要创建一个 myfile.page.inc 文件?这么做的好处是什么?在上一篇教程中。

表单只需要一个字段,即文件上传字段,在 form.inc 里,类型为 file。

问题:myfile_menu 的定义,并没有传递参数,为什么这儿有一个参数(&$form_state)呢?答案在上一篇教程中。

01/**
02 * @param (array) &$form_state
03 *  表单基本数据
04 */
05function myfile_page_form(&$form_state) {
06   
07  // 上传文件,必须设置 enctype
08  $form['#attributes']['enctype'] = 'multipart/form-data';
09   
10  $form['file'] = array(
11    '#title' => '文件',
12    '#type' => 'file', // 文件类型
13    '#description' => '可上传任意格式的文件,大小不超过 2 M',
14  );
15   
16  $form['submit'] = array(
17    '#type' => 'submit',
18    '#value' => '确认上传',
19  );
20  return $form;
21}


第四步:处理表单提交,在 myfile.page.inc 文件中创建函数 myfile_page_form_submit

这个函数用来处理上传表单 (myfile_page_form) 的提交,我们把文件上传处理放在提交中来完成。

问题:myfile_page_form 中定义的表单,并没有设置提交处理函数,为什么要创建这个函数呢?难道会自动调用吗?

文件验证处理,请看代码中详细注释:

01/**
02 * 表单提交,在提交中处理上传文件
03 * @param (array) &$form
04 * @param (array) &$form_state
05 */
06function myfile_page_form_submit(&$form, &$form_state) {
07  /**
08   * 设置验证函数,索引为函数名称,值则为传递给函数的参数
09   * 系统默认有一些常用验证函数,你也可以自定义
10   */
11  $validators = array();
12   
13  /**
14   * 验证文件大小,以及分配给用户的总空间大小,以 bytes 为单位
15   * 等同于调用函数:file_validate_size()
16   *
17   * 用户总空间以及允许上传的最大文件,在管理 - 文件系统中可以设置
18   * 此处直接调用该全局配置,你也可以自定义,如:
19   *  $validators['file_validate_size'] = array(2048000, 10000000);
20   */
21   
22  // 允许上传的最大文件
23  $file_limit = variable_get('upload_uploadsize_default', 1);
24  // 用户总空间大小
25  $user_limit = variable_get('upload_usersize_default', 1);
26   
27  // 文件大小相关验证
28  $validators['file_validate_size'] = array($file_limit, $user_limit);
29   
30  /**
31   * 验证文件类型,以半角空格分隔多个后缀
32   * 可以通过 variable_get('upload_extensions_default') 获取全局设置
33   */
34  $validators['file_validate_extensions'] = array('zip txt doc rar');
35   
36  // 如果是图片可以限制最大尺寸
37  // $validators['file_validate_image_resolution'] = array('100x100');
38   
39  /**
40   * 接下来,自定义一个验证函数
41   */
42  $validators['myfile_ext_validate'] = array('test');
43   
44  /**
45   * 创建文件保存位置,该位置系统必须可读写,若不定义,则会使用默认文件目录
46   * file_directory_path() 用来获取默认文件存储目录,一般我们都将文件保存在该目录之下
47   */
48   
49  $dir = file_directory_path().'/test';
50   
51  /**
52   * 检查路径是否存在,若不存在,则尝试创建
53   * 注意:该函数不能递归创建,比如 /a/b/c,三层目录都不存在,无法同时创建
54   * drupal 7将支持递归创建,实际上也是 php5 mkdir 提供的支持
55   */
56  file_check_directory($dir, FILE_CREATE_DIRECTORY);
57   
58  /**
59   * 保存文件,调用 file_save_upload(),将会自动写入 files 表
60   *
61   * @param1:即为表单字段名称,必须对应上面表单中的定义
62   * @param2:验证相关设置
63   * @param3:文件保存路径
64   *
65   * @return:如果上传成功,将返回一个文件对象,包含 files 中所有字段
66   */
67  if ($file = file_save_upload('file', $validators, $dir)) {
68     
69    // 上传成功了,把文件状态改为正常,默认为 0,可能会被清除
70    file_set_status($file, 1);
71     
72    //在这儿,我们可以做一些扩展,比如让文件和节点关联起来,等等。
73     
74    drupal_set_message($file->fid .'-'. $file->filepath);
75     
76  } else {
77    // 一般来说,上传失败,系统会显示失败的原因
78     
79    drupal_set_message('上传失败了');
80  }
81}


根据提交处理函数,我们还需要创建一个自定义的验证函数 myfile_ext_validate:

01/**
02 * 自定义文件上传验证函数
03 * @param (object) &$file
04 *  待保存的文件对象
05 * @param (string) $text
06 *  自定义参数
07 * @param (array) 错误信息
08 */
09function myfile_ext_validate(&$file, $text) {
10  // 若返回错误信息,则该信息将显示给用户,并且文件不会被保存,
11  $error = array();
12   
13  // 这儿只是做一个测试,表明这个函数被调用了。
14  drupal_set_message($text);
15   
16  return $error;
17}


好,到这儿,一个简单的文件上传模块就完成了。试一试,是不是可以成功上传文件呢?如果加上权限验证,这个模块就可以应用于正式站点了。 而下一篇实例,即为 hook_menu 的权限设置。

本教程源代码下载,可直接解压到模块目录,启用后,访问 http://www.mysite.com/?q=myfile 即可上传文件。

来自 http://hi.baidu.com/kongqi/item/e64b5fe20782d1f72a09a4c8

普通分类: