53

私はこのコードを試しています

$json = file_get_contents("http://www.google.com/alerts/preview?q=test&t=7&f=1&l=0&e");
print_r(json_decode(utf8_encode($json), true));

        //////////////

// Define the errors.
$constants = get_defined_constants(true);
$json_errors = array();
foreach ($constants["json"] as $name => $value) {
    if (!strncmp($name, "JSON_ERROR_", 11)) {
        $json_errors[$value] = $name;
    }
}

// Show the errors for different depths.
foreach (range(4, 3, -1) as $depth) {
    var_dump(json_decode($json, true, $depth));
    echo 'Last error: ', $json_errors[json_last_error()], PHP_EOL, PHP_EOL;
}

html_entities_decode、utf8_encode、decode、16進コードのデコードなど、多くの関数を試しましたが、常にエラー「JSON_ERROR_UTF8」が発生します。

どうすればこれを解決できますか?

4

6 に答える 6

77

配列をサニタイズするための優れた機能があります。

次のような json_encode ラッパーを使用することをお勧めします。

function safe_json_encode($value, $options = 0, $depth = 512, $utfErrorFlag = false) {
    $encoded = json_encode($value, $options, $depth);
    switch (json_last_error()) {
        case JSON_ERROR_NONE:
            return $encoded;
        case JSON_ERROR_DEPTH:
            return 'Maximum stack depth exceeded'; // or trigger_error() or throw new Exception()
        case JSON_ERROR_STATE_MISMATCH:
            return 'Underflow or the modes mismatch'; // or trigger_error() or throw new Exception()
        case JSON_ERROR_CTRL_CHAR:
            return 'Unexpected control character found';
        case JSON_ERROR_SYNTAX:
            return 'Syntax error, malformed JSON'; // or trigger_error() or throw new Exception()
        case JSON_ERROR_UTF8:
            $clean = utf8ize($value);
            if ($utfErrorFlag) {
                return 'UTF8 encoding error'; // or trigger_error() or throw new Exception()
            }
            return safe_json_encode($clean, $options, $depth, true);
        default:
            return 'Unknown error'; // or trigger_error() or throw new Exception()

    }
}

function utf8ize($mixed) {
    if (is_array($mixed)) {
        foreach ($mixed as $key => $value) {
            $mixed[$key] = utf8ize($value);
        }
    } else if (is_string ($mixed)) {
        return utf8_encode($mixed);
    }
    return $mixed;
}

私のアプリケーションでは、utf8_encode() は iconv() よりもうまく機能します

于 2014-11-05T15:32:10.100 に答える
14

入力が有効であることを保証できない限り、iconv 関数はほとんど役に立ちません。代わりに mb_convert_encoding を使用してください。

mb_convert_encoding($value, "UTF-8", "auto");

「auto」よりも明示的に取得でき、予想される入力エンコーディングのカンマ区切りのリストを指定することもできます。

最も重要なことは、(iconv とは異なり) 文字列全体が破棄されることなく、無効な文字が処理されることです。

于 2014-06-25T17:22:18.720 に答える
1

エンコーディングの問題を「解決」する特効薬はありません。使用しているエンコーディングを理解してから変換する必要があります。

コンピュータは最終的にバイナリ データを送信して保存します。そのバイナリ データを有用なものにするために、「このバイナリ文字列は「a」を表し、これは「b」を表し、このもう 1 つはビジネス スーツを着た男性が浮揚する絵文字を表す ️」というコードを考案します。 UTF-8 (少し簡略化) はこれらのエンコーディングの 1 つにすぎず、ASCII、ISO-8859-1、Windows Code Page 1252、Shift-JIS などの名前を持つエンコーディングもあります。

文字列が「UTF-8 ではない」ということだけがわかっている場合、最初の文字が「a」なのか「️」なのかがわからないため、UTF-8 にすることはできません。

文字列のエンコーディングがわかっている場合は、PHP の 3 つの関数のいずれかを使用できます。インストールされている PHP によっては、一部またはすべてが利用できない場合がありますが、それらは必要なものです。

mb_convert_encoding を使用すると、現在のエンコーディングを示す引数を省略できることに注意してください。これは正しいエンコーディングを自動的に解決するのではなく、ユーザーが制御するグローバル設定を使用するだけです。

PHP には、不適切な名前のutf8_encodeutf8_decodeという 2 つの関数が用意されています。これらは、上記の 3 つの関数の非常に限定されたバージョンです。ISO-8859-1 から UTF-8 への変換とその逆の変換のみが可能です。文字列がそのエンコーディングでない場合 (そして、エンコーディングしたくない場合) 、これらの関数は役に立ちません。エラーがなくなるかもしれませんが、それはデータを修正することと同じではありません。

于 2021-04-04T22:33:01.677 に答える