Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

json_decode: 'Syntax error' for valid JSON from HEREDOC string

Tags:

json

php

heredoc

I have the JSON code below. According to one or two JSON validators it is valid JSON.


{
  "patterns": {
    "email": "/[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,}/i",
    "phone": "/(?:(?:\\(?(?:0(?:0|11)\\)?[\\s-]?\\(?|\\+)44\\)?[\\s-]?(?:\\(?0\\)?[\\s-]?)?)|(?:\\(?0))(?:(?:\\d{5}\\)?[\\s-]?\\d{4,5})|(?:\\d{4}\\)?[\\s-]?(?:\\d{5}|\\d{3}[\\s-]?\\d{3}))|(?:\\d{3}\\)?[\\s-]?\\d{3}[\\s-]?\\d{3,4})|(?:\\d{2}\\)?[\\s-]?\\d{4}[\\s-]?\\d{4}))(?:[\\s-]?(?:x|ext\\.?|\\#)\\d{3,4})?/"
  }
}

However, when I try to decode using in PHP using the json_decode function I get a 'Syntax Error'. Here's my PHP code:

const JSON_CONFIG = <<<JSON
{
  "patterns": {
    "email": "/[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,}/i",
    "phone": "/(?:(?:\\(?(?:0(?:0|11)\\)?[\\s-]?\\(?|\\+)44\\)?[\\s-]?(?:\\(?0\\)?[\\s-]?)?)|(?:\\(?0))(?:(?:\\d{5}\\)?[\\s-]?\\d{4,5})|(?:\\d{4}\\)?[\\s-]?(?:\\d{5}|\\d{3}[\\s-]?\\d{3}))|(?:\\d{3}\\)?[\\s-]?\\d{3}[\\s-]?\\d{3,4})|(?:\\d{2}\\)?[\\s-]?\\d{4}[\\s-]?\\d{4}))(?:[\\s-]?(?:x|ext\\.?|\\#)\\d{3,4})?/"
  }
}
JSON;

$config = json_decode(mb_convert_encoding(JSON_CONFIG, "UTF-8"), true); // Tried called trim but it made no difference
echo 'json_last_error_msg() => ' . json_last_error_msg() . PHP_EOL;
print_r($config); // Doesn't get to run

Try for yourself: https://repl.it/@DanStevens/PHP-jsondecode-Syntax-Error

Any ideas what json_decode isn't liking this valid JSON? Is it related to the use of HEREDOC?

like image 820
Dan Stevens Avatar asked Oct 28 '25 07:10

Dan Stevens


1 Answers

The backslashes are acting as PHP escape sequences, not JSON escape sequences. To prevent PHP escaping, surround your heredoc start token in single quotes:

const JSON_CONFIG = <<<'JSON'
{
  "patterns": {
    "email": "/[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,}/i",
    "phone": "/(?:(?:\\(?(?:0(?:0|11)\\)?[\\s-]?\\(?|\\+)44\\)?[\\s-]?(?:\\(?0\\)?[\\s-]?)?)|(?:\\(?0))(?:(?:\\d{5}\\)?[\\s-]?\\d{4,5})|(?:\\d{4}\\)?[\\s-]?(?:\\d{5}|\\d{3}[\\s-]?\\d{3}))|(?:\\d{3}\\)?[\\s-]?\\d{3}[\\s-]?\\d{3,4})|(?:\\d{2}\\)?[\\s-]?\\d{4}[\\s-]?\\d{4}))(?:[\\s-]?(?:x|ext\\.?|\\#)\\d{3,4})?/"
  }
}
JSON;

var_dump(JSON_CONFIG);
echo PHP_EOL;

$config = json_decode(mb_convert_encoding(JSON_CONFIG, "UTF-8"), true); // Tried called trim but it made no difference
echo 'json_last_error_msg() => ' . json_last_error_msg() . PHP_EOL;
echo 'json_last_error() => ' . json_last_error() . PHP_EOL;
print_r($config);

Repl: https://repl.it/repls/AmusedOvercookedEmbed

like image 70
Zenexer Avatar answered Oct 31 '25 01:10

Zenexer