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
Related
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 want to base64_encode the parameters I send over the url.
Send:
<?php
$product = array("productID"=>"13776", "name"=>"something", "availability"=>"1000");
$url_details = "?id=" . base64_encode(http_build_query($product));
?>
Details
Receive:
<?php
$details = base64_decode($_GET["id"]);
// $product = what is the best way to reconstruct the array from $details?
?>
<p>
Name: <?php echo $products["name"]; ?>
...
</p>
The encoding destroys the array, is there a convenient way to make an associative array out of the string again?
(the encoded url is not sensitive information, but I still do not want it to be flat out readable in the url. If there is a better way to pass this data between pages than what I am doing, let me know)
parse_str is the inverse of http_build_query, so to recover your data:
parse_str(base64_decode($_GET["id"]), $details);
Note that parse_str is harmful if called with only one argument.
And as an aside, you may not want to put this kind of information into the URL to begin with, since it can be easily disclosed to third parties, via the Referrer header, for instance.
You can serialize() your array:
<?php
$product = array("productID"=>"13776", "name"=>"something", "availability"=>"1000");
$url_details = base64_encode(serialize($product));
And then, on your end page unserialize() it:
<?php
$details = unserialize(base64_decode($url_details));
Demo
However you need to be careful and do thorough checking of what you're receiving, since unserialize() will execute arbitrary code sent by the client. For example, I can serialize() my own array, then base64_encode() it, and pass it to the URL in the id parameter, and I can do pretty nasty stuff. So definitely check what you're getting in the request!
From the 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.
Here's a comprehensive article on the matter. Give it a read!
As the manual says, you can also probably accomplish what you're trying to do with json_encode() and json_decode(), though the same warning remains, check that what you're getting is what you're supposed to get and sanitize it.
I am getting JSON files but each file has a code/ID with it, in the beginning
i am trying to make a standard way to crop the strings no matter how the code/ID changes.
so these are 2 JSON files:
a:12{/*JSON DATA HERE*/}
a:130 {/*JSON DATA HERE*/}
a:1 {/*JSON DATA HERE*/}
i did not find a way to locate the first occurrence of "{" and include it in the new string that will also include the rest of the JSON string.
in JAVA it would go something like that, but i need it in php:
String myjson = "a:130{/*JSON here*/}";
String newjson = myjson.substring(myjson.indexOf("{"), myjson.length());
how can i do that in php?
This really seems to be a PHP serialized array (through serialize / unserialize) and not JSON.
PHP uses a:<count>{...} to indicate a serialized array in its format.
If you can trust the data (i.e. not user submitted but generated by a trusted application), don't parse it yourself and use unserialize instead.
The reason why you never should use unserialize on user submitted data that you can't verify independently is that it is able to create objects of a user specific selection, and if the object defines __wakeup, it might be able to coerce the object into performing any operation the attacker want. This is also why there is a large warning on the unserialize manual page.
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.
I'm trying to store a complex object here and am doing that by serialising the object running a mysql_real_escape_string on it and inserting it into a mysql database.
However when I retrieve it running a sql query - I'm using Zend frameworks Zend_DB_Table here but anyway - and when I try to stripslashes and unserialize I dont get my object back. I've tried to just unserialize without stripping slashes and all but nothings working.
UPDATE
This is weird. I made a simple page which just unserializes a serialised object. If I take the serialized string as it is retrieved from the database and unserialize it via this other page which just has an unserialize() on it - it works perfectly and I get my object back. However in the code where ironically I'm retriving the string and I run the exact same unserialize option there ,its not working!
So basically there is nothing wrong with the serialized string - for some weird reason it won't unserialize it in my application but it unserializes somewhere else, it makes no sense.
You probably need to run it through base64 encoding first:
$safe_string_to_store = base64_encode(serialize($data));
Then to get it back out:
$date = unserialize(base64_decode($safe_string_to_store));
Try that and let us know if it works.
(and dont run stripslashes on it - there is no need to)
You shouldn't run stripslashes on it - the database will give you back the right string to put into unserialize.
Make sure you have notices turned on and echo the string before you unserialize it - does it look right?
You should be able to just do the following:
Assuming MyTable is your instance of Zend_Db_Table_Abstract:
$t = new MyTable();
$n = $t->createRow();
$n->serializedfield = serialize($data);
$n->save();
and let Zend DB take care of the escaping for you.
If you're doing it via an insert(), you shouldnt need to do anything either (the above uses insert())
Otherwise use $db->quoteInto() like
$db->quoteInto('INSERT INTO mytable (serializedfield) values (?)', serialize($data));
I strongly recommend you to use json_encode instead of serialize. Some day you will find yourself trying to use that data from another place that is not PHP and having it stored in JSON makes it readable everywhere; virtually every language supports decoding JSON and is a well stablished standard. And is even worse if you base64 it, you also make the serialized content unreadable from your database console client.