$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
看起来正在发生的事情是_prep_filename()
Upload.php 中的方法检查allowed_types
和mimes_types
与爆炸的文件名。文件名中的句点将扩展名之前的最后一个数字(示例文件名中的 65243756)拆分为parts
数组。allowed_types
然后它根据和检查这个值mimes_types
。无法在allowed_types
或 中找到数字mimes_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);
pop
s$parts
数组:
print_r($parts); //Array ( [0] => fax-1377119706-52152dda0205e5 [1] => 29551151 )
下一行...
$filename = array_shift($parts);
shift
s 数组:
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_types
ormime_types
数组中。由于它是一个数字并且不在这两个数组中,因此它将部分连接到$filename
变量中并附加下划线。