JSON 特殊字符 JSON php 5.2.13

发布于 2024-09-10 05:00:04 字数 331 浏览 11 评论 0原文

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

我使用 json_decode 和 json_encode 来存储和检索数据。我发现,json 总是需要 utf-8。那里没问题。我用 utf-8 给出 json 'hello',在我的数据库中它看起来像 hello00f6。好的,代码点。但是当我使用 json_decode 时,它不会将代码点解码回来,所以我仍然有 hello00f6。 另外,在 php 5.2.13 中,JSON 中似乎仍然没有可选标签。如何将代码点字符转换回正确的特殊字符以在浏览器中显示?

问候并感

谢梅尼

I'm getting crazy over these encoding probs...

I use json_decode and json_encode to store and retrieve data. What I did find out is, that json always needs utf-8. No problem there. I give json 'hellö' in utf-8, in my DB it looks like hellu00f6. Ok, codepoint. But when I use json_decode, it won't decode the codepoint back, so I still have hellu00f6.
Also, in php 5.2.13 it seems like there are still no optionial tags in JSON. How can I convert the codepoint caracters back to the correct specialcharacter for display in the browser?

Greetz and thanks

Maenny

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

朦胧时间 2024-09-17 05:00:05

这可能是因为 JSON unicode 字符串中代码点前面的反斜杠:ö 表示为 \u00f6。当存储在数据库中时,DBMS 不知道如何解释 \u00f6 因此我猜它会将其读取(并存储)为 u00f6

您使用转义函数吗?

尝试在 unicode 转义字符上添加反斜杠:

$json = str_replace("\\u", "\\\\u", $json);

It could be because of the backslash preceding the codepoint in the JSON unicode string: ö is represented \u00f6. When stored in your DB, the DBMS doesn't knows how to interpret \u00f6 so I guess it reads (and store) it as u00f6.

Are you using an escaping function ?

Try adding a backslash on unicode-escaped chars:

$json = str_replace("\\u", "\\\\u", $json);
羁客 2024-09-17 05:00:05

前面的文章已经解释了为什么您的示例没有按预期工作。
然而,在使用数据库时有一些好的编码实践,这对于提高应用程序的安全性(即防止 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 注入。

The preceding post already explains, why your example did not work as expected.
However, there are some good coding practices when working with databases, which are important to improve the security of your application (i.e. prevent SQL-injection).

The following example intends to show some of these practices, and assumes PHP 5.2 and MySQL 5.1. (Note that all files and database entries are stored using UTF-8 encoding.)

The database used in this example is called test, and the table was created as follows:

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 

(Note that the encoding is set to utf8_bin.)

It follows the php code, which is used for both, adding new entries and creating 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);
}
?>

Note the usage of the method $conn->quote(..) before passing data to the database. As mentioned in the preceding post, it would even be better to use prepared statements, since they already do the whole escaping. Thus, it would be better if we write:

$prepStmt = $conn->prepare('INSERT INTO `entries` (`data`) VALUES (:data)');
if($prepStmt->execute(array('data'=>$_GET['add_entry']))) {...}

instead of

$data = $conn->quote($_GET['add_entry']);
if($conn->exec('INSERT INTO `entries` (`data`) VALUES ('.$data.')')) {...}

Conclusion: Using UTF-8 for all character data stored or transmitted to the user is reasonable. It makes the development of internationalized web applications way easier. To make sure, user-input is properly sent to the database, using an escape function is a good idea. Otherwise, using prepared statements make life and development even easier and furthermore improves your applications security, since SQL-Injection is prevented.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文