php session variable multidimensional associative array issue - php

I've looked around SO, but can't find an explanation to what is going on in my $_SESSION variables.
#ob_start();
$k=#ob_get_contents();
#ob_end_clean();
#session_start();
unset($s,$m);
$m1 = explode(" ", microtime());
$stime = $m1[1] + $m1[0];
echo $k;
$_SESSION['resendConfirmation']['function'] = 'resend';
$_SESSION['resendConfirmation']['id'] = '8';
print_r($_SESSION);
outputs:
Array ( [resendConfirmation] => 8esend )
Why is it string replacing? I've never had this issue before.
What I want is thus:
Array([resendConfirmation] => Array(
[id] =>8
[function} => resend
)
)
I've never had this happen before, I'm totally confused!
UPDATE
In response to #DanRedux I've changed to two non-existent variable names to take the referencing out of the equation, still the same result...
$_SESSION['resendConfirmation']['tweak'] = 'resend';
$_SESSION['resendConfirmation']['tweak2'] = '8';
Same result :(
Did a sitewide query of resendConfirmation and none were found, but once I change that array name, it all worked, baffled, but fixed...
$_SESSION['reConfirm']['function'] = 'resend';
$_SESSION['reConfirm']['id'] = '8';
print_r($_SESSION);

Since I dont really know what other sorts of shenanigans the code is up to outside of this block you gave us I would say to just try this instead:
$_SESSION['resendConfirmation'] = array('id' => 8, 'function' => 'resend');
If this also fails then there has to be something else going on outside of what you posted. Good luck!

What you think is an multidimensional array really isn't. What really happens is:
What you think is an array is really a string. After that you are trying to access the string as an array. You are trying to access the element id which doesn't exists. PHP always tries to be smarter than it should and just says: OK I'll assume you meant the first index. So basically what happens is:
<?php
$notAnArray = 'somestring';
$notAnArray['id'] = '8';
var_dump($notAnArray); // 8omestring
This is the reason you should always enable error_reporting on your development machine:
error_reporting(E_ALL | E_STRICT);
ini_set("display_errors", 1);
And never suppress errors using #. Well there are some situations where you can use #, but this really isn't one of them.

Related

2D Array in PHP Fails When Trying to Find Matching String

I'm still learning PHP, but I needed a way of keeping track of a list of two associated values, a cinema and its postcode. Now before you read any further I must stress that I do not technically need this problem solving as I have since replaced it with a more efficient method. I'm really just wanting to know why it doesn't work as I can't find anything about it elsewhere.
$cinema_locations = array(
array("Odeon", "M4 2BS"),
array("Cineworld", "OL7 0PG"),
array("Vue", "M50 3AG"),
array("AMC", "M3 4EN")
);
for ($i=0; $i<count($cinema_locations); $i++) {
if ($cinema_locations[$i][0] == $_GET['cinema_name']) {
$postcode = $cinema_locations[$i][1];
return;
}
}
As you can probably tell from the code, I am trying to loop through the main array so that I may compare the first value of each child array against a $_GET variable. I have checked over this code multiple times and even showed some of my other coder friends and none of us can find anything wrong, syntax or otherwise. And yet, the browser shows only a white screen. If anyone can shed some light on the issue, I and my friends would be most appreciative; and who knows, it may help someone else with the same issue.
For anyone that may be curious, I replaced the 2D array with an associative array thus:
$cinema_locations = array(
"Odeon" => "M4 2BS",
"Cineworld" => "OL7 0PG",
"Vue" => "M50 3AG",
"AMC" => "M3 4EN"
);
$postcode = $cinema_locations[$_GET['cinema_name']];
EDIT
Thanks rishi, that did it. I never even considered that the return would nullify the result. Using break stopped the loop and the rest of the page loaded fine.
May be you should write break; instead of return;
You needed to break your for loop if you meet the condition. and continue with the below code.
return will instantly returns value from where its called.
For situations in which you cannot change the array structure, this code is a better approach.
// same array as the original post
$cinema_locations = array(
array("Odeon", "M4 2BS"),
array("Cineworld", "OL7 0PG"),
array("Vue", "M50 3AG"),
array("AMC", "M3 4EN")
);
foreach ($cinema_locations as $c_loc) {
$postcode = ($_GET'cinema_name'] == $c_loc[0]) ? $c_loc[1] : null;
}
print $postcode;
Of course, you should never use $_GET directly like this, but you probably already knew that.

"Cannot use a scalar value as an array" for undefined values

I have the following piece of code:
function Biz_GetAccountsPerMarket($site = "", $cache = true){
if($site == ""){
$site = $_SESSION["sitedirect_current_site"];
}
$aAccounts = Sys_OptionsGet("sys_site/".$site, "account", $cache);
$aAccountInfo = array();
$aVatAccount = Biz_GetVatAccounts($site, $cache);
$aSalesAccount = Biz_GetSalesAccounts($site, $cache);
foreach((array)$aAccounts as $code => $data){
foreach((array)$data["data"] as $market => $aItem){
$aAccountInfo[$market][$code] = $aItem;
$aAccountInfo[$market][$code]["vat"] = $aVatAccount[$aItem["vat_account_code"]]["value"];
$aAccountInfo[$market][$code]["vat_account"] = $aVatAccount[$aItem["vat_account_code"]]["account"];
$aAccountInfo[$market][$code]["sales_account"] = $aSalesAccount[$aItem["sales_account_code"]]["account"];
}
}
return $aAccountInfo;
}
The four innermost lines in the nested loop generates warnings: "Cannot use a scalar value as an array".
Adding lines that initialises $aAccountInfo[$market] and $aAccountInfo[$market][$code] to empty arrays first silences the errors, but this is far from the only place in our code where nested arrays are initialised in this way; and I can't figure out why it is a problem in the first place.
The following code should reproduce the problem; as far as I can tell; but doesn't:
<?php
ini_set('display_errors', '1');
error_reporting(E_ALL | E_STRICT);
$aTest = [];
$aTest['key']['key'] = 'sausage';
If $aItem was a string or false, or any scalar; I could understand what the problem is; but then the warning should only happen for the last three lines, not all four.
There are other weird things happening there, I hope they're all connected. This is the only one I've managed to isolate enough to ask a question about.
Is it possble to set the default value created by array access somehow?
edit:
I've noticed that many strings that are generates have an extraneous "0". This breaks things, like SQL. If empty array values somehow default to "0" or something, that would explain a lot. I have no idea how that could happen though. I'm currently grepping for "register_tick_function"...
You need to check if arrays have the expected keys. Something like this:
$aAccountInfo[$market][$code]["vat"] = isset($aItem["vat_account_code"]) ? (isset($aVatAccount[$aItem["vat_account_code"]]) ? $aVatAccount[$aItem["vat_account_code"]]["value"] : []) : [];
I am afraid your code is wrong
This line
$aAccountInfo[$market][$code] = $aItem;
creates the new occurance containing a SCALAR value and you then try and add a sub array onto that scalar value, hence the error
If you do this instead
$t = array();
$t['item'] = $aItem;
$t["vat"] = $aVatAccount[$aItem["vat_account_code"]]["value"];
$t["vat_account"] = $aVatAccount[$aItem["vat_account_code"]]["account"];
$t["sales_account"] = $aSalesAccount[$aItem["sales_account_code"]]["account"];
$aAccountInfo[$market][$code] = $t;
Then you will get a sub array created with all the values in it;

Have I understood sessions/multi-dimensional arrays properly?

Am I doing the following correctly?
I have an array, which I want to save to a session, so I can use it later in my web application:
$data = array(
"id" => $_POST["id"],
"r1" => $_POST["r1"],
"r2" => $_POST["r2"],
"r3" => $_POST["r3"]);
I save it to a session like this:
$_SESSION['settings'] = $data;
Now, I am not sure how to make use of this later in my application.
Do I do the following
$id = $_SESSION['settings']['id'];
$r1 = $_SESSION['settings']['r1'];
or do I do the following
$data = $_SESSION['settings'];
$id = $data['id'];
$r1 = $data['r1'];
or do I do something else?
Both those methods are perfectly valid ways of doing it. It's probably worth putting some defensive coding in there however.
eg.
$id = "";
if (ISSET($SESSION["settings"]) && ISSET($SESSION["settings"]["id"])
{
$id = $SESSION["settings"]["id"];
}
You can do both as $_SESSION['settings'] points to an array, the two expressions will be identical:
// The expression...
$val = $_SESSION['settings']['id'];
// ... is an internal shorthand for ...
$tmp = $_SESSION['settings']; // $tmp never exist - just to aid explanation.
$val = $tmp['id'];
Don't forget to use session_start(); before setting/using variables.
Then set the variables as you did. Not 100% sure, but both ways should work.
When you finish working with session, dont forget to destroy it session_destroy();.
Do whatever you need to solve your problem. In your case, both ways are acceptable of working with sessions. If I were you, I would choose the first example when only need to acces 1 or 2 elements from the session and the secon example to access more than 2 (in order to type less ).

Assigning array() before using a variable like array

I tried to find a proper and explanatory title but I couldn't and I will try to explain what I am asking here:
Normally if you don't assign an empty array to a variable, you can start assign values to indexes like this:
$hello["world"] = "Hello World";
...
echo $hello["world"];
but I always encounter such definition:
$hello = array() //assigning an empty array first
$hello["hello"] = "World";
...
echo $hello["hello"];
Why is it used a lot. Is there a performance gain or something with the second one?
Thanks.
Two reasons:
Better readability (you know the array is initialized at this point)
Security - when running on a system with register_globals enabled a user could add e.g. hello[moo]=something to the query string and the array would already be initialized with this. $hello = array(); overwrites this value though since a new array is created.
Initializing your variables is good practice.
Take for example this:
$foo = 'bar';
// 10 lines and 1 year later
$foo['baz'] = 'test';
Congratulations, you now have the string "tar".
This may happen accidentally and introduce needless bugs. It gets even worse with conditional variable creation. It's avoided easily by getting into the good habit of explicitly initializing your variables.
$hello = array();
if(someConditionIsTrue){
$hello["world"] = "Hello World";
}
foreach($hello as $val){ // this will not give you any error or warning.
echo $val;
}
But
if(someConditionIsTrue){
$hello["world"] = "Hello World";
}
foreach($hello as $val){ // this will give you error .
echo $val;
}
If I remember correctly, the first one will produce a warning by PHP if you have error_reporting as E_ALL. You should always use the second method because it explicitly initialises a new array. If you are looking through code and out of nowhere see $hello["hello"] but cannot recall seeing any reference to $hello before, it would be confusing.
The same will happen if you do $hello[] = "World", a warning will be displayed

PHP set assigned variable to undefined - it stays the same?

I have question about some behavior I was just debugging, specifically what happens if a variable which is already set is assigned to an undefined value. I just want to check that I'm understanding what happened correctly. If a variable has a value set already, and you try to set it to something undefined, it stays at its old value?
Specifically, I had some PHP code that looked approximately like this - assume that $string is some string of 1's and 2's.
$array = array(1 => 'foo', 2 => 'bar');
for($count=0;$count<len($string);$count++)
{
$newvar = $array[$string[$count]];
if(!empty($newvar))
{
switch($newvar)
{
case 'foo':
// blah blah break;
case 'bar':
// blah blah break;
}
}
}
Now, my code was supposed to set $string to be something like "12212", but an error on my part was sending it something with extra spaces at the end - "12212 ". This caused some aberrant behavior, and I think what happened was this - when $count=5, $string[5] is undefined, so $array[$string[5]] is undefined, and $newvar stays as 2. Thus my if(!empty statement doesn't do its job and case 'bar' happens more times than it should have. Does that all seem like what would happen?
Of course, trimming $string solved my problem, but I want to make sure I understand what was going wrong. Apologies if this is a stupid question - I'm just an amateur here....
Edit: Here's the actual code. $upstr is supposed to be a string of digits.
$len = strlen($upstr);
$cost=0;
$upnames = array(4=>"man", 2=>"raw", 1=>"food", 3=>"fuel",5=>"tech");
for($strloop=0;$strloop<$len; $strloop++)
{
$number = $upstr[$strloop];
if(! empty($number))
{
$name = $upnames[$number];
$cost+= mysql_result($result1,0,$name) +1;
if(mysql_result($result2,0,$name."up")==1)
{
$cost+=100;
}
}
}
What happened when $upstr had some extra spaces at the end was I would see a mysql error, that it couldn't find the column "up" in $result2 . So it was trying to run that block of code in the if() statement with $name being empty or NULL or something. And if I intentionally added 3 or 4 extra spaces, I would see that many mysql errors.
I'm afraid the definition of variable $array is incorrect in your code example, it should read as follows:
$array = array(1 => 'foo', 2 => 'bar');
If you set $newvar to an undefined element of $array (e.g. 3) then $newvar will be set to NULL.
Use array_key_exists($array, $string[$count]) to check if your array has value for your key.
Ok, I've figured out what was causing the behavior I saw. The strings '' and ' ' behave differently under empty(). One of them is considered empty and the other isn't, which was confusing me. Thanks so much for all the help.

Categories