环境: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>
有两个页面,一个是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>
magic_quotes_gpc设置是否自动为GPC(GET,POST,COOKIE)传来的数据中的某些字符进行转义,
可以使用addslashes()
这个是profile.php的运行结果(其他地方省略了):
array(1) {
["TAName"]=>
string(3) "???"
}以下是post.php的运行结果:
array(1) {
["TAName"]=>
string(9) "管理类"
}回楼上的朋友:不是转意,而是为了防止修改URL中的参数而对数据进行非法访问而做的一点小手脚。我是新手,1个月前才开始接触PHP,请大家多多指教!!我看文档中说,magic_quote_gpc相关的函数好像尽量不要在用了,好像在最新版本的PHP已经deprecate了。所以,就没用那个函数。
数据库编码、脚本文件本身编码、html文档的编码(页面编码),只要这3个编码一致就不会出现乱码的问题,自己去看看问题出现在那里.
问题可能出现在include的头文件上。
post.php 引用的是DW生成的文件V1版本,里面不包含中文字符,而且有以下内容:# FileName="Connection_php_mysql.htm"
# Type="MYSQL"
# HTTP="true"
profile.php 引用的是我修改过的V2版本,去掉了上述的字符,而且加入了设置时区位Asia/Chongqing的语句,还写了中文注释。我觉得可能由于上面的这三个原因,所以才会显示乱码。请问各位高手,上面这三行语句是做什么用的??在我修改过的引用文件V2中,我去掉了这些语句,会有什么样的后果??
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");
mysql_query("SET NAMES utf8");这句话只有在乱码的时候加上才有用,否则的话,我觉得可能会造成数据返回结果的二次编码,从而导致乱码。头疼的问题终于基本上解决了。等下回应版主贴上结果。先把网站完善。十分感谢各位。:)