【问题标题】:Codeigniter upload adding underscore to filenameCodeigniter 上传在文件名中添加下划线
【发布时间】:2013-08-21 19:47:28
【问题描述】:

我正在使用 Codeigniter 的内置上传库。这些是我的上传设置:

$config['upload_path'] = upload_path() . 'incoming_faxes/';
$config['allowed_types'] = 'xml|pdf';
$config['file_name'] = uniqid('fax-' . time() . '-', true) . '.xml';
$this->load->library('upload', $config);

确实有效。返回的数据如下,但是file_name 后面有一个下划线:

Array
(
    [file_name] => fax-1377114300-521518bca7c5a7.65243756_.xml
    [file_type] => application/xml
    [file_path] => /var/www/vhosts/example.org/httpdocs/uploads/incoming_faxes/
    [full_path] => /var/www/vhosts/example.org/httpdocs/uploads/incoming_faxes/fax-1377114300-521518bca7c5a7.65243756_.xml
    [raw_name] => fax-1377114300-521518bca7c5a7.65243756_
    [orig_name] => fax-1377114300-521518bca7c5a7.65243756_.xml
    [client_name] => Sample.xml
    [file_ext] => .xml
    [file_size] => 84.69
    [is_image] => 
    [image_width] => 
    [image_height] => 
    [image_type] => 
    [image_size_str] => 
)

如何在文件上传到服务器之前去掉下划线?

【问题讨论】:

标签: php codeigniter file-upload codeigniter-upload


【解决方案1】:
$fn = uniqid('fax-' . time() . '-', true);
$filename = preg_replace('/\./','_', $fn) . '.xml';

应该这样做。

测试:

$parts      = explode('.', $filename);
$ext        = array_pop($parts);
$filename   = array_shift($parts);

foreach ($parts as $part)
{
    if ( 1==1)
    {
        $filename .= '.'.$part.'_';
    }
    else
    {
        $filename .= '.'.$part;
    }
}


$filename .= '.'.$ext;

echo $filename;//fax-1377117024-52152360903ae2_02709878.xml

看起来正在发生的事情是 Upload.php 中的 _prep_filename() 方法检查 allowed_typesmimes_types 与分解的文件名。文件名中的句点将扩展名之前的最后一个数字(示例文件名中的 65243756)拆分为 parts 数组。然后它根据allowed_typesmimes_types 检查这个值。在allowed_typesmimes_types 中都找不到数字,它会附加下划线。

这是一个奇怪的问题。更多信息请看这里:https://github.com/EllisLab/CodeIgniter/issues/1380

分解:

// system/core/libraries/Upload.php
// line 984
protected function _prep_filename($filename)
{
    if (strpos($filename, '.') === FALSE OR $this->allowed_types == '*')
    {
        return $filename;
    }

    $parts      = explode('.', $filename);
    $ext        = array_pop($parts);
    $filename   = array_shift($parts);

    foreach ($parts as $part)
    {
        if ( ! in_array(strtolower($part), $this->allowed_types) OR $this->mimes_types(strtolower($part)) === FALSE)
        {
            $filename .= '.'.$part.'_';
        }
        else
        {
            $filename .= '.'.$part;
        }
    }

    $filename .= '.'.$ext;

    return $filename;
}

给定文件名fax-1377114300-521518bca7c5a7.65243756.xml,会发生这种情况。

$parts     = explode('.', $filename);

这会将$filename 分解为一个包含 3 个值的数组:

print_r($parts); //Array ( [0] => fax-1377119574-52152d561f4694 [1] => 21065888 [2] => xml )

下一行...

$ext       = array_pop($parts);

pops $parts 数组:

print_r($parts); //Array ( [0] => fax-1377119706-52152dda0205e5 [1] => 29551151 )

下一行...

$filename   = array_shift($parts);

shifts 数组:

print_r($parts); //Array ( [0] => 39795691 )

所以现在$parts 只包含一项:39795691

现在运行

foreach ($parts as $part)
{
    if ( ! in_array(strtolower($part), $this->allowed_types) OR $this->mimes_types(strtolower($part)) === FALSE)
    {
        $filename .= '.'.$part.'_';
    }
    else
    {
        $filename .= '.'.$part;
    }
}

它检查$parts 中的任何值(请记住,在这种情况下我们只有一项:39795691)是否在allowed_typesmime_types 数组中。由于它是一个数字并且不在这两个数组中,因此它将部分连接到 $filename 变量中并附加下划线。

【讨论】:

  • 我想在上传之前执行此操作。如果我echo $config['file_name'] 最后没有句号或下划线。根据你的解释,你是说它从最后一个数字中分离出来,你的意思是它从字面上删除最后一个数字并用句号替换它吗?
  • 好吧,你在上传之前设置了$config。所以在配置之前设置 $filename 并设置 $config['file_name'] = $filename;
  • 不,它不会删除最后一个数字并用下划线替换它......我更新了答案,希望能澄清发生了什么。
  • 哇,很好的解释。谢谢你。在我阅读它之后,我能够做一个更简单的解决方案。我从uniqid 中删除了true,它禁用了more_entropy,因此它停止添加下划线。再次感谢!
猜你喜欢
  • 2011-08-09
  • 1970-01-01
  • 1970-01-01
  • 2012-02-12
  • 2019-08-15
  • 2012-09-07
  • 1970-01-01
  • 2013-02-21
  • 1970-01-01
相关资源
最近更新 更多