[大阪/横滨/德岛] 寻找基础设施/服务器端工程师!

[大阪/横滨/德岛] 寻找基础设施/服务器端工程师!

【超过500家企业部署】AWS搭建、运维、监控服务

【超过500家企业部署】AWS搭建、运维、监控服务

【CentOS的后继者】AlmaLinux OS服务器搭建/迁移服务

【CentOS的后继者】AlmaLinux OS服务器搭建/迁移服务

[仅适用于 WordPress] 云服务器“Web Speed”

[仅适用于 WordPress] 云服务器“Web Speed”

[便宜]网站安全自动诊断“快速扫描仪”

[便宜]网站安全自动诊断“快速扫描仪”

[预约系统开发] EDISONE定制开发服务

[预约系统开发] EDISONE定制开发服务

[注册100个URL 0日元] 网站监控服务“Appmill”

[注册100个URL 0日元] 网站监控服务“Appmill”

【兼容200多个国家】全球eSIM“超越SIM”

【兼容200多个国家】全球eSIM“超越SIM”

[如果您在中国旅行、出差或驻扎]中国SIM服务“Choco SIM”

[如果您在中国旅行、出差或驻扎]中国SIM服务“Choco SIM”

【全球专属服务】Beyond北美及中国MSP

【全球专属服务】Beyond北美及中国MSP

[YouTube]超越官方频道“美由丸频道”

[YouTube]超越官方频道“美由丸频道”

关于如何使用fuelphp文件上传的备注

你好。
我是Mandai,负责Wild 开发团队。

使用 Fuelphp 简单地上传文件非常简单,如果您从文档中复制并粘贴代码,那么它基本上就可以工作。
不过有很多东西不知道怎么做,所以总结了一下。


 

准备文件上传(HTML + CSS + JS)

在实现文件上传之前,需要准备好HTML等前端材料。

让我们从 HTML 开始。
它是表单标签内的输入标签。

<form id="form" name="form" method="post" enctype="multipart/form-data"><input type="file" name="f" class="hidden" id="f" multiple="multiple"><label for="f"><span class="btn">文件选择</span><span class="selected" id="f_selected">未选择</span></label></form>

 
接下来,CSS。

input.hidden { /* 显示:无;*/ } 标签 > span.btn { 显示:内联块;边框:1px 实心 #999; 字体:13.333px 行高:21px;左:0.25em;右内边距:0.25em;背景:-webkit-线性渐变(#fcfcfc,#dcdcdc);背景:线性渐变(#fcfcfc,#dcdcdc); span.btn:active { 背景:-webkit-线性渐变(#dcdcdc, #fcfcfc); 背景:线性渐变(#dcdcdc, #fcfcfc); } 标签 > span.btn:hover { 边框: 1px 实心 #666 ; } 标签 > span.selected { 显示:内联块; 字体:13.333px; 行高:21px; } 标签 { -moz-user-select:无; ; -webkit-用户选择:无;

 
最后但并非最不重要的是 JavaScript。

(function(){ var f = document.getElementById('f'); var label_selected = document.getElementById(f.id + '_selected'); f.addEventListener('change', function(){ if (f.files .length == 0){ label_selected.textContent = '未选择'; } else if (f.files.length == 1){ label_selected.textContent = f.files[0].name } else { label_selected .textContent = f.files.length + '文件' } });


 当您在浏览器中显示它时,它看起来如下所示。推荐使用Chrome。
当你看到它的时候,原因就很明显了。

重复文件上传

有两个文件上传按钮。
按任一按钮都会起作用。

左边的是实际产品,右边的是使用标签标签的复制品。
我只是想这么做。

表单部分在浏览器之间的显示不同,而且我还想让文件上传按钮本身符合设计,所以这个技巧很有用。
使用 CSS + JS 大致匹配行为和外观,这次我使它类似于 chrome 表单组件。

如果您将“display: none”添加到 CSS 中的输入标记中,它的行为与普通表单没有什么不同。
(已注释掉)

重要的是不要忘记表单标记中的 enctype 属性。

至此,前期准备工作已经完成。

 

Fuelphp的实现(准备)

在实施之前,我们将进行各种设置并准备模型。

由于 Fuelphp 是配置优先的,因此可以通过配置文件极大地改变其行为。
首先,在上传时,准备一个用于上传的配置文件。

源配置文件位于“fuel/core/config/upload.php”中,因此将其复制到“fuel/app/config”下并更改设置。

需要设置的项目是path。
至于保存目的地,如果将其设置为公共,下载机制会更容易,但如果您知道带有个人信息的PDF的URL,则可以随意下载,因此最好设置它低于公众。

如果需要控制访问,请创建并指定一个目录,例如公共层次结构中的文件。
在这种情况下,将无法从外部访问它,并且您将无法下载它,因此您会担心开销,但您可以通过创建单独的控制器来创建下载 URL 来处理此问题。
这部分和文件上传有点不同,所以我想下次再写。

这次,创建一个与public同级的files目录(直接在项目根目录下)并保存文件。

另外,对于要保存的文件名,我在配置文件中将 randomize 设置为 true 并使用 32 个字符的 MD5 哈希值。

修改后的 config/upload.php 现在如下所示。

return array( 'path' => '/var/www/html/test/files', 'randomize' => true, );


 接下来,创建模型。
由于要保存的文件名加上了哈希值,原来的文件名已经不知道了,所以它的主要作用就是保存。

创建上传表进行存储的SQL语句如下。

创建表 `uploads` (`id` int(11) unsigned NOT NULL AUTO_INCRMENT、`origin_name` varchar(256) NOT NULL、`file_name` varchar(256) NOT NULL、`created_at` 时间戳不为 NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `updated_at` 时间戳 NOT NULL DEFAULT '0000-00-00 00:00:00', PRIMARY KEY (`id`), KEY `idx_file_name` (`file_name`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 
执行此 SQL 后,最快的方法是使用 oil 命令创建模型,如下所示。

php /path/to/oil r fromdb:模型上传


 另外,由于我们将使用 ORM 包,因此我们需要修改 config.php 中的always_load 项。
如果取消注释包部分,它将自动加载。

 

Fuelphp(控制器)的实现

我们将在发布数据时实现控制器的行为。

现在控制器中编写的源代码如下。

function post_index() { $data = []; $this->template->title = 'test'; /* * 随机化处理后的文件名如下 * [0-9a-f] { 32}.[ext] * 由于原始文件名将保存在单独的字段中,因此我们将介绍一个在保存之前将文件名更改为仅哈希值的过程 */ Upload::register('before', function( &$ file) { $file['filename'] = substr($file['filename'], 0, 32); $file['path'] .= $file['filename'][0]. '. $file['文件名'][1]. }); if (Upload::is_valid()) { 上传::save(); foreach (Upload::get_files() as $file) { Model_Upload: :add($file); } } foreach (Upload::get_errors() as $file) { // 错误处理 } $this->template->content = View::forge('upload/index', $数据) ; }


 如果在config中的upload.php中将“auto_process”设置为true(默认),则不需要显式编写Upload::process()。
文档,如果在 'auto_process' => true 时执行 Upload::process(),Upload::process() 将执行两次。

您可以使用 Upload::process() 覆盖配置,因此如果在多个位置描述文件上传过程,则最好将 auto_process 设置为 false 并每次执行 Upload::process() 。

Upload::register() 方法用于在保存文件之前中断处理。
第一个参数应该是“验证”、“之前”和“之后”之一。
这次我选择之前,因为我想在保存之前更改文件名和保存路径。

如果 config/upload.php 中的 randomize 设置为 true,则文件名将是 32 个字符的哈希值,但具有原始扩展名。
为了完全统一文件名为32个字符,我们添加了一个将文件名更改为哈希值的过程。

另外,关于保存目的地,使用哈希值的第一个和第二个字符创建目录并重置为路径。
如果上传的文件数量较少,这并不是特别必要,但如果上传的文件数量较多,或者存储了数万个文件,则读写响应会明显下降。
作为对此的回应,我们添加了处理以分配一个目录中的文件数量。

$file,它是Upload::register()中闭包中的一个参数,传递的是fuel/vendor/fuelphp/upload/src/File.php中编写的类,并且这个类似乎可以从外部访问。没办法做到这一点。
如果您在“之前”(保存之前)编辑此类,则可以操作保存路径和文件。

如果你转储 $file,它将包含如下内容:

Fuel\Upload\File::__set_state(array( 'container' => array ( 'element' => 'f', 'filename' => 'e9477391cbeefc40e69f7e1bc24868d2', 'name' => 'test.html', 'type' => 'text/html', 'tmp_name' => '/tmp/phpDsDmiL', '错误' => 0, '大小' => 335, '扩展名' => 'html', '基本名称' => '测试', 'mimetype' => 'text/html', 'path' => '/home/vagrant/workspace/test/files/e/9/', ), 'index' => 0, 'errors' => array ( ), 'config' => array ( 'langCallback' => '\\Upload::lang_callback', 'moveCallback' => NULL, 'max_size' => 0, 'max_length' => 0, 'ext_whitelist' = > array ( ), 'ext_blacklist' => 数组 ( ), 'type_whitelist' => 数组 ( ), 'type_blacklist' => 数组 ( ), 'mime_whitelist' => 数组 ( ), 'mime_blacklist' => 数组 ( ), “前缀”=>“”、“后缀”=>“”、“扩展名”=>“”、“随机化”=> true、“标准化”=> false、“normalize_separator”=>“_”、“change_case” =>假,“路径”=>“/var/www/html/test/files”,“create_path”=>真,“path_chmod”=>511,“file_chmod”=>438,“auto_rename”=>真, 'new_name' => false, 'overwrite' => false, ), 'isValidated' => true, 'isValid' => true, 'callbacks' => array ( 'before_validation' => array ( ), 'after_validation' = > array ( ), 'before_save' => array ( 0 => Closure::__set_state(array( )), ), 'after_save' => array ( ), ), ))


 有点混乱,但是用Upload::get_files()获取的文件信息只是Fuel\Upload\File的容器部分,而不是上面的类。
另外,即使你改变了Upload::get_files()中的信息,实际的文件信息也无法改变,所以看来改变上传文件信息的唯一方法就是在before事件中。

该区域文档的注册方法部分中有详细介绍

 
就是这样。

如果您觉得这篇文章有帮助,请点赞!
0
加载中...
0 票,平均:0.00 / 10
5,109
X Facebook 哈特纳书签 口袋
[2025.6.30 Amazon Linux 2 支持结束] Amazon Linux 服务器迁移解决方案

[2025.6.30 Amazon Linux 2 支持结束] Amazon Linux 服务器迁移解决方案

写这篇文章的人

关于作者

万代洋一

我的主要工作是为社交游戏开发 Web API,但我也很幸运能够做很多其他工作,包括营销。
此外,我在 Beyond 中的肖像权被视为 CC0。