PHP how to stringify array and store in cookie [duplicate] - php

This question already has answers here:
Storing PHP arrays in cookies
(9 answers)
Closed 1 year ago.
I got an array like this
$value = {array('id'=>$id, 'email'=>$email, 'token'=>$token)}
I want to stringify the array then encode then store it in cookie "login". How do you do that ? Also please tell me how to decode and read the stored value.
Edit:
I've been trying serialize/unserialize, but it didn't work as expected. for example,
$value = serialize(array('id'=>33, 'email'=>'big#gmail.com', 'token'=>'e9aa0966773d68e0fbf9cb21fc2877b4'));
echo $value; //a:3:{s:2:"id";i:33;s:5:"email";s:20:"big#gmail.com";s:5:"token";s:32:"e9aa0966773d68e0fbf9cb21fc2877b4";}
But when the value go to cookie, it looks like this
a%3A3%3A%7Bs%3A2%3A%22id%22%3Bs%3A1%3A%226%22%3Bs%3A5%3A%22email%22%3Bs%3A20%3A%22craigcosmo%40gmail.com%22%3Bs%3A5%3A%22token%22%3Bs%3A32%3A%22e9aa0966773d68e0fbf9cb21fc2877b4%22%3B%7D

json_encode/json_decode
$_COOKIE['login'] = json_encode($array);
$array = json_decode($_COOKIE['login']);
Can also use serialize/unserialize:
$_COOKIE['login'] = serialize($array);
$array = unserialize($_COOKIE['login']);
Perhaps.
UPDATE
With this code:
<html><body><pre><?php
$array = Array(
'id' => 1234,
'email' => 'example#example.com',
'token' => base64_encode('abcDEF1234')
);
echo "Var Dump (initial):\r\n";
var_dump($array);
$serialized = serialize($array);
echo "Serialized:\r\n".$serialized."\r\n";
$unserialized = unserialize($serialized);
echo "Unserialized:\r\n".$unserailized."\r\n";
var_dump($unserialized);
?></pre></body></html>
You would generate the following:
Var Dump (initial):
array(3) {
["id"]=>
int(1234)
["email"]=>
string(19) "example#example.com"
["token"]=>
string(16) "YWJjREVGMTIzNA=="
}
Serialized:
a:3:{s:2:"id";i:1234;s:5:"email";s:19:"example#example.com";s:5:"token";s:16:"YWJjREVGMTIzNA==";}
Unserialized:
array(3) {
["id"]=>
int(1234)
["email"]=>
string(19) "example#example.com"
["token"]=>
string(16) "YWJjREVGMTIzNA=="
}
EDIT2
You're seeing the encoded value based on how the HTTP protocol transfers cookies. There are two headers in a cookie transfer: Set-Cookie & Cookie. One is server->client, other other is client->server, respectfully.
When PHP sets the cookie (using setcookie e.g.) PHP is really just short-handing the following:
setcookie('login',$serialized);
which, in PHP translates to:
header('Set-Cookie: login='.urlencode($serialized).'; '
.'expires=Wed, 12-Jan-2011 13:15:00 GMT; '
.'path=/; domain=.mydomain.com');
If you had characters like : or a SPACE, the browser wouldn't know where the cookie's properties began and ended.

NEVER EVER USE serialize with User input! serialize calls __wakeup and is a big security vulnerability, because you can execute code on the server. (Now the rules before you break 'em)
there is a serialize/unserialize function to convert an array to a string and back.
Edit:
When you store a string to cookie (setcookie), php needs to do a url encode on the string. This prevents any characters in the string saved to cookie interfering with any other headers. When the page is loaded next, php gets the cookie and automatically does a url decode on the cookie value to return it to it's previous value. As far as what is stored in the cookie, this shouldn't matter within php because php will do the url encode/decode automatically. Now if you are getting the cookie in another language such as javascript, then yes, you will get the raw string back. In this case you can use something like decodeURI in JS to get the original value back.

Related

How to get the value of a $_POST, if it is an array in PHP?

Let's say I have an array of emails
['email1', 'email2'...'email(n)'];
submitted to a form,
How do I store this values into a variable,
ie,
$emails = $_POST['emails'];
but this does not work as it sees the value ($emails) as a string rather than an array.
I have also tried
$emailsArray = explode(' ', $emails);
while the $emailsArray is of type array , it fails cause it groups all elements as a single string
Remember the email is dynamic and cannot be predicted its length.
You are receiving a JSON string, you need to decode it like this:
$emails = json_decode($_POST['emails']);
Here is the documentation .
I'm not a 100% clear how you send the array, but if you use var_dump($_POST) you should be able to see the contents of $_POST.
The output should be something like this:
array(3) {
[1]=>
string(6) "email1"
[2]=>
string(6) "email2"
[3]=>
string(6) "email3"
}
The key to use is in the []. So in this case you would use $_POST[1] to get "email1". If you don't understand you could send the output of var_dump($_POST), or send the code from which you send the array.
EDIT: Mehdi just asked the same question, and apparrently your question is how you can convert a string to an array.
There is probably already an answer for that somewhere, but here is a way to do it:
$array = explode(',', trim($_POST['emails'], "[]"));
It basically removes the [] brackets (with trim), then cuts the string into pieces divided by the commas (with explode). You still have the ' quotation marks to handle, but with what I've given you you should be able to figure out how to do that on your own.
EDIT2: Or you could just use json_decode like the answer of Mehdi...

Access Json Object PHP (String Not Array)

Yes, I have read previous questions and I know how to access a JSON object and how to convert it into an array. I know about json_encode/decode. My problem is that my JSON response has a string, arrays and all and it will always return NULL when I access the data directly.
object(Unirest\Response)#8 (4) {
["code"]=>
int(200)
["body"]=>
string(666) "{ "ticker": "AAPL:US", ".."
["headers"]=>
array(9) {
[0]=>
string(15) "HTTP/1.1 200 OK"
Normally you would be able to directly access the object like this and this worked just fine when I last accessed the script a few days ago:
$response->body->ticker
Or you could use json_decode with true to turn it into an array.
$array = json_decode($response->body, true);
However, all of this no longer works. I believe they changed something with the output because it was working just a while ago but I have no clue. Any idea how to access the ticker data? I tested it with a different API and the same commands are working just fine to retrieve data from a different API, but the output seems to be different.
$response->body is a json string assuming you didnt shorten it so much as to loose someting important and therefore needs to be seperately converted to a PHP data item.
As its a json string representing an object why not convert it to a PHP object like so
$body = json_decode($response->body);
Then you can address its properties like
$body->ticker
Alternatively
$response->body = json_decode($response->body);
Now you can address it as you expected i.e.
$response->body->ticker
Ok, finally solved it after reading this answer:
PHP json_decode() returns NULL with valid JSON?
Apparently, as I assumed earlier it was a formatting issue. I did not know that JSON would return NULL if the object includes non-UTF8 code and/or BOM codes.
I couldn't find any BOM codes but I suppose there was some non-UTF8 that was breaking it.
Long story short this works:
$dec = json_decode( preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $response->body), true );
echo $dec['ticker'];
Well at least I now know a lot more about JSON which will come in handy some day ;)

Is it legal for a cookie value to be an array?

I always assumed that cookies may only hold strings, but the way PHP handles cookies, it is also possible to store an array in a cookie (and I'm not talking about serialized array, but a native array). All you need to do is this:
setcookie('a[1]', 'a');
setcookie('a[2]', 'b');
var_dump($_COOKIE);
The above will produce the following (remember to execute it twice):
array(1) {
["a"]=>
array(2) {
[1]=>
string(1) "a"
[2]=>
string(1) "b"
}
}
What's going on here? Clearly we managed to store an array to a cookie, which is supposed to hold strings only. Is this a bug?
It is certainly not a bug. As a matter of fact it is documented in PHP Documentation
You may also set array cookies by using array notation in the cookie name. This has the effect of setting as many cookies as you have array elements, but when the cookie is received by your script, the values are all placed in an array with the cookie's name:
A cookie value can only be a string.
When PHP parses the cookies into $_COOKIE, certain naming conventions (i.e. cookies with names that end in [] or [something]) will cause it to represent them as an array.

$_GET Breaks XML

I'm using the SimpleViewer flash image gallery on a site, and it uses an XML file for information about the images it displays.
For the site, I need to dynamically generate the XML, so I'm using a PHP file with a text/xml Content-type declared. However, for some reason when I access one of the GET variables in the $_GET array SimpleViewer tells me that there are no images in the gallery, even though when I view the source it looks the exact same and is well-formed.
Here's the code:
$photos = array(
"1" => array("house1_1.JPG")
);
foreach($photos[$_GET["hid"]] as $p){
echo '';
}
If I replace $_GET["hid"] with "1" then it works fine, but when I make the reference to $_GET it returns the error.
Is there some reason as to why accessing a GET variable would cause scripts linking to the XML (the SimpleViewer flash) to malfunction, and is there a way to get around this?
*Note: The "hid" GET variable is 100% sure set to "1", and there is no PHP error.
Also, the output looks exactly the same for when I use $_GET["hid"] versus "1", the only difference is the SimpleViewer script refuses to see that the images are there.
Also, the stuff in the empty quotes is some XML, but I don't know how to get it to appear in the tags...
Var dump of $photos and $_GET, respectively:
array(1) {
[1]=>
array(1) {
[0]=>
string(12) "house1_1.JPG"
}
}
array(1) {
["hid"]=>
string(1) "1"
}
I would first check and make sure $_GET["hid"] is returning "1". If it's possible that it is not returning "1" then it should throw an error accessing a bad index of $photos.
Is the $_GET hid variable set in your request? If not this will trigger a PHP warning.
var_dump($_GET['hid']); to see the value of the $_GET variable and ensure it as you expect.
Also please ensure that you have error reporting set to at least E_ALL and display errors is set to yes/true to make your debugging easier.
I think you're probably having an issue with the difference between "1" and 1. When you use a get with something like ?hid=1, it's not coming through as a string, that's being converted to a number, whereas your actual array is using the string "1" as the key.
Either change your key to 1 instead of "1" or cast the hid to string.
Issue was never resolved -- I ended up having to just move on and go for a longer and less elegant solution. Oh well.

Is it possible to pass an array as a command line argument to a PHP script?

I'm maintaining a PHP library that is responsible for fetching and storing incoming data (POST, GET, command line arguments, etc). I've just fixed a bug that would not allow it to fetch array variables from POST and GET and I'm wondering whether this is also applicable to the part that deals with the command line.
Can you pass an array as a command line argument to PHP?
Directly not, all arguments passed in command line are strings, but you can use query string as one argument to pass all variables with their names:
php myscript.php a[]=1&a[]=2.2&a[b]=c
<?php
parse_str($argv[1]);
var_dump($a);
?>
/*
array(3) {
[0]=> string(1) "1"
[1]=> string(3) "2.2"
["b"]=>string(1) "c"
}
*/
Strictly speaking, no. However you could pass a serialized (either using PHP's serialize() and unserialize() or using json) array as an argument, so long as the script deserializes it.
something like
php MyScript.php "{'colors':{'red','blue','yellow'},'fruits':{'apple','pear','banana'}}"
I dont think this is ideal however, I'd suggest you think of a different way of tackling whatever problem you're trying to address.
As it was said you can use serialize to pass arrays and other data to command line.
shell_exec('php myScript.php '.escapeshellarg(serialize($myArray)));
And in myScript.php:
$myArray = unserialize($argv[1]);
In case, if you are executing command line script with arguments through code then the best thing is to base encode it -
base64_encode(json_encode($arr));
while sending and decode it while receiving in other script.
json_decode(base64_decode($argv[1]));
That will also solve the issue of json receiving without quotes around the keys and values. Because without quotes, it is considered to be as bad json and you will not be able to decode that.
The following code block will do it passing the array as a set of comma separated values:
<?php
$i_array = explode(',',$argv[1]);
var_dump($i_array);
?>
OUTPUT:
php ./array_play.php 1,2,3
array(3) {
[0]=>
string(1) "1"
[1]=>
string(1) "2"
[2]=>
string(1) "3"
}
You need to figure out some way of encoding your array as a string. Then you can pass this string to PHP CLI as a command line argument and later decode that string.
After following the set of instructions below you can make a call like this:
phpcl yourscript.php _GET='{ "key1": "val1", "key2": "val2" }'
To get this working you need code to execute before the script being called. I use a bash shell on linux and in my .bashrc file I set the command line interface to make the php ini flag auto_prepend_file load my command line bootstrap file (this file should be found somewhere in your php_include_path):
alias phpcl='php -d auto_prepend_file="system/bootstrap/command_line.php"'
This means that each call from the command line will execute this file before running the script that you call. auto_prepend_file is a great way to bootstrap your system, I use it in my standard php.ini to set my final exception and error handlers at a system level. Setting this command line auto_prepend_file overrides my normal setting and I choose to just handle command line arguments so that I can set $_GET or $_POST. Here is the file I prepend:
<?php
// Parse the variables given to a command line script as Query Strings of JSON.
// Variables can be passed as separate arguments or as part of a query string:
// _GET='{ "key1": "val1", "key2": "val2" }' foo='"bar"'
// OR
// _GET='{ "key1": "val1", "key2": "val2" }'\&foo='"bar"'
if ($argc > 1)
{
$parsedArgs = array();
for ($i = 1; $i < $argc; $i++)
{
parse_str($argv[$i], $parsedArgs[$i]);
}
foreach ($parsedArgs as $arg)
{
foreach ($arg as $key => $val)
{
// Set the global variable of name $key to the json decoded value.
$$key = json_decode($val, true);
}
}
unset($parsedArgs);
}
?>
It loops through all arguments passed and sets global variables using variable variables (note the $$). The manual page does say that variable variables doesn't work with superglobals, but it seems to work for me with $_GET (I'm guessing it works with POST too). I choose to pass the values in as JSON. The return value of json_decode will be NULL on error, you should do error checking on the decode if you need it.
Sort of.
If you pass something like this:
$php script.php --opt1={'element1':'value1','element2':'value2'}
You get this in the opt1 argument:
Array(
[0] => 'element1:value1'
[1] => 'element2:value2'
)
so you can convert that using this snippet:
foreach($opt1 as $element){
$element = explode(':', $element);
$real_opt1[$element[0]] = $element[1];
}
which turns it into this:
Array(
[element1] => 'value1'
[element2] => 'value2'
)
So if a CLI is as such
php path\to\script.php param1=no+array param2[]=is+array param2[]=of+two
Then the function thats reads this can be
function getArguments($args){
unset($args[0]); //remove the path to script variable
$string = implode('&',$args);
parse_str($string, $params);
return $params;
}
This would give you
Array
(
[param1] => no array
[param2] => Array
(
[0] => is array
[1] => of two
)
)

Categories