Unserialize not working for multi-dimensional array - php

So I have run into this problem many times before, but I would always get around it using base64_encode/decode and that would get it working right away.
However, in this application I cannot use that, because I need to be able to query this field and I wouldn't know how I could do that if it was encoded.
Pardon my ignorance, but is there a way to unserialize a multi-dimensional array without using base64 encoding?
Update 1
Removing the strings and turning them to integers fixes the problem. So it is either a problem with strings, or I suspect the " is causing issues. Anyway to work around that?
For this application, the second element of the array represents a date in a format that it would be searched under. Ideally, I would like to leave that as is, but if it is necessary I suppose I can use an integer to represent the number of days away from a constant, and then interpret that result.
Below is the code:
// Load Contact from Database
$returnFields = array('_AttendanceRecords');
$Contact = $app->loadCon(39732,$returnFields);
echo "<pre>";
print_r($Contact);
echo "</pre>";
echo $Contact['_AttendanceRecords'] . "</br>";
// To unserialize...
$AttendanceRecordsLoad = unserialize($Contact['_AttendanceRecords']);
echo "<pre>";
print_r($AttendanceRecordsLoad);
echo "</pre>";
Output is:
Array (
[_AttendanceRecords] => a:1:{i:0;a:3:{i:0;i:1;i:1;s:10:"10-09-2015";i:2;s:1:"1";}} )
a:1:{i:0;a:3:{i:0;i:1;i:1;s:10:"10-09-2015";i:2;s:1:"1";}}
As you can see, the final print_r comes out empty, which I believe is returning false for whatever reason.
Update 2
So after more fiddling around, I made this new code:
Code
$ContactId = 39732;
$returnFields = array('_AttendanceRecords');
$Contact = $app->loadCon($ContactId,$returnFields);
echo $Contact['_AttendanceRecords'] . " - IS result </br>";
echo $str = 'a:1:{i:0;a:3:{i:0;i:0;i:1;s:8:"10-10-15";i:2;i:1;}}'; echo " - str result </br>";
// To unserialize...
$AttendanceRecordsLoad = unserialize($Contact['_AttendanceRecords']);
$AttendanceRecordsLoad1 = unserialize($str);
echo "IS<pre>";
print_r($AttendanceRecordsLoad);
echo "</pre>";
echo "str<pre>";
print_r($AttendanceRecordsLoad1);
echo "</pre>";
Output
a:1:{i:0;a:3:{i:0;i:0;i:1;s:8:"10-10-15";i:2;i:1;}} - IS result
a:1:{i:0;a:3:{i:0;i:0;i:1;s:8:"10-10-15";i:2;i:1;}} - str result
IS
str
Array (
[0] => Array
(
[0] => 0
[1] => 10-10-15
[2] => 1
)
)
I don't understand. The strings appear identical. Yet the result that comes from the database won't unserialize if it contains a string.
Does that make sense to anyone?
Update 3
Ok, so now I used var_dump instead of echo and I get this outputted:
Output
string(61) "a:1:{i:0;a:3:{i:0;i:0;i:1;s:8:"10-10-15";i:2;i:1;}}" - IS
result
string(51) "a:1:{i:0;a:3:{i:0;i:0;i:1;s:8:"10-10-15";i:2;i:1;}}" - str result
So obviously they are not identical. But I tried trim before, and now, and it doesn't remove any hidden extra characters that somehow have lodged themselves in to this string.
What does that mean and how do I correct this?

Ok figured it out by looking at this question:
SOLUTION FOUND - Same strings, but var_dump() says one is 5 characters longer
The fix was using this on the returned result from the database:
html_entity_decode($string], ENT_QUOTES)
Hope that helps someone else too.

Related

PHP check JSON string for item = value

I need to get the value one one particular value in my json string
the json string comes from an api url http://url:port/api.php?action=reg_user&sub=list and outputs like so
[{"id":"1","username":"username1","credits":"0","group_id":"1","group_name":"Administrators","last_login":"1511883014","date_registered":"1421604973","email":"test1#my-email.com","ip":"8.8.8.8","status":"1"},{"id":"31","username":"username2","credits":"0","group_id":"1","group_name":"Administrators","last_login":"1539813642","date_registered":"1473632400","email":"test2#my-email.com","ip":"8.8.8.8","status":"1"},
i would like to check the value of credits where username = username1
then if credits > 30 do x, else do y
I presume first of all I need to decode this jason string
so i tried to do
$api_result = file_get_contents( 'http://url:port/api.php?action=reg_user&sub=list' );
$json_decode = json_decode($api_result);
echo $json_decode;
expecting this to echo the array in a nicely formatted structure, instead it just outputs the word Array. Where do I go from here?
Thanks
UPDATE 1...
SO i checked again and I defo can echo $api_result so I know that the file_get_contents is working fine i tried the two comments suggestions however both didn't work...
one of the suggestions was to make my php
$api_result = file_get_contents( 'http://url:port/api.php?action=reg_user&sub=list' );
$json_decode = json_decode($api_result);
echo $json_decode['username'];
here is a screenshot of how the echo $api_result is formatted in case this isnt a propper json string
so to me this looks like it opens with (and is all contained in a pair of [] and then each result is enclosed in {} as I'd expect with a json string right? however i thought json strings used {} and arrays used {} so to me this looks like a string inside an array???
I looked at php.net's resource on JSON DECODE and tried var_dump(json_decode($json)); which did print me this
UPDATE 2
I just tried https://www.functions-online.com/json_decode.html and pasted the data in, it was able to decode the data absolutely fine,
It then gave me a copy if the json_decode sample at the bottom but this didn't work either, returning a null value like json_decode doesn't work on my server?
From your second screenshot (please cut & paste the text instead!) you can see the decoded JSON is an array of objects with properties id, username etc. So you can access them using object notation. This code uses the snippet of your api_result from your original question to demonstrate how to do what you want:
$api_result = '[{"id":"1","username":"username1","credits":"0","group_id":"1","group_name":"Administrators","last_login":"1511883014","date_registered":"1421604973","email":"test1#my-email.com","ip":"8.8.8.8","status":"1"},{"id":"31","username":"username2","credits":"0","group_id":"1","group_name":"Administrators","last_login":"1539813642","date_registered":"1473632400","email":"test2#my-email.com","ip":"8.8.8.8","status":"1"}]';
$json = json_decode($api_result);
foreach ($json as $user) {
if ($user->username == 'username1') {
if ($user->credits > 30) {
// do x
echo "user $user->username has more than 30 credits ($user->credits)";
}
else {
// do y
echo "user $user->username has less than or equal to 30 credits ($user->credits)";
}
}
}
Output:
user username1 has less than or equal to 30 credits (0)

JSON encoding an associative array containing quotes

I have an associative array:
$contents = array();
$contents["notes"] = "this doesn't seem like it will work";
(For sake of simplicity, the above string is not actually defined in-line in my code, it is fetched from the MySQL DB)
When I do:
echo json_encode($contents, JSON_HEX_APOS);
It fails silently and I don't see any output sent to javascript.
However, if the array $contents is not associative, JSON_HEX_APOS seems to convert the quotes as it should, and json_encode works perfectly fine.
That's not a valid PHP array definition. Try instead,
With PHP <5.4: $contents = array("notes => "it'll work!")
With PHP >=5.4: same as above or $contents = ["notes" => "yey"]
And then your echo should work.
--EDIT
As per your edit, the array looks good now. If that's not the problem, check encoding errors with echo json_last_error()
Json_encode usually take array as a parameter.
Your code is almost fine.
Just tweak it a bit like this
$contents = array();
$contents["notes"] = "this doesn't seem like it will work";
echo json_encode(array("data"=>$contents), JSON_HEX_APOS);

PHP Database Results > Array > JSON (without deprecated mysql_fetch_assoc)

I've been searching everywhere for a definitive answer to what seems to be a really simple task - unfortunately all the solutions I can find (and there are a lot) use mysql_fetch_assoc which is deprecated.
All I'm trying to do is to take a two column set of results from a database and echo in JSON format - I've managed everything fine except for one bit - I can't work how to get the values in to a two dimensional array (two column array) using array_push. I just end up with my two column values merged in to one array. Here's a stripped version of what I've done:
header('Content-Type: application/json');
$mostPopularStm = $sparklyGenericPdoObj->prepare("SELECT views, thing FROM X");
$mostPopularStm->execute();
$mostPopularRS = $mostPopularStm->fetchAll();
echo '{data:';
$mostPopularJson = array();
foreach ($mostPopularRS as $mostPopularItem)
{
array_push($mostPopularJson, $mostPopularItem["views"], $mostPopularItem["thing"]);
}
echo json_encode($mostPopularJson);
echo '}';
This is producing output like this:
{data:["Monkeyface","43","Giblets","25","Svelte","22","Biriani","21","Mandibles","20"]}
But what I need is this:
{data:["Monkeyface":"43","Giblets":"25","Svelte":"22","Biriani":"21","Mandibles":"20"]}
I know I can create something manually to do this, using json_encode to format the string on each loop but it seems inefficient.
Any pointers would be hugely appreciated!
Your current array is like
array(0 => 'Monkeyface', 1 => 43, /* ... */);
but you need like
array('Monkeyface' => 43, /* ... */);
Replace
array_push($mostPopularJson, $mostPopularItem["views"], $mostPopularItem["thing"])
By
$mostPopularJson[$mostPopularItem["thing"]] = $mostPopularItem["views"];
And
echo '{data:';
echo json_encode($mostPopularJson)
echo '}';
Better to use:
echo json_encode(array('data' => $mostPopularJson));
As kingkero said, you will never get your expected result because it is invalid:
{data:["Monkeyface":"43" ...
Correct:
{ "data": { "Monkeyface": "43" ...
Compose your array like so:
$mostPopularJson [$mostPopularItem["thing"]] = $mostPopularItem["views"];

PHP: Strange Array Problem - Where is my value?

I have an array ($form) which retreives some information from $_POST:
$form = $_POST['game'];
Now I want to work with the values in this array, but I somehow fail.
For debugging I used these commands (in the exact same order, with no extra lines inbetween):
print_r($form);
echo '#' . $form['System_ID'] . "#";
and as returned output I get:
Array
(
['Title'] => Empire: Total War - Special Forces
['Genre_ID'] => 1
['Type'] => Spiel
['System_ID'] => 1
)
##
Any ideas where my System_ID went? It's there in print_r, but not in the next line for echo?!?
Alright, I found the solution myself (a.k.a. d'oh!)
I added another
var_dump($form);
for further analysis and this is what I got:
array(4) {
["'Title'"]=>
string(34) "Empire: Total War - Special Forces"
["'Genre_ID'"]=>
string(1) "1"
["'Type'"]=>
string(5) "Spiel"
["'System_ID'"]=>
string(1) "1"
}
Notice the single quote inside the double quote?
Looks as if you're not allowed to use the single quote in html forms or they will be included in the array key:
Wrong: <input type="text" name="game['Title']" />
Correct: <input type="text" name="game[Title]" />
print_r() doesn't put quotes around keys - for debugging i'd recommend ditching print_r altogether. var_export or var_dump are better.
even better: use firephp. it sends the debug info via headers, so it doesn't mess up your output and thus is even usable with ajax. output is displayed nicely with firebug including syntax coloring for data structures.
and it's even easier to use: just fb($myvar);
It works for me:
<?
$form['System_ID'] = 1;
print_r($form);
echo '#' . $form['System_ID'] . '#';
?>
Output:
% php foo.php
Array
(
[System_ID] => 1
)
#1#
PHP 5.2.6, on Fedora Core 10
EDIT - note that there's a hint to the real cause here. In my code the print_r output (correctly) shows the array keys without single quotes around them. The original poster's keys did have quotes around them in the print_r output, showing that somehow the actual key contained the quote marks.

Php $_GET issue

foreach ($_GET as $field => $label)
{
$datarray[]=$_GET[$field];
echo "$_GET[$field]";
echo "<br>";
}
print_r($datarray);
This is the output I am getting. I see the data is there in datarray but when
I echo $_GET[$field]
I only get "Array"
But print_r($datarray) prints all the data. Any idea how I pull those values?
OUTPUT
Array (
[0] => Array (
[0] => Grade1
[1] => ln
[2] => North America
[3] => yuiyyu
[4] => iuy
[5] => uiyui
[6] => yui
[7] => uiy
[8] => 0:0:5
)
)
EDIT: When I completed your test, here was the final URL:
http://hofstrateach.org/Roberto/process.php?keys=Grade1&keys=Nathan&keys=North%20America&keys=5&keys=3&keys=no&keys=foo&keys=blat&keys=0%3A0%3A24
This is probably a malformed URL. When you pass duplicate keys in a query, PHP makes them an array. The above URL should probably be something like:
http://hofstrateach.org/Roberto/process.php?grade=Grade1&schoolname=Nathan&region=North%20America&answer[]=5&answer[]=3&answer[]=no&answer[]=foo&answer[]=blat&time=0%3A0%3A24
This will create individual entries for most of the fields, and make $_GET['answer'] be an array of the answers provided by the user.
Bottom line: fix your Flash file.
Use var_export($_GET) to more easily see what kind of array you are getting.
From the output of your script I can see that you have multiple nested arrays. It seems to be something like:
$_GET = array( array( array("Grade1", "ln", "North America", "yuiyyu", "iuy", "uiyui", "yui","uiy","0:0:5")))
so to get those variables out you need something like:
echo $_GET[0][0][0]; // => "Grade1"
calling echo on an array will always output "Array".
print_r (from the PHP manual) prints human-readable information about a variable.
Use <pre> tags before print_r, then you will have a tree printed (or just look at the source. From this point you will have a clear understanding of how your array is and will be able to pull the value you want.
I suggest further reading on $_GET variable and arrays, for a better understanding of its values
Try this:
foreach ($_GET as $field => $label)
{
$datarray[]=$_GET[$field];
echo $_GET[$field]; // you don't really need quotes
echo "With quotes: {$_GET[$field]}"; // but if you want to use them
echo $field; // this is really the same thing as echo $_GET[$field], so
if($label == $_GET[$field]) {
echo "Should always be true<br>";
}
echo "<br>";
}
print_r($datarray);
It's printing just "Array" because when you say
echo "$_GET[$field]";
PHP can't know that you mean $_GET element $field, it sees it as you wanting to print variable $_GET. So, it tries to print it, and of course it's an Array, so that's what you get. Generally, when you want to echo an array element, you'd do it like this:
echo "The foo element of get is: {$_GET['foo']}";
The curly brackets tell PHP that the whole thing is a variable that needs to be interpreted; otherwise it will assume the variable name is $_GET by itself.
In your case though you don't need that, what you need is:
foreach ($_GET as $field => $label)
{
$datarray[] = $label;
}
and if you want to print it, just do
echo $label; // or $_GET[$field], but that's kind of pointless.
The problem was not with your flash file, change it back to how it was; you know it was correct because your $dataarray variable contained all the data. Why do you want to extract data from $_GET into another array anyway?
Perhaps the GET variables are arrays themselves? i.e. http://site.com?var[]=1&var[]=2
It looks like your GET argument is itself an array. It would be helpful to have the input as well as the output.

Categories