Cannot parse JSON with huge value - php

In my JSON I have 4 root values. 3 of them are parsed just good. The 4th dict is not even in the result. In this dict there is a UTF-8 string with key "base64" which length is 50915 symbols.
This happens only on the server (PHP 5.3.*), on my local (PHP 5.4.4) all works fine. What the hell is going on? Is there a limit on one object size?
Code
$json = new Services_JSON(SERVICES_JSON_LOOSE_TYPE);
$result = $json->decode($var);

I think you should use json_decode instead.
As far as I know, the PEAR library to handle JSON was build because there were no proper way to handle JSON before PHP 5.1. I think you can leave this library aside and use json_* function instead.

Related

PHP - How would you catch the line at which an error is thrown when decoding a json?

I'm building a specification validator that is based on json format in a PHP environment.
At some point, I considered creating a text editor which would help users directly edit and create their json.
In order to do that, I need the catch which errors are thrown when the json cannot be output (json_decode($myjson) returns NULL).
I've tried using both json_last_error() and json_last_error_msg() builtin functions but they neither provides the granularity I need.
What I want is to actually catch which character (or at least which line) is preventing the json from being decoded so that I can highlight it in the editor.
I've read that PHP does not nativly handle this. Is there a lib that do? If not, how would you tackle that issue? Do I need to code my own json encoder/decoder? If so, would you use regex on the string to explode it into subsets of arrays before recomposing the final object? Any other idea (maybe JS natively handles json decoding errors better than PHP does? :)
Cheers,

PHP & OCI query returns NUMBER columns as STRING

I'm using PHP5 and OCI 8 with Oracle 11g.
When I fetch a row using oci_fetch_all, the whole result is converted as STRING even for the NUMBER columns and even if I use Oracle's TO_NUMBER in the query.
What I'm trying to do is simple: the javascript calls the PHP script through an Ajax request. The script just fetch some NUMBER data and encode them into JSON. I want the data to be encoded as integer, so the javascript can do math stuff on it (add, divide,..etc) without any conversion.
I am pretty sure that the problem comes from OCI and not JSON encoding because when I VAR_DUMP the result of oci_fetch_all, I can clearly see double quotes on every result:
{
"COLUMN1":"12",
"COLUMN2":"52"
}
I want the result to look like this:
{
"COLUMN1":12,
"COLUMN2":52
}
I tried to:
Change the flag of oci_fetch_all (OCI_FETCHSTATEMENT_BY_ROW, OCI_FETCHSTATEMENT_BY_COLUMN...)
Use oci_fetch_array instead of oci_fetch_all
Remove the UTF8 encoding on the connexion to oracle (I know, its stupid)
The strange thing is that I can't find any thing on the internet about this problem... It's like nobody faced the same issue. Maybe i'm doing something wrong...
Thanks in advance
You can use an extra option in json_encode:
json_encode($rows, JSON_NUMERIC_CHECK);
However this option requires a PHP version of 5.3.3 or higher (thus its ok for you).
All database extensions in PHP work like this, there's nothing you can do about it.
You'll have to manually type-cast the database results.

PHP json_decode returns null

I'm writing PHP code that uses a database. To do so, I use an array as a hash-map.
Every time content is added or removed from my DB, I save it to file.
I'm forced by my DB structure to use this method and can't use mysql or any other standard DB (School project, so structure stays as is).
I built two functions:
function saveDB($db){
$json_db = json_encode($db);
file_put_contents("wordsDB.json", $json_db);
} // saveDB
function loadDB(){
$json_db = file_get_contents("wordsDB.json");
return json_decode($json_db, true);
} // loadDB
When echo-ing the string I get after the encoding or after loading from file, I get a valid json (Tested it on a json viewer) Whenever I try to decode the string using json_decode(), I get null (Tested it with var_dump()).
The json string itself is very long (~200,000 characters, and that's just for testing).
I tried the following:
Replacing single/double-quotes with double/single-quotes (Without any backslashes, with one backslash and three backslashes. And any combination I could think of with a different number of backslashes in the original and replaced string), both manually and using str_replace().
Adding quotes before and after the json string.
Changing the page's encoding.
Decoding without saving to file (Right after encoding).
Checked for slashes and backslashes. None to be found.
Tried addslashes().
Tried using various "Escape String" variants.
json_last_error() doesn't work. I get no error number (Get null, not 0).
It's not my server, so I'm not sure what PHP version is used, and I can't upgrade/downgrade/install anything.
I believe the size has something to do with it, because small strings seem to work fine.
Thanks Everybody :)
In your JSON file change null to "null" and it will solve the problem.
Check if your file is UTF8 encoded. json_decode works with UTF8 encoded data only.
EDIT:
After I saw uploaded JSON data, I did some digging and found that there are 'null' key. Search for:
"exceeding":{"S01E01.html":{"2217":1}},null:{"S01E01.html":
Change that null to be valid property name and json_decode will do the job.
I had a similar problem last week. my json was valid according to jsonlint.com.
My json string contained a # and a & and those two made json_decode fail and return null.
by using var_dump(json_decode($myvar)) which stops right where it fails I managed to figure out where the problem was coming from.
I suggest var_dumping and using find dunction to look for these king of characters.
Just on the off chance.. and more for anyone hitting this thread rather than the OP's issue...I missed the following, someone had htmlentities($json) way above me in the call stack. Just ensure you haven't been bitten by the same and check the html source.
Kickself #124

Push JSON Encoded Data To Website in what format?

I need to push some JSON data to my website which I would like to read in PHP. What type of file should I make this? A PHP file with the JSON inside of a variable? I understand how to make a text file with JSON encoded data in it, but how do I get this into PHP? Should I use a PHP include with the JSON-encoded data in it assigned to a variable? Or should I read the file from PHP and put the contents into a variable?
Save your json string as plain text, then you can use:
$file = yourfile
$data = file_get_contents($file);
$parsed = json_decode($data);
// compacted:
$parsed = json_decode(file_get_contents($file));
See file_get_contents() and json_decode().
The advantage of doing this (versus storing it in a PHP file then including it) is that now any program or language that understands JSON can read the file.
The question is too vague for a definite "do this" answer, but here are some options and what they might be most suitable for:
Turn the json data into a PHP data structure. If this is a one-time thing (meaning you won't be getting a new json file every day or week or hour), then reading a file (file_get_contents) and parsing JSON (json_decode) for every request is a pretty big waste of resources since that data isn't changing on a regular basis. Just turn JSON key/value objects into PHP associative arrays, JSON strings into PHP strings, etc.
Just serve the json file. If this is data that will just wind up going to the client to be used in javascript anyway, there's no need to do anything special with it on the server, just parse the json on the client.
Put it in a database. This may be a little heavy-handed, but if you really need it in PHP and not just the client, and it is going to be changing or growing on a regular basis, it may be worth it to have something that handles this use case appropriately.

Is PHP serialize function compatible UTF-8?

I have a site I want to migrate from ISO to UTF-8.
I have a record in database indexed by the following primary key :
s:22:"Informations générales";
The problem is, now (with UTF-8), when I serialize the string, I get :
s:24:"Informations générales";
(notice the size of the string is now the number of bytes, not string length)
So this is not compatible with non-utf8 previous records !
Did I do something wrong ? How could I fix this ?
Thanks
The behaviour is completely correct. Two strings with different encodings will generate different byte streams, thus different serialization strings.
Dump the database in latin1.
In the command line:
sed -e 's/latin1/utf8/g' -i ./DBNAME.sql
Import the file converted to a new database in UTF-8.
Use a php script to update each field.
Make a query, loop through each field and update the serialized string using this:
$str = preg_replace('!s:(\d+):"(.*?)";!se', "'s:'.strlen('$2').':\"$2\";'", $str);
After that, I was able to use unserialize() and everything working with UTF-8.
To unserialize an utf-8 encoded serialized array:
$array = #unserialize($arrayFromDatabase);
if ($array === false) {
$array = #unserialize(utf8_decode($arrayFromDatabase)); //decode first
$array = array_map('utf8_encode', $array ); // encode the array again
}
PHP 4 and 5 do not have built-in Unicode support; I believe PHP 6 is starting to add more Unicode support although I'm not sure how complete that is.
You did nothing wrong. PHP prior to v6 just isn't Unicode aware, and as such doesn't support it, if you don't beat it to be (i.e., via the mbstring extension or other means).
We here wrote our own wrapper around serialize() to remedy this. You could, too, move to other serialization techniques, like JSON (with json_encode() and json_decode() in PHP since 5.2.0).

Categories