j.json
その内容が有効なjsonに従っているファイルを考え てみましょう。
{
"t": "\\"
}
PHPjson_encodeはそれを解析できません:
$r=json_decode(file_get_contents('j.json'));
var_dump($r); //returns null
注:質問はクリーンアップされ、問題は同じです。
あなたはこれを必要とします:
<?php
json_decode('{
"target": "^http://(www|corail)\\\\.sudoc\\\\.abes\\\\.fr"
}')
あなたは一度だけsを脱出しまし\\
た。2回必要です。1回目はPHP用で、2回目はJSON用です。
PS JSONの文字列はRegExpのように見えるため、エスケープをもう一度行う必要がある場合があります。つまり、バックスラッシュの数をもう一度2倍にする必要があります。
何が起こっているのかを視覚化してみましょう。まずPHPで、次のように文字列を記述します。
$s='{"a":"^http://(www|corail)\\\\\\\\.sudoc\\\\\\\\.abes\\\\\\\\.fr"}'
この後、あなたecho $s
がこれを見つけるならば:
{"a":"^http://(www|corail)\\\\.sudoc\\\\.abes\\\\.fr"}
次に、あなたの場合json_decode($s)
、メンバーa
はコンテンツを持っています:
^http://(www|corail)\\.sudoc\\.abes\\.fr
最後に、RegExpを実行すると、\\
はさらにエスケープされ\
ます。
試してみると:
<?php
echo '{
"target": "^http://(www|corail)\\.sudoc\\.abes\\.fr"
}';
出力は次のとおりです。
{
"target": "^http://(www|corail)\.sudoc\.abes\.fr"
}
何が悪いのか分かりますか?JSON(JavaScript)では、有効なエスケープシーケンスではないため\.
、有効なJSONではないため、json_decode
失敗して、を返しNULL
ます。
試してみると:
<?php
echo '{
"target": "^http://(www|corail)\\\\.sudoc\\\\.abes\\\\.fr"
}';
出力は次のとおりです。
{
"target": "^http://(www|corail)\\.sudoc\\.abes\\.fr"
}
エスケープシーケンス\\
はJSONに有効です。
<?php
echo var_export(json_encode((object)array('target'=>'^http://(www|corail)\\.sudoc\\.abes\\.fr')));
echo '<br/>';
echo '{
"target": "^http://(www|corail)\\.sudoc\\.abes\\.fr"
}';
ここで行ったことは、オブジェクトをPHPで手動で記述し、JSONにエンコードしてから「エクスポート」して、PHP文字列として表示することです。
それから私はそれをあなたのひもと比較しました。
結果は次のとおりです。
'{"target":"^http:\\/\\/(www|corail)\\\\.sudoc\\\\.abes\\\\.fr"}'
{ "target": "^http://(www|corail)\.sudoc\.abes\.fr" }
文字列が一部の文字を見逃していることがはっきりとわかります。すべての円記号と円記号をエスケープする必要があります。
試す
json_decode('{
"target": "^http://(www|corail)\\\\.sudoc\\\\.abes\\\\.fr"
}');
余分なコンマがあり、バックスラッシュを2回エスケープする必要があります(最初はphp文字列、次にjson)。
echo "\\"; // outputs "\"
echo "\\\\"; // outputs "\\", ie what you need for the json
問題は明らかに脱出についてです。PHPでJSONがどのように解析されるかについては、いくつかの議論があるようです(マニュアルhttp://php.net/manual/en/function.json-decode.phpのコメントを参照してください)。
とにかく、この「フィドル」 http://codepad.viper-7.com/2t4pP0からわかるように、バックスラッシュの追加を開始する必要があります。
それはこれを行います:
<?php
$r=json_decode('{"t": "a"}');
var_dump($r);
echo "<br/>\n";
$r=json_decode('{"t": "\a"}');
var_dump($r);
echo "<br/>\n";
$r=json_decode('{"t": "\\a"}');
var_dump($r);
echo "<br/>\n";
$r=json_decode('{"t": "\\\a"}');
var_dump($r);
echo "<br/>\n";
$r=json_decode('{"t": "\\\\a"}');
var_dump($r);
および出力
object(stdClass)#1 (1) { ["t"]=> string(1) "a" }
NULL
NULL
object(stdClass)#1 (1) { ["t"]=> string(2) "\a" }
object(stdClass)#2 (1) { ["t"]=> string(2) "\a" }
今、あなたが達成しようとしていることに応じて(あなたの質問の現在の編集では言及された目標はありません)、あなたはこれをどうするかを理解することができるはずですか?
残念ながら json_decode
、実装が正しくなく、有効なjsonファイルを取得したり、値を変更したりするとnullが返される場合があります。次の関数を使用して、すべての有効なjson文字列をデコードできます。
function r_json_decode($jsonString,$originalJsonValue=false){
$j=($originalJsonValue)?str_replace('\\','\\\\\\\\',$jsonString):str_replace('\\','\\\\',$jsonString);
return json_decode($j);
}
echo(r_json_decode(file_get_contents('j.json'))->t); // prints "/"
echo(r_json_decode(file_get_contents('j.json'),true)->t); //prints "//"