Cookie Value not available, why? - php

I have tested this on my development computer, but now I have uploaded everything to the production server and I cant read out the value of the cookie.
I think the problem lies in the Serialization and Unserialization.
if (isset($_COOKIE['watched_ads'])){
$expir = time()+1728000; //20 days
$ad_arr = unserialize($_COOKIE['watched_ads']); // HERE IS THE PROBLEM
$arr_elem = count($ad_arr);
if (in_array($ad_id, $ad_arr) == FALSE){
if ($arr_elem>10){
array_shift($ad_arr);
}
$ad_arr[]=$ad_id;
setcookie('watched_ads', serialize($ad_arr), $expir, '/');
}
}
When I echo this: count($ad_arr) I receive the expected nr, 1 in this case, so there is a value there. But when I echo the value: echo $ad_arr[0]; I get nothing. Completely blank. No text at all.
Anybody have a clue?
if you need more info about something let me know...

Turns out it was stripslashes which was needed here.
Did a stripslashes() first and it worked unserializing the cookie.

You should understand that count returns 1 for most non-array values, including an empty string.
> php
<?php
echo count("");
^Z
1
So, to debug it, try var_dump'ing the $_COOKIE superglobal itself.

I would guess, that your $ad_arr is no array. You can check this with the "is_array()" function or by calling:
var_dump($ad_arr);
It sould have "array" in the output and not "string" (as Artefacto just already mentioned).
Another little tip:
If you want to store a associative array, you can use an encoded JSON String which use can save using the json_encode() gunction:
setcookie('watched_ads', json_encode($ad_arr), $expir, '/');
And loading the data you can use the opposite function json_decode():
$ad_arr = json_decode($_COOKIE['watched_ads'], true);
Adding true as a second paramter, you will get a associative array and not an object. Using the JSON format is also a good idea saving complex data within a database.
A and a last tip: "!in_array()" works just as fine as "in_array() == FALSE"

Related

json_encode Returning a PHP Array

So I am working with PHP to pass a PHP array over a jQuery Ajax request to another PHP page. This is quite the task. For some reason, my json_encode is returning an array instead of a string, I am not quite sure why. Here is my PHP code:
$new_spreadsheet = nl2br($_POST['spreadsheet']);
$new_spreadsheet = explode('<br />', $new_spreadsheet);
array_shift($new_spreadsheet);
$new_spreadsheet = array_values($new_spreadsheet);
echo json_encode($new_spreadsheet);
I would show you the output, but it is really long. Basically this is outputting a PHP array which consists of each row on the spreadsheet. This is what I want to have, but the problem is that I don't want the quotes and everything in the array. I am pretty sure I need to run json_decode, but when I do that my code returns an error saying that the parameter needs to be a string. I can tell something is not right, but am not quite sure what I need to change. I would appreciate any advice.
Update: At this point, when I try to loop through the array and print each value, the first array index is equal to a double quote like so: ". There are double quotes in random values throughout the area. I am not quite sure about what is causing this.
If I echo the rows from within the json_encoded PHP array onto the console, I get the following output:
"
correct value
correct value
correct value
"
You're using JSON, which means you have to adhere to somewhat more stringent syntax rules than Javascript's. e.g.
<?php
$arr = array('This' => 'is', 'an' => 'array in php');
echo json_encode($array);
?>
output:
{"This":"is","an":"array in PHP"}
There is NO way to avoid getting quotes on the values, as they're a fundamental requirement of JSON (and Javascript). If you don't want quotes, then don't use JSON.
try only br.
$new_spreadsheet = explode("<br>", $new_spreadsheet);
It will work. and json_enode can never return an array. try var_dump and check.Also make sure before you post, use htmlspecialcharacters.

Convert key-value JSON to object and refer individual values directly

I am making a web app. In one part of it, I have JS send a string(in json format) to PHP.
The value php receives is:
{"date":"24-03-2014","Cars":["Cheap","Expensive"]}
Now, this is saved in a variable $meta. The problem I am facing is, as to how do I convert this string into an object and reference each individual entry separately.
I have tried json_decode and json_encode
and then I have referenced each variable using $meta.["date"] and $meta.date but nothing seams to work. I am getting just { as the output.
What's the correct way to do this?
$str = '{"date":"24-03-2014","Cars":["Cheap","Expensive"]}';
$obj = json_decode($str);
echo $obj->date;
// 24-03-2014
Usually a $my_obj = json_decode($_POST['jsonstring'], 1); (true supply means it'll be returned as an assoviative array) should be the way to go. If I were you I'd probably try a var_dump($my_obj); to see what actually comes through. If it doesn't work you'll want to make sure that you correctly submit a valid json string, e.g. JSON.stringify();
You should check out the PHP doc page for json_decode here.
By default, unless you pass true as the second parameter for json_decode, the function call will return an object, which you can access the members of by using:
$meta->date
The arrow operator will allow you to access object values, not the square brackets or a dot.

Variable in $_POST returns as string instead of array

In my form i have fields with name photoid[] so that when sent they will automatically be in an array when php accesses them.
The script has been working fine for quite some time until a couple days ago. And as far as i can remember i havent changed any php settings in the ini file and havent changed the script at all.
when i try to retrieve the array using $_POST['photoid'] it returns a string with the contents 'ARRAY', but if i access it using $_REQUEST['photoid'] it returns it correctly as an array. Is there some php setting that would make this occur? As i said i dont remember changing any php settings lately to cause this but i might be mistaken, or is there something else i am missing.
I had the same problem. When I should recieve array via $_POST, but var_dump sad: 'string(5) "Array"'. I found this happens, when you try use trim() on that array!
Double check your code, be sure you're not doing anything else with $_POST!
Raise your error_reporting level to find any potential source. It's most likely that you are just using it wrong in your code. But it's also possible that your $_POST array was mangled, but $_REQUEST left untouched.
// for example an escaping feature like this might bork it
$_POST = array_map("htmlentities", $_POST);
// your case looks like "strtoupper" even
To determine if your $_POST array really just contains a string where you expected an array, execute following at the beginning of your script:
var_dump($_POST);
And following for a comparison:
var_dump(array_diff($_REQUEST, $_POST));
Then verifiy that you are really using foreach on both arrays:
foreach ($_POST["photoid"] as $id) { print $id; }
If you use an array in a string context then you'll get "Array". Use it in an array context instead.
$arr = Array('foo', 42);
echo $arr."\n";
echo $arr[0]."\n";
​
Array
foo
$_POST['photoid'] is still an array. Just assign it to a variable, and then treat it like an array. ie: $array = $_POST['photoid'];
echo $array[0];

Erratic behaviour when comparing PHP imploded arrays with form field values using JavaScript

I've got a PHP Object, whose properties are initialized the following way:
$this->contact = implode(PHP_EOL,$description->getContact()) . PHP_EOL;
The only exceptions are two properties named version and bugs.
This object is then encoded into a JSON object and passed into the following javascript, which compare the JSON object with value from a form.
function compareEntry(data){
var dataProperties = ["version", "bugs", "scenario", "exception", "instruction", "sources", "risks", "test", "contact"];
var hasChanged = false;
for(var i = 0; i < dataProperties.length; i++){
var dataProperty = dataProperties[i];
alert("Original: '" + data[dataProperty] + "'\nModified: '" + document.myform[dataProperty].value + "'\nTest Value: " + (!data[dataProperty].localeCompare(document.myform[dataProperty].value)));
if(!data[dataProperty].localeCompare(document.myform[dataProperty].value)){
hasChanged = true;
}
}
[...]
In the exception of version and bugs, all other properties are compared with the value in the textarea.
The form fields are initialized with the value of the PHP object. When I submit the form the function is called. If I submit the form without changing any value, it still give me a false when comparing a property with the value of a textarea. Why and how could I correctly compare them?
Notes: The PHP Object is a reflection of a MySQL entry which was created with the same form. In between, the information was encrypted and decrypted. But it shouldn't play a role, because the PHP/JSon object and the initial value of the form are from the same source.
EDIT
After the explanation of Frode, I changed my testing statement to:
data[dataProperty].localeCompare(document.myform[dataProperty].value)!=0
But afterwards I noted two discrepencies.
Properties version and bugs which until then returned true when tested return now false. But in the contrary to the other properties, I don't manipulate the values when I'm retrieving them from the database. The value of the property version is stored in a select tag in the form.
And weirder is, when I'm changing one of the value in the textarea, instead of giving me false, it gives me true.
It occured to me that it may be due to the implementation of javascript of the browser I use. But the result I got is not quite as I expected it. Whereas, I've got the described behaviour in Firefox and Chrome, IE and Opera throw always false (with the notable exception of the comparing the version, which gave me true in IE, although he couldn't retrieve the value of the select tag).
Should I maybe use some other method to compare my strings?
EDIT 2
After taking the suggestion of WoLpH, I changed the test condition to:
data[dataProperty].trim() document.myform[dataProperty].trim()
Where trim() is the function described in this other question. And the result are the inverse of what I had in the first EDIT. Except for Chrome who seems to assign it's boolean in random. There seems to be something really wrong in my data in a way.
Here is an example of a JSON object as I can see it in Firefox (variable data in the code snippet).
{"version":"REL-773","bugs":"20831","scenario":"THIS IS A TEST\r\n\r\nThis is the what happens: stuffs.\r\n","exception":"N\/A\r\n","instruction":"1. First Step.\r\n2. Second Step.\r\n2. Third Step\r\nIt is longer.\r\n4. Fourth Step.\r\n5. Fifth Step.\r\n6. Sixth Step.\r\n","sources":"me\r\n","risks":"High risks as it is just for testing of the web application.\r\n","test":"1. Select an entry\r\n2. Change some data such as <HOME>\/path\/\r\n3. See if the application run as expected!\r\n","contact":"me#web.de\r\n"}
EDIT 3
Using the function escape() to escape all special characters of the two strings, I noticed that in the character %OA is written as %OD%OA in the JSON object. It made me suspect that my trimming function doesn't replace correctly the \r\n by \n. (trimming function that I added after the suggestion of the posters here.)
Here is the function I use:
if(typeof(String.prototype.trim) === "undefined")
{
String.prototype.trim = function()
{
return String(this).replace(/^\s+|\s+$/g, '').replace(/\r\n/g,"\n");
};
}
First, Disclaimer: I have the feeling that maybe this isn't the definite answer but more of a workaround. As this is the only way I could deal with this problem.
Now, since I had posted this question, I learned that client-side form validation is not enough. Not only it not enough, but in my case it is not needed as it wouldn't bring anything in the user experience to know that a value has been changed. It is much more interesting for the user to know that a value is not well formatted or just plain wrong. So I migrated the comparison check to the server side.
First I encase my PHP information in a json string, being sure to escape all the relevant characters. I first ensured that the quote symbol was escape correctly, and then I replaced characters which could be problematic by there unicode equivalent, before putting the resulting string in a hidden input of my form.
//escaping ",' and other throublesome characters properly for json
$json_string = str_replace('\'', "\\'", json_encode($objEncasing));
$json_string = str_replace(array('\\"', '\\\'', '&','<','>'), array('\\u0022', '\\\u0027', '\\u0026', '\\u003C', '\\u003E'), $json_string);
echo "<input name='json' type='hidden' value='".$json_string."' />";
One should note that the json object correspond to the information before any change are made in the form, thus why the json string is formatted in PHP. The form information is then sent through POST to a new script which will do all the necessary work.
Now first thing I do in the receiving script, is retrieve the json variable, but one should not forget to check for magic quotes:
if(get_magic_quotes_gpc()){
$json_string = stripslashes($_POST['json']);
}else{
$json_string = $_POST['json'];
}
Now to convert the json object into an array and the you can compare it to the $_POST array (with the exception of the json value):
if(!empty($json_string)){
$json_encasing = json_decode($json_string, true);
$gotChange = false;
foreach($_POST as $key => $value){
if($key != "json"){
//Compare the value, if something change set $gotChange to true
$value = stripslashes($value);
if($value != $json_encasing[$key]){
$json_encasing[$key] = $value;
$gotChange = true;
}
}
}
if($gotChange){
//Do your stuff
}
}
As I'm doing that on my Server, I don't need to anticipate several different behaviour. So my advice is, if you can help it, do your stuff server-side.
Javascript's string.localeCompare returns 0 if the strings compared are identical, and -1 or 1 otherwise. So your if clause:
if(!data[dataProperty].localeCompare(document.myform[dataProperty].value)){
hasChanged = true;
}
.. will in fact set hasChanged to true when the strings are equal. Try removing the ! and see if it behaves as you expect.

outputting all array values to file with php

Im working with a foreign API and im trying to get a fix on what all its sending to my file with the GET method.
How can i output something like print_r($_GET) to a file so i can read what all its sending?
If you have a hash, both of the listen solutions won't give you the keys. So here's a way to get your output formatted by print_r:
$var = print_r($your_array, 1);
file_put_contents("your_file.txt",$var);
The second option of print_r is boolean, and when set to true, captures the output.
It sounds like you need a log to store the $_GET variables being submitted to your script, for debug purposes. I'd do something like this appending values to the end of the file, so the file is not overwritten every request:
file_put_contents('path_to_log.txt', print_r($_GET, true), FILE_APPEND);
Writing to a file:
You could use file_put_contents() to create the file with your output. This function will accept a string, or an array, which releases you of the burden to convert your array into a writable-format.
file_put_contents("myget.txt", $_GET);
As stated in the comments, this option isn't ideal for multidimensional arrays. However, the next solution is.
Maintaining format:
If you'd like to maintain the print_r() formatting, simply set the second parameter to true to return the value into a variable rather than outputting it immediately:
$output = print_r($_GET, true);
file_put_contents("myget.txt", $output);

Categories