今天部署一台新的服务器,部署好后发现验证码不能正确显示。检查了代码,确定没有问题,用Fiddle抓取了验证码的数据,看到有BOM,不知道修改哪个文件的时候带进去了。文件太多,不好查找,于是写了以下脚本,自动查找当前目录下的php文件,如果含有BOM,尝试清除,如果清除失败,会提示,进行手动修改。
PHP代码:<code>
class BomCleaner
{
private $files = array();
private $cleaned = array();
private $uncleaned = array();
public function clean($base_dir)
{
$this->walk_files($base_dir);
foreach($this->files as $file)
{
$state = $this->clean_bom($file);
if( $state==1 )
$this->uncleaned[] = $file;
elseif( $state==2 )
$this->cleaned[] = $file;
}
$this->show_result();
}
private function walk_files($dir, $suffix='php')
{
foreach( glob($dir.'/*') as $file )
{
if( is_dir($file) )
$this->walk_files($file);
elseif( is_file($file) && preg_match('/'.$suffix.'$/is', $file) )
$this->files[] = $file;
}
}
private function clean_bom($file)
{
$head = file_get_contents($file, false, null, 0, 3);
if( bin2hex($head)=='efbbbf' )
{
if( !is_writable($file) )
return 1;
$data = file_get_contents($file, false, null, 3);
file_put_contents($file, $data);
return 2;
}
return 0;
}
private function show_result()
{
if( !$this->cleaned && !$this->uncleaned )
{
die('No BOM file found!');
}
else
{
echo 'Cleaned '.count($this->cleaned).' files: ';
echo '<ol>';
foreach($this->cleaned as $file)
echo '<li>'.$file.'</li>';
echo '</ol>';
echo 'Uncleaned '.count($this->uncleaned).' files: (not writeable)';
echo '<ol>';
foreach($this->uncleaned as $file)
echo '<li>'.$file.'</li>';
echo '</ol>';
}
}
}
$cleaner = new BomCleaner;
$cleaner->clean(__DIR__);
</code>
Linux脚本
在linux下,可用以下脚本一键解决,更方便
<code>find . -type f -exec sed -i 's/\xEF\xBB\xBF//' {} ;</code>