Hi I have a api call that returns a string like the following, and I need to convert it in a JSON object to process.
"a:1:{s:19:\"is_featured_service\";b:0;}"
That's a serialize()d string. unserialize() it, then json_encode() it:
<?php
$string = "a:1:{s:19:\"is_featured_service\";b:0;}";
$json = json_encode(unserialize($string));
var_dump($json);
Be careful, though. Per PHP manual:
Warning Do not pass untrusted user input to unserialize() regardless
of the options value of allowed_classes. Unserialization can result in
code being loaded and executed due to object instantiation and
autoloading, and a malicious user may be able to exploit this. Use a
safe, standard data interchange format such as JSON (via json_decode()
and json_encode()) if you need to pass serialized data to the user.
Demo
serialize() reference
unserialize() reference
I am having trouble understanding the concept of serialize/unserialize in PHP.
Assume I have a very simple PHP object (class someObject) and after setting the attributes of that object I want to serialize it:
So I call: serialize($someObject);
I want to transfer this serialized object into another php skript via a html form so I set it as a hidden value:
<input type="hidden" name="someObject" value="<? print $someObject; ?>"
In the next php script I want to use unserialize to get my object back and transfer it e.g. to a databae.
$unserialize = unserialize($_POST['someObject'])
But this always returns BOOL(false) - so what am I missing here?
Thanks for your help!
A serialized string looks like this:
O:1:"a":1:{s:3:"foo";s:3:"100";}
You have tourlencode/urldecode the serialized string to prevent any characters in the serialized representation from breaking your markup. Have a look at your page source. The first quote likely ended your HTML value attribute. So you got something like:
<input ... value="O:1:"a":1:{s:3:"foo";s:3:"100";}">
So your $_POST will never contain the full serialized string, but only O:1:
If this is not the issue, make sure you got a serialized string from the object in the first place. Also please be aware that there some objects cannot be serialized or have modified behavior when (un)serialized. Please refer to the Notes in PHP Manual for serialize for details.
If you dont need to send objects across different servers running PHP, consider persisting them in a Session instead. It's easier, less error prone and more secure because the object cannot be tampered with while in transit.
You need to have the class defined in your second script before you unserialize() the object
Disclaimer: I am fairly new to using json.
I am trying to use php to receive json data from an iPAd application. I know how to convert json to an array in php, but how do I actually receive it and store it into a variable so it can be decoded?
Here are a couple examples that I have tried based on google and stackoverflow searches.
$json_request = #file_get_contents('php://input');
$array = json_decode($json_request);
AND ALSO
$array = json_decode($_POST['data'], true);
Any suggestions?
You have the basic idea already.
you should test that the value is set and also strip extra slashes from the incoming string before trying to parse it as JSON.
if(isset($_POST['data'])){
$array = json_decode(stripslashes($_POST['data']),true);
//$array now holds an associative array
}//Data Exists
It also would not be a bad idea before you start working with the array to test that the call to json_decode() was successful by ensuring that $array isn't null before use.
If you do not fully trust the integrity of the information being sent you should do extended checking along the way instead of trusting that a given key exists.
if($array){ // Or (!is_null($array)) Or (is_array($array)) could be used
//Process individual information here
//Without trust
if(isset($array['Firstname'])){
$CustomerId = $array['Firstname'];
}//Firstname exists
}//$array is valid
I in-particular like to verify information when I am building queries dynamically for information that may not be required for a successful db insert.
In the above example $_POST['data'] indicates that what ever called the PHP script did so passing the JSON string using the post method in a variable identified as data.
You could check more generically to allow flexibility in the sending method by using the $_REQUEST variable, or if you know it is coming as via the get method you can check $_GET. $_REQUEST holds all incoming parameters from both get and post.
If you don't know what the name of the variable coming in is and want to play really fast and loose you could loop over the keys in $_REQUEST trying to decode each one and use the one that successfully decoded (if any). [Note: I'm not encouraging this]
I'm storing some "unstructured" data (a keyed array) in one field of my table, and i'm currently using serialize() / unserialize() to "convert" back and forth from array to string.
Every now and then, however, I get errors when unserializing the data. I believe these errors happen because of Unicode data in the strings inside the array i'm serializing, although there are some records with Unicode data that work just fine. (DB field is UTF-8)
I'm wondering whether using json_encode instead of serialize will make a difference / make this more resilient. This is not trivial for me to test, since in my dev environment everything works well, but in production, every now and then (about 1% of records) I get an error.
Btw, I know i'm weaseling out of finding an actual explanation for the problem and just blindly trying something, I'm kind of hoping I can get rid of this without spending too much time on it.
Do you think using json_encode instead of serialize will make this more resilient to "serialization errors"? The data format does look more "forgiving" to me...
UPDATE: The actual error i'm getting is:
Notice: unserialize(): Error at offset 401 of 569 bytes in C:\blah.php on line 20
Thanks!
Daniel
JSON has one main advantage :
compatibility with other languages than PHP.
PHP's serialize has one main advantage :
it's specifically designed to store PHP-based data -- most notably, it can store serialized objects, instance of classes, that will be re-instanciated to the right class-type when the string is unserialized.
(Yes, those advantages are the exact opposite of each other)
In your case, as you are storing data that's not really structured, both formats should work pretty well.
And the encoding problem you have should not be related to serialize by itself : as long as everything (DB, connection to the DB, PHP files, ...) is in UTF-8, serialization should work too.
I think unless you absolutely need to preserve php specific types that json_encode() is the way to go for storing structured data in a single field in MySQL. Here's why:
https://dev.mysql.com/doc/refman/5.7/en/json.html
As of MySQL 5.7.8, MySQL supports a native JSON data type defined by RFC 7159 that enables efficient access to data in JSON (JavaScript Object Notation) documents
If you are using a version of MySQL that supports the new JSON data type you can benefit from that feature.
Another important point of consideration is the ability to perform changes on those JSON strings. Suppose you have a url stored in encoded strings all over your database. Wordpress users who've ever tried to migrate an existing database to a new domain name may sympathize here. If it's serialized, it's going to break things. If it's JSON you can simply run a query using REPLACE() and everything will be fine. Example:
$arr = ['url' => 'http://example.com'];
$ser = serialize($arr);
$jsn = json_encode($arr);
$ser = str_replace('http://','https://',$ser);
$jsn = str_replace('http://','https://',$jsn);
print_r(unserialize($ser));
PHP Notice: unserialize(): Error at offset 39 of 43 bytes in /root/sandbox/encoding.php on line 10
print_r(json_decode($jsn,true));
Array
(
[url] => https://example.com
)
json_encode() converts non-ASCII characters and symbols (e.g., “Schrödinger” becomes “Schr\u00f6dinger”) but serialize() does not.
Source: https://www.toptal.com/php/10-most-common-mistakes-php-programmers-make#common-mistake-6--ignoring-unicodeutf-8-issues
To leave UTF-8 characters untouched, you can use the option JSON_UNESCAPED_UNICODE as of PHP 5.4.
Source: https://stackoverflow.com/a/804089/1438029
If the problem is (and I believe it is) in UTF-8 encoding, there is not difference between json_encode and serialize. Both will leave characters encoding unchanged.
You should make sure your database/connection is properly set up for handle all UTF-8 characters or encode whole record into supported encoding before inserting to the DB.
Also please specify what "I get an error" means.
Found this in the PHP docs...
function mb_unserialize($serial_str) {
$out = preg_replace('!s:(\d+):"(.*?)";!se', "'s:'.strlen('$2').':\"$2\";'", $serial_str );
return unserialize($out);
}
I don't quite understand it, but it worked to unserialize the data that I couldn't unserialize before. Moved to JSON now, i'll report in a couple of weeks whether this solved the problem of randomly getting some records "corrupted"
As I'm going through this I'll give my opinion, both serialize and json_encode are good for storing data in DB, but for those looking for performance, I've tested and I get these results, json_encode are a little microsegunds faster tham serialize, i used this script to calculate a the difference time.
$bounced =array();
for($i=count($bounced); $i<9999; ++$i)$bounced[$i]=$i;
$timeStart = microtime(true);
var_dump(serialize ($bounced));
unserialize(serialize ($bounced));
print timer_diff($timeStart) . " sec.\n";
$timeStart = microtime(true);
var_dump(json_encode ($bounced));
json_decode(json_encode ($bounced));
print timer_diff($timeStart) . " sec.\n";
function timer_diff($timeStart)
{
return number_format(microtime(true) - $timeStart, 3);
}
As a design decision, I'd opt for storing JSON because it can only represent a data structure, whereas serialization is bound to a PHP data object signature.
The advantages I see are:
* you are forced to separate the data storage from any logic layer on top.
* you are independent from changes to the data object class (say, for example, that you want to add a field).
Some have see that code :
<?php
echo stripslashes(json_encode(glob("photos-".$_GET["folder"].'/*.jpg')));
?>
it echo a really nice perfect string like that :
["photos-animaux/ani-01.jpg","photos-animaux/ani-02.jpg","photos-animaux/ani-02b.jpg","photos-animaux/ani-03.jpg","photos-animaux/ani-04.jpg","photos-animaux/ani-05.jpg","photos-animaux/ani-06.jpg","photos-animaux/ani-07.jpg","photos-animaux/ani-08.jpg","photos-animaux/ani-09.jpg","photos-animaux/ani-10.jpg","photos-animaux/ani-11.jpg","photos-animaux/ani-12.jpg","photos-animaux/ani-13.jpg","photos-animaux/ani-14.jpg"]
With json encode it shoul send a array so variable[0] should = to photos-animaux/ani-01.jpg
NOW it is only the fisrt caracter of the string..
how a array get converted to string, and how in javascipt to convert string to array to be able to get value [0] [1] etc..
the question is WHEN or WHY the perfect array get converted to string anyway ?
Using JSON.parse(), from the library available here, is preferable to using eval() since this only reads JSON strings and hence avoids the inherant security risks associated with eval().
In order to parse a JSON-encoded string into actual javascript objects, you need to eval() the data returned in order for javascript to execute against the data:
var data = eval(json_string)
Keep in mind that you should only ever run eval on a string when you trust the source and are sure that there is no possibility of a script injection attack, since javascript will run everything present in the string.
Use one of the JSON libraries listed at the bottom of http://json.org/
WHEN or WHY
If I understood correctly, the answer to both is json_encode(): check out the documentation. Converting a variable to a string (often called serialization or flattening) is a quite common operation.