1. Drupal 7的文件目录分类
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返回(这里有一个副作用是增加了系统开销)。
2. 怎样使用ummanaged file
在表单生成函数中添加文件控件:
$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); }
3. 怎样下载private file
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;
}
}
4. 怎样使用managed file
$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_useage_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); }
5. File API
http://api.drupal.org/api/drupal/includes--file.inc/group/file/7
5.1 drupal_realpath($uri) 把public://路径转换成服务器文件系统的绝对路径(/srv/www/…)
5.2 file_create_url($uri)
创建一个网络可访问的链接,即http开头的地址 5.3 file_create_filename($filename)
创建文件名,如果系统已有重名文件,可以自动加后缀。 5.4 file_destination($destination, FILE_EXISTS_RENAME)
获取文件名,如果系统已有重名文件,可以自动加后缀。
5.5 $base_url Drupal根目录,通过global $base_url获取。
5.6 $base_path 不含域名
5.7 drupal_get_path http://api.drupal.org/api/drupal/includes%21common.inc/function/drupal_get_path/7 drupal_get_path('module', 'name_of_module');
5.8 libraries_get_path($library_name)
获取library的路径(例如sites/all/libraries/mylibrary)
5.9 url
把相对路径转换成绝对路径
5.10 获取public path
$files_dir = variable_get('file_public_path', conf_path() . '/files')
5.11 获取temporary path
file_directory_temp()
5.12 file_get_content_headers
构造文件头,如果想改文件名可修改返回的数组。 http://api.drupal.org/api/drupal/includes%21file.inc/function/file_get_content_headers/7
5.13 file_transfer
把文件传回客户端,此函数不再返回,整个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);
5.14 module_load_include($type, $module, $name)
引用模块 module_load_include('inc', 'transliteration');
5.15 file_usage_list
https://api.drupal.org/api/drupal/includes%21file.inc/function/file_usage_list/7 获取文件引用情况
5.16 file_usage_add
增加文件引用计数