我对这些编码问题感到疯狂......
我使用json_decode
和json_encode
来存储和检索数据。我发现的是,json总是需要utf-8。没问题。我在utf-8中给json'hellö',在我的DB中看起来像hellu00f6
。好的,codepoint。但是当我使用json_decode
时,它不会解码代码点,所以我仍然有hellu00f6
。
此外,在PHP 5.2.13中,似乎JSON中仍然没有选项标签。如何将代码点caracters转换回正确的特殊字符以便在浏览器中显示?
Greetz和谢谢
Maenny
答案 0 :(得分:1)
可能是因为JSON unicode字符串中代码点之前的反斜杠:ö
表示\u00f6
。当存储在您的数据库中时,DBMS不知道如何解释\u00f6
所以我猜它会将其读取(并存储)为u00f6
。
您使用的是逃避功能吗?
尝试在unicode-escaped chars上添加反斜杠:
$json = str_replace("\\u", "\\\\u", $json);
答案 1 :(得分:0)
上一篇文章已经解释过,为什么你的例子没有按预期工作。 但是,在使用数据库时有一些很好的编码实践,这对提高应用程序的安全性很重要(即防止SQL注入)。
以下示例旨在展示其中一些实践,并假设PHP 5.2和MySQL 5.1。 (请注意,所有文件和数据库条目都使用UTF-8编码存储。)
此示例中使用的数据库名为test
,表格创建如下:
CREATE TABLE `test`.`entries` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`data` VARCHAR( 100 ) NOT NULL
) ENGINE = InnoDB CHARACTER SET utf8 COLLATE utf8_bin
(请注意,编码设置为utf8_bin
。)
它遵循php代码,用于两者,添加新条目和创建JSON:
<?
$conn = new PDO('mysql:host=localhost;dbname=test','root','xxx');
$conn->exec("SET NAMES 'utf8'"); // Enable UTF-8 charset for db-communication ..
if(isset($_GET['add_entry'])) {
header('Content-Type: text/plain; charset=UTF-8');
// Add new DB-Entry:
$data = $conn->quote($_GET['add_entry']);
if($conn->exec('INSERT INTO `entries` (`data`) VALUES ('.$data.')')) {
$id = $conn->lastInsertId();
echo 'Created entry '.$id.': '.$_GET['add_entry'];
} else {
$info = $conn->errorInfo();
echo 'Unable to create entry: '. $info[2];
}
} else {
header('Content-Type: text/json; charset=UTF-8');
// Output DB-Entries as JSON:
$entries = array();
if($res = $conn->query('SELECT * FROM `entries`')) {
$res->setFetchMode(PDO::FETCH_ASSOC);
foreach($res as $row) {
$entries[] = $row;
}
}
echo json_encode($entries);
}
?>
在将数据传递到数据库之前,请注意方法$conn->quote(..)
的用法。正如前面的帖子所提到的,使用预准备语句甚至会更好,因为它们已经完成了整个转义。因此,如果我们写下来会更好:
$prepStmt = $conn->prepare('INSERT INTO `entries` (`data`) VALUES (:data)');
if($prepStmt->execute(array('data'=>$_GET['add_entry']))) {...}
而不是
$data = $conn->quote($_GET['add_entry']);
if($conn->exec('INSERT INTO `entries` (`data`) VALUES ('.$data.')')) {...}
结论:对存储或传输给用户的所有字符数据使用UTF-8是合理的。它使国际化Web应用程序的开发变得更加容易。为了确保用户输入正确发送到数据库,使用转义函数是个好主意。否则,使用预准备语句可以使生活和开发更加轻松,并且可以进一步提高应用程序的安全性,因为可以防止SQL注入。