You are here

上传文件

g089h515r806 的头像
Submitted by g089h515r806 on 星期四, 2009-08-20 15:41

 

尽管上传模块提供了一个完整的实现,用来为节点上传文件;但是有时候,你不想把上传的文件与节点关联起来。下面的函数可帮你实现这一点。
 
file_save_upload($source, $validators = array(), $dest = FALSE,
$replace = FILE_EXISTS_RENAME)
    $source参数用来告诉函数哪个已上传的文件将被保存。$source对应于web表单中的文件输入字段的名字。例如,如果在“管理➤用户管理➤用户设置”中启用了头像图片支持,那么在“我的帐户”页面的表单上,就会有一个文件字段用来允许你上传自己的图片,该字段的名字就是picture_upload。显示在浏览器中的表单,如图13-4所示。当用户点击保存按钮时,将会得到$_FILES全局变量,如图13-5所示。注意,$_FILES中的信息是以表单的文件字段的名字为键的(这样,就可以在单个表单中支持多个文件字段了)。全局变量$_FILES是由PHP本身定义的,而不是由Drupal。
 
13-4.表单元素的文件字段,它显示在“我的帐户”页面
13-5.HTTP POST之后,得到的$_FILES全局变量
 
    $validators参数是一个数组,里面包含了成功文件上传后所要调用的函数的名字。例如,user_validate_picture()函数,当用户编辑了他/她的“我的帐户”页面以后将调用这个表单验证函数,这个函数在调用file_save_upload()以前添加了3个验证器。如果需要向验证器函数中传递参数,那么可将参数定义在后面的数组中。例如,在下面的代码中,当验证器运行时,对file_validate_image_resolution()的调用应该像file_validate_image_resolution('85x85')一样:
 
/**
 * Validates uploaded picture on user account page.
 */
function user_validate_picture(&$form, &$form_state) {
    $validators = array(
        'file_validate_is_image' => array(),
        'file_validate_image_resolution' =>
            array(variable_get('user_picture_dimensions', '85x85')),
        'file_validate_size' => array(variable_get('user_picture_file_size', '30')
            * 1024),
    );
    if ($file = file_save_upload('picture_upload', $validators)) {
        ...
    }
    ...
}
 
    file_save_upload()函数中的$dest参数是可选的,它包含的是文件将被复制到的目录。例如,在处理把文件附加在一个节点上时,上传模块使用file_directory_path()(默认为sites/default/files)作为$dest的值(参看图13-6)。如果没有提供$dest,那么将使用临时目录。
    $replace参数用来定义,在一个同名文件已存在时,Drupal应该做什么。可能值如表13-3所示。
 
13-6.文件对象已存在,当它传递给file_save_upload()的验证器时的情景
 
    file_save_upload()的返回值是一个包含了完整属性的文件对象(如图13-7所示);如果有地方出错的话,那么将返回0。
 
13-7.成功调用file_save_upload()以后,返回的文件对象
 
    在调用了file_save_upload()以后,在Drupal的临时目录中新增了一个文件,同时向files表中写入了一条新纪录。该纪录包含的值与如图13-7所示的文件对象相同。
 
    注意状态字段被设置为了0。这意味着到目前为止,在Drupal看来,这个仍然是一个临时文件。调用者需要负责将该文件改为持久的。继续使用我们的上传一个用户头像这个例子,我们看到用户模块负责将这个文件复制到了Drupal的user_picture_path变量所定义的目录中,并使用用户的ID对其重命名:
 
// The image was saved using file_save_upload() and was added to the
// files table as a temporary file. We'll make a copy and let the garbage
// collector delete the original upload.
$info = image_get_info($file->filepath);
$destination = variable_get('user_picture_path', 'pictures') .
'/picture-'. $form['#uid'] .'.'. $info['extension'];
file_copy($file, $destination, FILE_EXISTS_REPLACE));
...
 
    这将已上传的图片移到了sites/default/files/pictures/picture-2.jpg。
    在前面的代码注释中所提到的垃圾收集器,用来清理临时目录中的过期的临时文件。对于每个临时文件,在files表中都为其保存了一条状态字段为0的纪录,所以Drupal知道需要清理哪些文件。垃圾收集器位于modules/system/system.module的system_cron()函数中。它将删除那些过期文件,这里的过期指的是超过了常量DRUPAL_MAXIMUM_TEMP_FILE_AGE所指定的秒数。该常量的值为1440秒,也就是24分钟。

    如果提供了$dest参数,并且文件被移动到了它的最终位置,来代替原来的临时目录,那么调用者可以通过调用file_set_status(&$file, $status)将files表中纪录的状态修改为持久的,这里面$file被设置为一个完整的文件对象(如图13-7所示),$status被设置为FILE_STATUS_PERMANENT。依照includes/file.inc,如果你想在你的模块中使用额外的状态常量的话,那么你必须从256开始,因为0, 1, 2, 4, 8, 16, 32, 64, 和128是为核心保留的。

 

老葛的Drupal培训班 Think in Drupal

Drupal版本: