环境:godaddy Linux主机 LAMP环境。php:v5.3,MYSQL:5.0.96,测试操作系统Mac OSX M.Lion,傲游3浏览器问题:
有两个页面,一个是post.php;另一个是profile.php。一段完全相同的简单的代码,就是从数据库里取一个中文再显示。但是奇怪的事情发生了。post.php的中文显示正常,profile.php的总是显示问号。如果我先打开post.php,再转到profile.php,profile.php的中文就能正常显示;反之,profile.php的中文不能显示,但是post.php的中文依旧能正常显示。我已经把php代码里加入了 mysql_query("SET NAMES UTF8"); mysql的字段也设成了UTF_General_CI,数据库连接字符集也是UTF8_General_CI。但是问题依旧。下面的代码是profile.php的代码片段,去掉了冗长的HTML内容。其中第2-16行的代码是我从post.php中复制粘贴的,在post.php中正常,在profile.php中无法显示中文。需要先打开post.php,然后不关闭窗口,再打开profile.php才能正常显示中文。而且我注意到,dump出来的数组内容长度不对。正常显示应该是字数*3,显示不正常的时候就仅仅是字数*1。烦劳各位高手给看看,这问题困扰我好几天了。<?php
mysql_select_db($database_r365, $r365);
$query_Recordset1 = "SELECT JAName FROM JFieldsA";
mysql_query("SET NAMES UTF8");
$Recordset1 = mysql_query($query_Recordset1, $r365) or die(mysql_error());
$row_Recordset1 = mysql_fetch_assoc($Recordset1);
$totalRows_Recordset1 = mysql_num_rows($Recordset1);$query_jt = "SELECT TAName FROM JTitlesA";
mysql_query("SET NAMES UTF8");
$rsJTitlesA = mysql_query($query_jt, $r365) or die(mysql_error());
$row_rsJTitlesA = mysql_fetch_assoc($rsJTitlesA);
echo "<pre>";
var_dump($row_rsJTitlesA);
echo "</pre>";
$totalRows_rsJTitlesA = mysql_num_rows($rsJTitlesA);
?><?php
    //此处需要判断cookie的内容,以防止非法访问。留到1.1版本再说吧。先把基本功能实现。
    $sid=$_GET['s'];
    $sid2 = $_COOKIE['PHPSESSID'];    session_id(strrev($sid));
    session_start();    $bSID=0;
    if($sid == $sid2 || $sid==strrev($sid2))
    {
        $bSID=1;
    }
    
    if($bSID==1 && UID_Decode($_GET['u']) == $_SESSION['UID'])
    {
        $sid3 = strrev($sid);
        $uid=$_SESSION['UID'];
        $val_query = "SELECT * FROM ConsDB where UID=\"$uid\" AND sessid=\"$sid3\"";
        mysql_select_db($database_r365, $r365);
        mysql_query("SET NAMES UTF8");
        $temp = mysql_query($val_query, $r365) or die("Error in L22.");
        isset($temp) ? : die("Session数据错误。可能是您的浏览器不支持Cookie。请不要手动修改URL的数据和Cookie中的内容。");
    }
    else
    {
        die("Session数据错误。可能是您的浏览器不支持Cookie。请不要手动修改URL的数据和Cookie中的内容。");
    }
    
    //header("Content-Type:text/html;charset=UTF-8");    $UID = UID_Decode($_GET['u']);
    //debug($UID);
    
    $str = "SELECT * FROM `r365`.`ConsDB` WHERE UID=" . "\"$UID\"";
    //debug($str);
    $strAdv = "SELECT * FROM `r365`.`ConsDB_Adv` WHERE UID=" . "\"$UID\"";
    mysql_select_db($database_r365, $r365);
    mysql_query("SET NAMES UTF8");
    $rsUID = mysql_query($str, $r365) or die(mysql_error());
    mysql_query("SET NAMES UTF8");
    $rsAdv = mysql_query($strAdv, $r365) or die(mysql_error());
    $rsProfile = mysql_fetch_array($rsUID);
    $rsAdvProf = mysql_fetch_array($rsAdv);
    $_SESSION['$rsProfile'] = $rsProfile;
    //var_dump($rsAdvProf);
    //setcookie("PHPSESSID", strrev($_GET['s']), time()+106903);
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<!--meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /-->
<title><?php echo $rsProfile["LoginName"] . "的用户信息";?></title>
<link href="css/main.css" rel="stylesheet" type="text/css" />
<!--link href="css/profile.css" rel="stylesheet" type="text/css" /-->
</head><body></body>
</html>

解决方案 »

  1.   

    确认文件已保存文件 utf-8 的了,特别注意那些来自 window 的文件既然程序中有 var_dump,那么为什么不贴出相应的结果
      

  2.   

    PHP转义?
    magic_quotes_gpc设置是否自动为GPC(GET,POST,COOKIE)传来的数据中的某些字符进行转义,  
    可以使用addslashes() 
      

  3.   

    感谢各位的回复。编辑器我用的是网站自带的在线编辑器,所以应该不存在BOM签名的问题。我把结果贴出来:
    这个是profile.php的运行结果(其他地方省略了):
    array(1) {
      ["TAName"]=>
      string(3) "???"
    }以下是post.php的运行结果:
    array(1) {
      ["TAName"]=>
      string(9) "管理类"
    }回楼上的朋友:不是转意,而是为了防止修改URL中的参数而对数据进行非法访问而做的一点小手脚。我是新手,1个月前才开始接触PHP,请大家多多指教!!我看文档中说,magic_quote_gpc相关的函数好像尽量不要在用了,好像在最新版本的PHP已经deprecate了。所以,就没用那个函数。
      

  4.   

    一个环节一个环节地echo一下看看,可以找出问题在哪个环节上。再改变该环节的字符集。一楼的可能有。
      

  5.   

    乱码问题基本都是这个思路:
    数据库编码、脚本文件本身编码、html文档的编码(页面编码),只要这3个编码一致就不会出现乱码的问题,自己去看看问题出现在那里.
      

  6.   

    现在奇怪的是,两个网页的内容几乎相同(PHP部分是从A复制粘贴到B的),但是运行之后,A正常,B就显示问号。如果先运行A,在运行B,B又能够正常显示……觉得太诡异了,感觉自己我从下手,所以来求助。
      

  7.   

    http://bbs.csdn.net/topics/390503890这帖子里的方法我都试过了,不行啊~~  另外,有个问题可能和这个现象有关:我的网站统一都是UTF8编码。在进行注册时,通过网页注册的内容比如姓名,地址等,在phpMyAdmin当中显示的就是乱码,但是读取出来是正常的;这个表格是行业信息数据,我是从网上摘得,数据是通过phpMyAdmin导入的。在phpMyAdmin里面显示正常,但是读取后在网页上显示的时候,就发生了Post.php页面显示中文正常,但是Profile.php显示问号的问题。如果说是数据库字符集的问题,那为什么post.php却能够正常显示呢??
      

  8.   

    继续顶……我觉得,如果写一个php页面把这个数据表再写一遍,这样的话就应该正常了(在phpmyadmin里看到的是乱码的话,读取就是正常的)。只是这样的话仍然不能学到相关的知识。还请高手给把把脉
      

  9.   

    在phpmyadmin里看到的是乱码的话,读取就是正常的.这个是因为phpmyadmin显示的编码和你从数据库读取出来的字符编码不一致导致的.
      

  10.   

    谢谢楼上的朋友,我应该怎么改才能达到网页,数据库,phpmyadmin的现实都正常呢??我觉得现在我的网页编码和数据库编码应该是匹配的,我怎么才能在phpmyadmin里面也能够正常显示数据内容呢??
      

  11.   

    经过研究发现:
    问题可能出现在include的头文件上。
    post.php 引用的是DW生成的文件V1版本,里面不包含中文字符,而且有以下内容:# FileName="Connection_php_mysql.htm"
    # Type="MYSQL"
    # HTTP="true"
    profile.php 引用的是我修改过的V2版本,去掉了上述的字符,而且加入了设置时区位Asia/Chongqing的语句,还写了中文注释。我觉得可能由于上面的这三个原因,所以才会显示乱码。请问各位高手,上面这三行语句是做什么用的??在我修改过的引用文件V2中,我去掉了这些语句,会有什么样的后果??
      

  12.   

    1、检查是否有BOM头的影响$s = file_get_contents('http://localhost/post.php', false, null, 0, 20);
    print_r(unpack('H*', $s));
    $s = file_get_contents('http://localhost/profile.php', false, null, 0, 20);
    print_r(unpack('H*', $s));贴出结果
    2、profile.php 中有 array(1) {  ["TAName"]=>  string(3) "???" }
    这表示在 mysql 传出时,数据已经被破坏了,可绕过mysql的自动字符集转换
    $query_jt = "SELECT BINARY TAName FROM JTitlesA";
    mysql_query("SET NAMES UTF8");
    $rsJTitlesA = mysql_query($query_jt, $r365) or die(mysql_error());
    $row_rsJTitlesA = mysql_fetch_assoc($rsJTitlesA);
    var_dump($row_rsJTitlesA);
    最好贴出 echo base64_encode($row_rsJTitlesA['TAName']); 的结果
    3、尽管没有资料显示有这样的大小写敏感问题,但还是建议将 mysql_query("SET NAMES UTF8"); 写作
    mysql_query("SET NAMES utf8");
      

  13.   

    发现了一个问题。
    mysql_query("SET NAMES utf8");这句话只有在乱码的时候加上才有用,否则的话,我觉得可能会造成数据返回结果的二次编码,从而导致乱码。头疼的问题终于基本上解决了。等下回应版主贴上结果。先把网站完善。十分感谢各位。:)