zoukankan      html  css  js  c++  java
  • PHP批量去除文件BOM头

    检查bom头和utf8编码检查

    <?php
    set_time_limit(0);
    $basedir = ".";//检查的目录 ..为上级目录
    $otherDirArr = [".svn",'images','web'];//排除目录
    $fileTypeArr = ['.php'];//检查文件类型
    $auto = 0;//0 1为自动更改文件编码
    $display = 1;
    checkdir($basedir,$otherDirArr,$fileTypeArr);
    function checkdir($basedir,$otherDirArr,$fileTypeArr)
    {
        global $display;
        if ($dh = opendir($basedir))
        {
            while (($file = readdir($dh)) !== false)
            {
                if ($file != '.' && $file != '..' )
                {
                    if (!is_dir($basedir . "/" . $file) )
                    {//文件
                        if(in_array(strrchr($file, '.'),$fileTypeArr))
                        {//指定文件扩展
                            $fileName = "文 件: {$basedir}/{$file}";
                            $fileName = str_pad($fileName, 160, "-");
                            $result = checkBOM("$basedir/$file");
                            if ($display == 0 && $result == 'BOM not found')
                            {
                            }
                            else
                            {
                                echo $fileName . checkBOM("$basedir/$file") . " <br>";
                            }
                            //检查
                        }
                    }
                    else
                    {
                        if(!in_array($file,$otherDirArr))
                        {
                            $dirname = $basedir . "/" . $file; // 如果是目录
                            echo "<br>目 录: {$dirname}<br>";
                            checkdir($dirname,$otherDirArr,$fileTypeArr); // 递归
                        }
                    }
                }
            }
            closedir($dh);
        }
    }
    function checkBOM($filename)
    {
        $msg = "";
        global $auto;
        $contents = file_get_contents($filename);
        $charset[1] = substr($contents, 0, 1);
        $charset[2] = substr($contents, 1, 1);
        $charset[3] = substr($contents, 2, 1);
        // BOM的前三个字符的ASCII码分别为239、187、191
        if (ord($charset[1]) == 239 && ord($charset[2]) == 187 && ord($charset[3]) == 191)
        {
            if ($auto == 1)
            {
                $rest = substr($contents, 3);
                rewrite($filename, $rest);
                $msg = ("<b style='color:fuchsia'>BOM find, automatically removed</b>");
            }
            else
            {
                $msg = ("<b style='color: red'>BOM find</b>");
            }
        }
        else
        {
            $msg = ("<b style='color: green'>BOM not find</b>");
        }
        switch (utf8_check($contents))
        {
            case 1:
                $msg .= " 编码有BOM头";break;
            case 2:
                $msg .= " 编码utf8";break;
            case 3:
                $msg .= " 编码较可能是utf8";break;
            case 4:
                $msg .= " 编码较不可能是utf8";break;
        }
        return $msg;
    }
    
    function utf8_check($text)
    {
        $utf8_bom = chr(0xEF).chr(0xBB).chr(0xBF);
        // BOM头检查
        if (strstr($text, $utf8_bom) === 0)
            return 1;
        $text_len = strlen($text);
        // UTF-8是一种变长字节编码方式。对于某一个字符的UTF-8编码,如果只有一个字节则其最高二进制位为0;
        // 如果是多字节,其第一个字节从最高位开始,连续的二进制位值为1的个数决定了其编码的位数,其余各字节均以10开头。
        // UTF-8最多可用到6个字节。
        //
        // 如表:
        // < 0x80 1字节 0xxxxxxx
        // < 0xE0 2字节 110xxxxx 10xxxxxx
        // < 0xF0 3字节 1110xxxx 10xxxxxx 10xxxxxx
        // < 0xF8 4字节 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
        // < 0xFC 5字节 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
        // < 0xFE 6字节 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
        $bad   = 0; // 不符合utf8规范的字符数
        $good  = 0; // 符号utf8规范的字符数
        $need_check = 0; // 遇到多字节的utf8字符后,需要检查的连续字节数
        $have_check = 0; // 已经检查过的连续字节数
        for ($i = 0; $i < $text_len; $i ++) {
            $c = ord($text[$i]);
            if ($need_check > 0) {
                $c = ord($text[$i]);
                $c = ($c >> 6) << 6;
                $have_check ++;
                // 10xxxxxx ~ 10111111
                if ($c != 0x80) {
                    $i -= $have_check;
                    $need_check = 0;
                    $have_check = 0;
                    $bad ++;
                }
                else if ($need_check == $have_check) {
                    $need_check = 0;
                    $have_check = 0;
                    $good ++;
                }
                continue;
            }
            if ($c < 0x80)      // 0xxxxxxx
                $good ++;
            else if ($c < 0xE0) // 110xxxxx
                $need_check = 1;
            else if ($c < 0xF0) // 1110xxxx
                $need_check = 2;
            else if ($c < 0xF8) // 11110xxx
                $need_check = 3;
            else if ($c < 0xFC) // 111110xx
                $need_check = 4;
            else if ($c < 0xFE) // 1111110x
                $need_check = 5;
            else
                $bad ++;
        }
        if ($bad == 0)
            return 2;
        else if ($good > $bad)
            return 3;
        else
            return 4;
    }
    function rewrite($filename, $data)
    {
        $filenum = fopen($filename, "w");
        flock($filenum, LOCK_EX);
        fwrite($filenum, $data);
        fclose($filenum);
    }
  • 相关阅读:
    利用DTrace实时检测MySQl
    改进MySQL Order By Rand()的低效率
    RDS for MySQL查询缓存 (Query Cache) 的设置和使用
    RDS For MySQL 字符集相关说明
    RDS for MySQL 通过 mysqlbinlog 查看 binlog 乱码
    RDS for MySQL Mysqldump 常见问题和处理
    RDS for MySQL Online DDL 使用
    RDS MySQL 表上 Metadata lock 的产生和处理
    RDS for MySQL 如何使用 Percona Toolkit
    北京已成为投融资诈骗重灾区:存好骗子公司黑名单,谨防上当!
  • 原文地址:https://www.cnblogs.com/sentangle/p/11540290.html
Copyright © 2011-2022 走看看