欢迎各位兄弟 发布技术文章
这里的技术是共享的
Drupal 7的文件API分为unmanaged file和managed file两种类型,managed file会在数据库中记录文件的信息及引用记录。
Drupal文件对象有一个uri属性,它的形式如public://myfile.jpg,通过file_create_url($file->uri)可以把uri转换成web可访问的路径,如http://howto.eguidedog.net/sites/default/files/myfile.jpg
Drupal内建了public、private和temporary流报装器(stream wrapper),PHP文件操作函数可以直接操作这些uri,例如我们可以通过filesize(‘public://myfile.jpg')获取文件大小,而不需要先转换成本地文件的地址。
Drupal中的private目录应该是放在一个不能直接从Web访问的目录,其内容通过PHP返回(这里有一个副作用是增加了系统开销)。
在表单生成函数中添加文件控件:
$form[‘unmanaged_file’] = array( ‘#type’ => ‘file’, ‘#title’ => ‘文件’, );
在表单validate函数中把POST的文件数据保存到临时文件:
// 限制文件后缀 $validators = array( ‘file_validate_extensions’ => array(‘jpg jpeg png gif’), ); $file = file_save_upload(‘unmanaged_file’, $validators, FALSE, FILE_EXISTS_REPLACE);
if (isset($file) { // 有文件被上传 if ($file) { $form_state[‘values’][‘unmanaged_file’] = $file; } else { form_set_error(‘unmanaged_file’, ‘文件上传失败’); } }
在表单submit函数里把文件从临时文件夹(temporary)复制到public文件夹:
if ($file = $form_state[‘values’][‘unmanaged_file’]) { $dir = ‘public://assets/unmanaged'; // file_prepare_directory会检查目录是否存在,如果不存在则创建,也会检查文件权限是否正确。 file_prepare_directory($dir, FILE_CREATE_DIRECTORY); $filename = file_unmanaged_copy($file->uri, $dir, FILE_EXISTS_RENAME); }
function mymodule_file_download($uri) { // mymodule需要改成具体的模块名称
$path = file_uri_target($uri);
if (strpos($path, 'mydir') === 0 { // mydir是需要处理的目录的前缀,我们不需要处理其它模块的文件
if (user_access('view mymodule private file') { // 这里需要改成具体的权限
$file = new stdClass();
$file->filename = basename($uri);
$file->uri = $uri;
$file->filemime = file_get_mimetype($uri);
$file->filesize = filesize($uri);
return file_get_content_headers($file);
}
return -1;
}
}
$form[‘manage_file’] = array( ‘#type’ => ‘managed_file’, ‘#title’ => ‘managed file example’, ‘#upload_validators’ => array( ‘file_validate_extensions’ => array(‘jpg jpeg png gif’), // 限制后缀名 ), ‘#upload_location’ => ‘public://assets/managed', // 指定上传的位置 ‘#progress_indicator’ => ‘bar’, // 指定上传进度条效果 );
在hook_submit函数里保存文件:
if ($form_state[‘values’][‘managed_file’]) {
$file = file_load($form_state[‘values’][‘managed_file’]; $file->status = FILE_STATUS_PERMANENT; file_save($file);
//下面这一行话很重要,对于原理 很重要
// 添加文件引用,如果不添加引用,该文件6小时候内会被cron run删除掉
file_usage_add($file, ‘my_module’, ‘my_module_config_file’, 1);
}
查找文件的方法如下,通常在是在文件表单控件的#default_value值赋值时需要使用:
// file_usage表中对type, id做了索引,但module,type,id没有做索引,所以我们通过type,id来查询文件的fid
$result = db_query(‘SELECT fid FROM file_usage WHERE type = :type AND id = :id’, array(‘:type’ => ‘my_module_config_file’, ‘:id’ => 1)->fetch(); if ($result) { $file = file_load($result->fid); }
下面是删除文件的办法:
// 先判断文件是否被替换,如果被替换则删除旧文件
if ($form_state['values']['file'] != $form['file']['#default_value'] && $form['file']['#default_value']) { $file = file_load($form['file']['#default_value']); file_usage_delete($file, 'overall_performance', 'overall_performance_config'); file_delete($file); }
获取library的路径(例如sites/all/libraries/mylibrary)
把相对路径转换成绝对路径
$files_dir = variable_get('file_public_path', conf_path() . '/files')
file_directory_temp()
构造文件头,如果想改文件名可修改返回的数组。 http://api.drupal.org/api/drupal/includes%21file.inc/function/file_get_content_headers/7
把文件传回客户端,此函数不再返回,整个PHP程序会终止。 http://api.drupal.org/api/drupal/includes%21file.inc/function/file_transfer/7 $headers = array(...); $path_to_file = "/bla/bla/blabla"; file_transfer($path_to_file, $headers);
引用模块 module_load_include('inc', 'transliteration');
https://api.drupal.org/api/drupal/includes%21file.inc/function/file_usage_list/7 获取文件引用情况
增加文件引用计数
原文链接:http://cto.eguidedog.net/node/118
来自 http://drupalchina.cn/node/5656