Php UTF-8站点中的Windows-1251文件?

Php UTF-8站点中的Windows-1251文件?,php,encoding,utf-8,Php,Encoding,Utf 8,大家好,网络设备大师: 我有一段PHP脚本,从我的winamp中获取最后10首播放的歌曲。这个脚本在文件中,让我们调用它lastplayed.php,它包含在我的站点中,并带有一个div中的php include函数。 我的站点采用UTF-8编码。问题是有些歌曲的标题采用Windows-1251编码。在我的网站上,它们显示为������... 有没有已知的方法告诉这个包含lastplayed.php的div使用windows-1251编码? 还有其他建议吗 注意:带有抓取脚本a.k.a.last

大家好,网络设备大师: 我有一段PHP脚本,从我的winamp中获取最后10首播放的歌曲。这个脚本在文件中,让我们调用它lastplayed.php,它包含在我的站点中,并带有一个div中的php include函数。 我的站点采用UTF-8编码。问题是有些歌曲的标题采用Windows-1251编码。在我的网站上,它们显示为������... 有没有已知的方法告诉这个包含lastplayed.php的div使用windows-1251编码? 还有其他建议吗

注意:带有抓取脚本a.k.a.lastplayed.php的文件被转换为UTF-8。但如果是ANCII,结果也是一样的。我试着用windows-1251将和元标记放在头标记之间,但什么也没发生

p.p.S:获取Winamp数据lastplayed.php的脚本:

<?php
/******
* You may use and/or modify this script as long as you:
* 1. Keep my name & webpage mentioned
* 2. Don't use it for commercial purposes
*
* If you want to use this script without complying to the rules above, please contact me first at: marty@excudo.net
* 
* Author: Martijn Korse
* Website: http://devshed.excudo.net
*
* Date:  08-05-2006
***/

/**
 * version 2.0
 */
class Radio
{
    var $fields = array();
    var $fieldsDefaults = array("Server Status", "Stream Status", "Listener Peak", "Average Listen Time", "Stream Title", "Content Type", "Stream Genre", "Stream URL", "Current Song");
    var $very_first_str;
    var $domain, $port, $path;
    var $errno, $errstr;
    var $trackLists = array();
    var $isShoutcast;
    var $nonShoutcastData = array(
                    "Server Status"     => "n/a",
                    "Stream Status"     => "n/a",
                    "Listener Peak"     => "n/a",
                    "Average Listen Time"   => "n/a",
                    "Stream Title"      => "n/a",
                    "Content Type"      => "n/a",
                    "Stream Genre"      => "n/a",
                    "Stream URL"        => "n/a",
                    "Stream AIM"        => "n/a",
                    "Stream IRC"        => "n/a",
                    "Current Song"      => "n/a"
                    );
    var $altServer = False;

    function Radio($url)
    {
        $parsed_url = parse_url($url);
        $this->domain   = isset($parsed_url['host']) ? $parsed_url['host'] : "";
        $this->port = !isset($parsed_url['port']) || empty($parsed_url['port']) ? "80" : $parsed_url['port'];
        $this->path = empty($parsed_url['path']) ? "/" : $parsed_url['path'];

        if (empty($this->domain))
        {
            $this->domain = $this->path;
            $this->path = "";
        }

        $this->setOffset("Current Stream Information");
        $this->setFields();     // setting default fields

        $this->setTableStart("<table border=0 cellpadding=2 cellspacing=2>");
        $this->setTableEnd("</table>");
    }

    function setFields($array=False)
    {
        if (!$array)
            $this->fields = $this->fieldsDefaults;
        else
            $this->fields = $array;
    }
    function setOffset($string)
    {
        $this->very_first_str = $string;
    }
    function setTableStart($string)
    {
        $this->tableStart = $string;
    }
    function setTableEnd($string)
    {
        $this->tableEnd = $string;
    }

    function getHTML($page=False)
    {
        if (!$page)
            $page = $this->path;
        $contents = "";
        $domain = (substr($this->domain, 0, 7) == "http://") ? substr($this->domain, 7) : $this->domain;


        if (@$fp = fsockopen($domain, $this->port, $this->errno, $this->errstr, 2))
        {
            fputs($fp, "GET ".$page." HTTP/1.1\r\n".
                "User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows 98)\r\n".
                "Accept: */*\r\n".
                "Host: ".$domain."\r\n\r\n");

            $c = 0;
            while (!feof($fp) && $c <= 20)
            {
                $contents .= fgets($fp, 4096);
                $c++;
            }

            fclose ($fp);

            preg_match("/(Content-Type:)(.*)/i", $contents, $matches);
            if (count($matches) > 0)
            {
                $contentType = trim($matches[2]);
                if ($contentType == "text/html")
                {
                    $this->isShoutcast = True;
                    return $contents;
                }
                else
                {
                    $this->isShoutcast = False;

                    $htmlContent = substr($contents, 0, strpos($contents, "\r\n\r\n"));

                    $dataStr = str_replace("\r", "\n", str_replace("\r\n", "\n", $contents));
                    $lines = explode("\n", $dataStr);
                    foreach ($lines AS $line)
                    {
                        if ($dp = strpos($line, ":"))
                        {
                            $key = substr($line, 0, $dp);
                            $value = trim(substr($line, ($dp+1)));
                            if (preg_match("/genre/i", $key))
                                $this->nonShoutcastData['Stream Genre'] = $value;
                            if (preg_match("/name/i", $key))
                                $this->nonShoutcastData['Stream Title'] = $value;
                            if (preg_match("/url/i", $key))
                                $this->nonShoutcastData['Stream URL'] = $value;
                            if (preg_match("/content-type/i", $key))
                                $this->nonShoutcastData['Content Type'] = $value;
                            if (preg_match("/icy-br/i", $key))
                                $this->nonShoutcastData['Stream Status'] = "Stream is up at ".$value."kbps";
                            if (preg_match("/icy-notice2/i", $key))
                            {
                                $this->nonShoutcastData['Server Status'] = "This is <span style=\"color: red;\">not</span> a Shoutcast server!";
                                if (preg_match("/ultravox/i", $value))
                                    $this->nonShoutcastData['Server Status'] .= " But an <a href=\"http://ultravox.aol.com/\" target=\"_blank\">Ultravox</a> Server";
                                $this->altServer = $value;
                            }
                        }
                    }
                    return nl2br($htmlContent);
                }
            }
            else
                return $contents;
        }
        else
        {
            return False;
        }
    }

    function getServerInfo($display_array=null, $very_first_str=null)
    {
        if (!isset($display_array))
            $display_array = $this->fields;
        if (!isset($very_first_str))
            $very_first_str = $this->very_first_str;

        if ($html = $this->getHTML())
        {
             // parsing the contents
            $data = array();
            foreach ($display_array AS $key => $item)
            {
                if ($this->isShoutcast)
                {
                    $very_first_pos = stripos($html, $very_first_str);
                    $first_pos  = stripos($html, $item, $very_first_pos);
                    $line_start = strpos($html, "<td>", $first_pos);
                    $line_end   = strpos($html, "</td>", $line_start) + 4;
                    $difference = $line_end - $line_start;
                    $line       = substr($html, $line_start, $difference);
                    $data[$key] = strip_tags($line);
                }
                else
                {
                    $data[$key] = $this->nonShoutcastData[$item];
                }
            }
            return $data;
        }
        else
        {
            return $this->errstr." (".$this->errno.")";
        }
    }

    function createHistoryArray($page)
    {
        if (!in_array($page, $this->trackLists))
        {
            $this->trackLists[] = $page;
            if ($html = $this->getHTML($page))
            {
                $fromPos    = stripos($html, $this->tableStart);
                $toPos      = stripos($html, $this->tableEnd, $fromPos);
                $tableData  = substr($html, $fromPos, ($toPos-$fromPos));
                $lines      = explode("</tr><tr>", $tableData);
                $tracks = array();
                $c = 0;
                foreach ($lines AS $line)
                {
                    $info = explode ("</td><td>", $line);
                    $time = trim(strip_tags($info[0]));
                    if (substr($time, 0, 9) != "Copyright" && !preg_match("/Tag Loomis, Tom Pepper and Justin Frankel/i", $info[1]))
                    {
                        $this->tracks[$c]['time'] = $time;
                        $this->tracks[$c++]['track'] = trim(strip_tags($info[1]));
                    }
                }
                if (count($this->tracks) > 0)
                {
                    unset($this->tracks[0]);
                    if (isset($this->tracks[1]))
                        $this->tracks[1]['track'] = str_replace("Current Song", "", $this->tracks[1]['track']);
                }
            }
            else
            {
                $this->tracks[0] = array("time"=>$this->errno, "track"=>$this->errstr);
            }
        }
    }
    function getHistoryArray($page="/played.html")
    {
        if (!in_array($page, $this->trackLists))
            $this->createHistoryArray($page);
        return $this->tracks;
    }
    function getHistoryTable($page="/played.html", $trackColText=False, $class=False)
    {
        $title_utf8 = mb_convert_encoding($trackArr ,"utf-8" ,"auto");

        if (!in_array($page, $this->trackLists))
            $this->createHistoryArray($page);
        if ($trackColText)
            $output .= "
            <div class='lastplayed_top'></div>
            <div".($class ? " class=\"".$class."\"" : "").">";
        foreach ($this->tracks AS $title_utf8)
            $output .= "<div style='padding:2px 0;'>".$title_utf8['track']."</div>";
        $output .= "</div><div class='lastplayed_bottom'></div>
        <div class='lastplayed_title'>".$trackColText."</div>
        \n";
        return $output;
    }
}

 // this is needed for those with a php version < 5
 // the function is copied from the user comments @ php.net (http://nl3.php.net/stripos)
if (!function_exists("stripos"))
{
    function stripos($haystack, $needle, $offset=0)
    {
        return strpos(strtoupper($haystack), strtoupper($needle), $offset);
    }
}
?>
include "lastplayed.php";
$radio = new Radio($ip.":".$port);
echo $radio->getHistoryTable("/played.html", "<b>Last played:</b>", "lastplayed_content");
以及lastplayed.php之外的调用脚本:

<?php
/******
* You may use and/or modify this script as long as you:
* 1. Keep my name & webpage mentioned
* 2. Don't use it for commercial purposes
*
* If you want to use this script without complying to the rules above, please contact me first at: marty@excudo.net
* 
* Author: Martijn Korse
* Website: http://devshed.excudo.net
*
* Date:  08-05-2006
***/

/**
 * version 2.0
 */
class Radio
{
    var $fields = array();
    var $fieldsDefaults = array("Server Status", "Stream Status", "Listener Peak", "Average Listen Time", "Stream Title", "Content Type", "Stream Genre", "Stream URL", "Current Song");
    var $very_first_str;
    var $domain, $port, $path;
    var $errno, $errstr;
    var $trackLists = array();
    var $isShoutcast;
    var $nonShoutcastData = array(
                    "Server Status"     => "n/a",
                    "Stream Status"     => "n/a",
                    "Listener Peak"     => "n/a",
                    "Average Listen Time"   => "n/a",
                    "Stream Title"      => "n/a",
                    "Content Type"      => "n/a",
                    "Stream Genre"      => "n/a",
                    "Stream URL"        => "n/a",
                    "Stream AIM"        => "n/a",
                    "Stream IRC"        => "n/a",
                    "Current Song"      => "n/a"
                    );
    var $altServer = False;

    function Radio($url)
    {
        $parsed_url = parse_url($url);
        $this->domain   = isset($parsed_url['host']) ? $parsed_url['host'] : "";
        $this->port = !isset($parsed_url['port']) || empty($parsed_url['port']) ? "80" : $parsed_url['port'];
        $this->path = empty($parsed_url['path']) ? "/" : $parsed_url['path'];

        if (empty($this->domain))
        {
            $this->domain = $this->path;
            $this->path = "";
        }

        $this->setOffset("Current Stream Information");
        $this->setFields();     // setting default fields

        $this->setTableStart("<table border=0 cellpadding=2 cellspacing=2>");
        $this->setTableEnd("</table>");
    }

    function setFields($array=False)
    {
        if (!$array)
            $this->fields = $this->fieldsDefaults;
        else
            $this->fields = $array;
    }
    function setOffset($string)
    {
        $this->very_first_str = $string;
    }
    function setTableStart($string)
    {
        $this->tableStart = $string;
    }
    function setTableEnd($string)
    {
        $this->tableEnd = $string;
    }

    function getHTML($page=False)
    {
        if (!$page)
            $page = $this->path;
        $contents = "";
        $domain = (substr($this->domain, 0, 7) == "http://") ? substr($this->domain, 7) : $this->domain;


        if (@$fp = fsockopen($domain, $this->port, $this->errno, $this->errstr, 2))
        {
            fputs($fp, "GET ".$page." HTTP/1.1\r\n".
                "User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows 98)\r\n".
                "Accept: */*\r\n".
                "Host: ".$domain."\r\n\r\n");

            $c = 0;
            while (!feof($fp) && $c <= 20)
            {
                $contents .= fgets($fp, 4096);
                $c++;
            }

            fclose ($fp);

            preg_match("/(Content-Type:)(.*)/i", $contents, $matches);
            if (count($matches) > 0)
            {
                $contentType = trim($matches[2]);
                if ($contentType == "text/html")
                {
                    $this->isShoutcast = True;
                    return $contents;
                }
                else
                {
                    $this->isShoutcast = False;

                    $htmlContent = substr($contents, 0, strpos($contents, "\r\n\r\n"));

                    $dataStr = str_replace("\r", "\n", str_replace("\r\n", "\n", $contents));
                    $lines = explode("\n", $dataStr);
                    foreach ($lines AS $line)
                    {
                        if ($dp = strpos($line, ":"))
                        {
                            $key = substr($line, 0, $dp);
                            $value = trim(substr($line, ($dp+1)));
                            if (preg_match("/genre/i", $key))
                                $this->nonShoutcastData['Stream Genre'] = $value;
                            if (preg_match("/name/i", $key))
                                $this->nonShoutcastData['Stream Title'] = $value;
                            if (preg_match("/url/i", $key))
                                $this->nonShoutcastData['Stream URL'] = $value;
                            if (preg_match("/content-type/i", $key))
                                $this->nonShoutcastData['Content Type'] = $value;
                            if (preg_match("/icy-br/i", $key))
                                $this->nonShoutcastData['Stream Status'] = "Stream is up at ".$value."kbps";
                            if (preg_match("/icy-notice2/i", $key))
                            {
                                $this->nonShoutcastData['Server Status'] = "This is <span style=\"color: red;\">not</span> a Shoutcast server!";
                                if (preg_match("/ultravox/i", $value))
                                    $this->nonShoutcastData['Server Status'] .= " But an <a href=\"http://ultravox.aol.com/\" target=\"_blank\">Ultravox</a> Server";
                                $this->altServer = $value;
                            }
                        }
                    }
                    return nl2br($htmlContent);
                }
            }
            else
                return $contents;
        }
        else
        {
            return False;
        }
    }

    function getServerInfo($display_array=null, $very_first_str=null)
    {
        if (!isset($display_array))
            $display_array = $this->fields;
        if (!isset($very_first_str))
            $very_first_str = $this->very_first_str;

        if ($html = $this->getHTML())
        {
             // parsing the contents
            $data = array();
            foreach ($display_array AS $key => $item)
            {
                if ($this->isShoutcast)
                {
                    $very_first_pos = stripos($html, $very_first_str);
                    $first_pos  = stripos($html, $item, $very_first_pos);
                    $line_start = strpos($html, "<td>", $first_pos);
                    $line_end   = strpos($html, "</td>", $line_start) + 4;
                    $difference = $line_end - $line_start;
                    $line       = substr($html, $line_start, $difference);
                    $data[$key] = strip_tags($line);
                }
                else
                {
                    $data[$key] = $this->nonShoutcastData[$item];
                }
            }
            return $data;
        }
        else
        {
            return $this->errstr." (".$this->errno.")";
        }
    }

    function createHistoryArray($page)
    {
        if (!in_array($page, $this->trackLists))
        {
            $this->trackLists[] = $page;
            if ($html = $this->getHTML($page))
            {
                $fromPos    = stripos($html, $this->tableStart);
                $toPos      = stripos($html, $this->tableEnd, $fromPos);
                $tableData  = substr($html, $fromPos, ($toPos-$fromPos));
                $lines      = explode("</tr><tr>", $tableData);
                $tracks = array();
                $c = 0;
                foreach ($lines AS $line)
                {
                    $info = explode ("</td><td>", $line);
                    $time = trim(strip_tags($info[0]));
                    if (substr($time, 0, 9) != "Copyright" && !preg_match("/Tag Loomis, Tom Pepper and Justin Frankel/i", $info[1]))
                    {
                        $this->tracks[$c]['time'] = $time;
                        $this->tracks[$c++]['track'] = trim(strip_tags($info[1]));
                    }
                }
                if (count($this->tracks) > 0)
                {
                    unset($this->tracks[0]);
                    if (isset($this->tracks[1]))
                        $this->tracks[1]['track'] = str_replace("Current Song", "", $this->tracks[1]['track']);
                }
            }
            else
            {
                $this->tracks[0] = array("time"=>$this->errno, "track"=>$this->errstr);
            }
        }
    }
    function getHistoryArray($page="/played.html")
    {
        if (!in_array($page, $this->trackLists))
            $this->createHistoryArray($page);
        return $this->tracks;
    }
    function getHistoryTable($page="/played.html", $trackColText=False, $class=False)
    {
        $title_utf8 = mb_convert_encoding($trackArr ,"utf-8" ,"auto");

        if (!in_array($page, $this->trackLists))
            $this->createHistoryArray($page);
        if ($trackColText)
            $output .= "
            <div class='lastplayed_top'></div>
            <div".($class ? " class=\"".$class."\"" : "").">";
        foreach ($this->tracks AS $title_utf8)
            $output .= "<div style='padding:2px 0;'>".$title_utf8['track']."</div>";
        $output .= "</div><div class='lastplayed_bottom'></div>
        <div class='lastplayed_title'>".$trackColText."</div>
        \n";
        return $output;
    }
}

 // this is needed for those with a php version < 5
 // the function is copied from the user comments @ php.net (http://nl3.php.net/stripos)
if (!function_exists("stripos"))
{
    function stripos($haystack, $needle, $offset=0)
    {
        return strpos(strtoupper($haystack), strtoupper($needle), $offset);
    }
}
?>
include "lastplayed.php";
$radio = new Radio($ip.":".$port);
echo $radio->getHistoryTable("/played.html", "<b>Last played:</b>", "lastplayed_content");

如果所有源数据都在windows-1251中,则可以使用以下内容:

$title_utf8=mb_convert_encoding($title,"utf-8","Windows-1251")
并将转换后的数据放入HTML流中

因为我只查看文档,所以我不能100%确定源编码别名是否正确;如果Windows-1251无法工作,您可能需要尝试CP1251

如果您的源数据在1251中不可靠,您将不得不提出一种启发式猜测,并使用相同的转换方法。mb_detect_编码可能对您有所帮助

您不能仅更改HTML文档的一部分的编码,但您肯定可以很容易地将所有内容转换为UTF-8

较新的ID3实现在其文本框中有一个编码标记:

$00 ISO-8859-1 (ASCII)
$01 – UCS-2 in ID3v2.2 and ID3v2.3, UTF-16 encoded Unicode with BOM. 
$02 – UTF-16BE encoded Unicode without BOM in ID3v2.4 only.
$03 – UTF-8 encoded Unicode in ID3v2.4 only.
您的内容可能是UTF16格式的吗

根据您发布的代码,不清楚$trackArr是如何定义的,因为它没有在其他地方引用。看起来你有几个问题

$title_utf8 = mb_convert_encoding($trackArr ,"utf-8" ,"auto")
“自动”扩展为不包含Windows-1251的编码列表,因此我不确定您为什么使用它。你真的应该使用Windows-1251。我曾尝试在安装了PHP的mac电脑上使用Windows-1251、utf-16,但autodetect无法根据相对较短的字符串找到合适的编码,因此看起来您必须猜测

但这段代码看起来并没有任何存在的理由,因为您用迭代覆盖了这些值:

    foreach ($this->tracks AS $title_utf8)
            $output .= "<div style='padding:2px 0;'>".$title_utf8['track'].\"</div>";

mb_convert_编码将字符串作为第一个参数,而不是数组或对象,因此您需要在每个非utf-8的字符串上应用此编码。

只是为了让您知道最新版本支持字符编码/解码:-

可能更容易将mp3文件的ID3标记转换为utf-8编码。否则,您需要在显示ID3标记之前检测其编码。这里是ID3编码转换的实用工具,不知道如何使它工作。。。很抱歉否则它是有意义的…谢谢你Jasonrue,这是有意义的,但显然我想要的编码不是wIndows-1251。。。现在我必须弄清楚那该死的抓取数据的编码是什么!。。。。该死的。。。但是我尝试了你的代码,但它似乎不起作用,或者我做错了什么……也许你需要深入挖掘内容。我已经添加了一个关于ID3支持的编码标记的注释。我不能保证我的代码能正常工作,因为我不怎么使用PHP,但是你可以在文档中查找我使用的方法,很可能你是wright。我在winamp的mp3插件中看到了配置。引用:ID3标记读取-系统语言,ID3标记写入-Unicode UTF-16。。。其他可供选择的选项是系统语言和拉丁语-1。。。在我改变这个选项后,什么都不会发生。。。可能我需要重新加载整个播放列表,然后在网站上查看是否有任何更改?!。。。地狱我不知道会出现这样的问题……实际上,当我打开lastplayed.php并手动告诉浏览器编码为Windows-1251时,所有标题都会正确显示。当这个文件包含在我的基于utf-8的站点中时,问题就出现了。但这里重要的是,显然windows-1251是我歌曲标题的正确编码——winamp用这种编码发送数据可能是什么?该死的。。。我现在完全迷路了…:我不知道该怎么想:最有可能的是,你的CD翻录软件或任何最初编码你的文件的软件使用了CP_ACP系统ANSI代码页,除非它相当精通unicode。根据您描述的配置,听起来WinAmp将采用CP_ACP,除非明确标记编码;创建新项时创建新ID3记录时,它将显式设置为UTF-16。您的代码应该以相同的方式处理隐式情况,并注意ID3数据中的显式编码标记。Windows-1251、UTF-16作为从编码参数到mb_convert_编码是否足够?