JSON specialchars JSON php 5.2.13

时间:2010-07-13 15:44:14

标签: php json htmlspecialchars

我对这些编码问题感到疯狂......

我使用json_decodejson_encode来存储和检索数据。我发现的是,json总是需要utf-8。没问题。我在utf-8中给json'hellö',在我的DB中看起来像hellu00f6。好的,codepoint。但是当我使用json_decode时,它不会解码代码点,所以我仍然有hellu00f6。 此外,在PHP 5.2.13中,似乎JSON中仍然没有选项标签。如何将代码点caracters转换回正确的特殊字符以便在浏览器中显示?

Greetz和谢谢

Maenny

2 个答案:

答案 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注入。