Uninitialized array offset - php

I am using PHP to create a form with an array of fields. Basically you can add an unlimited number of 'people' to the form and each person has a first name, last name, and phone number. The form requires that you add a phone number for the first person only. If you leave the phone number field blank on any others, the handler file is supposed to be programmed to use the phone number from the first person.
So, my fields are:
person[] - a hidden field with a value that is this person's primary key.
fname[] - an input field
lname[] - an input field
phone[] - an input field
My form handler looks like this:
$people = $_POST['person']
$counter = 0;
foreach($people as $person):
if($phone[$counter] == '') {
// use $phone[0]'s phone number
} else {
// use $phone[$counter] number
}
$counter = $counter + 1;
endforeach;
PHP doesn't like this though, it is throwing me an
Notice: Uninitialized string offset error.
I debugged it by running the is_array function on people, fname, lname, and phone and it returns true to being an array. I can also manually echo out $phone[2], etc. and get the correct value. I've also ran is_int on the $counter variable and it returned true, so I'm unsure why this isn't working as intended?
Any help would be great!

I am pretty sure phone[$counter] should be $phone[$counter]. Otherwise it will treat "phone" as a string.

var_dump your $_POST value and see what's going on. The array indicies probably aren't set to what you're expecting.

Related

Variable without name: ${''}

So variable variables are existing. Meaning that this is working
$a = 'test';
$$a = 'Hello';
echo ${'test'}; //outputs 'Hello'
But now I've come across some rather strange code using a variable without a name:
function test(&$numRows) {
$numRows = 5;
echo ' -- done test';
}
$value = 0;
test($value);
echo ' -- result is '.$value;
test(${''}); //variable without name
http://ideone.com/gTvayV Code fiddle
Output of this is:
-- done test -- result is 5 -- done test
That means, the code is not crashing.
Now my question is: what exactly happens if $numRows value is changed when the parameter is a variable without name? Will the value be written into nirvana? Is that the PHP variable equivalent to /dev/null?
I wasn't able to find anything specific about this.
Thanks in advance
${''} is a valid variable which name happens to be an empty string. If you have never set it before, it is undefined.
var_dump(isset(${''})); // if you have never set it before, it is undefined.
You don't see any error because you disabled the NOTICE error message.
error_reporting(E_ALL);
ini_set('display_errors', 1);
echo ${''}; // Notice: Undefined variable:
You can set it like this:
${''} = 10;
echo ${''}; // shows 10
Now my question is: what exactly happens if $numRows value is changed
when the parameter is a variable without name?
There's no such thing as a variable without name, an empty string in PHP is a totally valid name.
Maybe I'm wrong, but in PHP, all varibles can be accessed by their names (or more precisely, the string representation of their name), and since an empty string is still a string, it counts as a valid name.
Think about variables like an array key-value pair. You can create an array key with an empty string:
$arr = [];
$arr[''] = 'appul';
var_dump($arr['']); // prints: string(5) "appul"
$arr[''] = 'ponka';
var_dump($arr['']); // prints: string(5) "ponka"
Whenever you access $arr[''], you address the same value.
You can access all variables as a string using the $GLOBAL variable too, so you can examine what happens to your "nameless" variable:
${''} = 'ponka';
var_dump($GLOBALS['']); // prints: string(5) "ponka"
${''} = 'appul';
var_dump($GLOBALS['']); // prints: string(5) "appul"
Will the value be written into nirvana? Is that the PHP variable equivalent to /dev/null? I wasn't able to find anything specific about this.
No, it doesn't go to nirvana, it sits quietly in the global space, and it's a little bit trickier to access it, but otherways, it's a normal variable like any others.

PHP - Why is this variable not working in this foreach loop?

The $value prints correctly. The number(s) are correct for $value so I think that part is eliminated.
If I manually enter the actual numbers in ($value)->price like (10079)->price, the function works fine and the last line print_r ($price) prints the number it supposed to.
For some reason $value is not working in the context of $xml_price = $fetch_app->products($value)->price; as the function returns nil for $price
foreach ($_SESSION['queueList'] as $value){
//this prints the correct item(s) in 'queueList'
print_r ($value);
//this gets the node with the price info
$xml_price = $fetch_app->products($value)->price;
//this converts the simpleXML node to a string
$price = ((string) $xml_price);
//session var accumulates the item prices in cart
$_SESSION['totalPrice'] += $price;
print_r ($price);
}
So why is the $value variable not working, but an actual number does, even though I have printed the $value and it shows the correct number? The number is a float by the way, not sure if that matters.
Judging by the additional information from the comments, the following should work:
$xml_price = $fetch_app->products((int)$value)->price;
It looks like this fetchapp API is strongly typed, which is untypical for PHP but still technically possible to a certain extent. At least it treats string parameters different from integer parameters.

CakePHP: How to switch two row values from a unique field?

I need to change the value of two rows in the order field of my database. This field is unique.
What I tried:
Storing the value of both items in a PHP variable,
Setting the first row's field value to NULL (nulls are accepted in the field),
Setting the value of the second row's field to the value that was held on the first row,
Setting the first row's field value to the original second row field value.
It doesn't work, since I am getting a "dupplicate entry" error when executing the order change. I can't seem to find out how to do this using CakePHP.
Here is the code that I have written (even though it's not functionnal):
if ($second_row) {
$next = $second_row['Immeuble']['order'];
$prev = $first_row['Immeuble']['order'];
$this->Immeuble->id = $first_row_id;
$this->Immeuble->saveField('order', 'null');
$this->Immeuble->id = $second_row['Immeuble']['id'];
$this->Immeuble->saveField('order', $prev);
$this->Immeuble->id = $first_row_id;
$this->Immeuble->saveField('order',$next);
}
of course its dublicate key
you defined id two times
$this->Immeuble->id = $first_row_id;
and
$this->Immeuble->id = $second_row['Immeuble']['id'];
and then
$this->Immeuble->id = $first_row_id;
try remove this last line
The code I stated above is fully functionnal. I just had inverted some values, which would screw everything up. I will not delete the question in case someone else needs to do something similar.

PHP isset not working properly on form, with loops and arrays

This is honestly the most finicky and inept language I've ever coded in. I'll be glad when this project is good and over with.
In any case I have to us PHP so here's my question.
I have an Array named $form_data as such:
$form_data = array
('trav_emer_med_insur',
'trav_emer_single',
'trav_emer_single_date_go',
'trav_emer_single_date_ba',
'trav_emer_annual',
'trav_emer_annual_date_go',
'trav_emer_extend',
'trav_emer_extend_date_go',
'trav_emer_extend_date_ef',
'trav_emer_extend_date_ba',
'allinc_insur',
'allinc_insur_opt1',
'allinc_single_date_go',
'allinc_single_date_ba',
'allinc_insur_opt2',
'allinc_annual_date_go',
'allinc_annual_date_ba',
'cancel_insur',
'allinc_annual_date_go',
'allinc_annual_date_ba',
'visitor_insur',
'country_select',
'visitor_supervisa',
'visitor_supervisa_date_go',
'visitor_supervisa_date_ba',
'visitor_student',
'visitor_student_date_go',
'visitor_student_date_ba',
'visitor_xpat',
'visitor_xpat_date_go',
'visitor_xpat_date_ba',
'txtApp1Name',
'txtApp2Name',
'txtApp1DOB',
'txtApp2DOB',
'txtApp1Add',
'txtApp1City',
'selprov',
'txtApp1Postal',
'txtApp1Phone',
'txtApp1Ext',
'txtApp1Email',
'conpref', );
These are the names of name="" fields on an HTML form. I have verified that ALL names exist and have a default value of '' using var_dump($_POST).
What I want to do is very simple, using the $form_data as reference do this:
create a new array called $out_data which can handle the data to display on a regurgitated form.
The structure of $out_data is simple the key will be the name of the element from the other array $out_data[txtApp1Name] for example, and then the value of that key will be the value.
Now what I want is to first check to see if every name="" is set or not, to eliminate errors and verify the data. Then regardless of whether it is set or not, create its placeholder in the $out_data array.
So if $_POST[$form_data[1]] (name is 'trav_emer_single') is not set create an entry in $out_data that looks like this $out_data([trav_emer_single] => "NO DATA")
If $_POST[$form_data[1]] (name is 'trav_emer_single') is set create and entry in $out_data that looks like this: $out_data([trav_emer_single] => "whatever the user typed in")
I have tried this code:
$out_data = array();
$count = count($form_data);
for( $i = 0; $i < $count; $i++ )
{
if(!isset($_POST[$form_data[$i]])) {
$out_data[$form_data[$i]] = "NO_DATA";
}
else {
$out_data[$form_data[$i]] = $_POST[$form_data[$i]];
}
}
Now this code technically is working, it is going through the array and assigning values, but it is not doing so properly.
I have hit submit on the form with NOTHING entered. Therefore every item should say "NO_DATA" on my regurgitated output (for user review), however only some items are saying it. All items I have confirmed have name="" and match the array, and have nothing entered in them. Why is "NO_DATA" not being assigned to every item in the array?
Also of note, if I fill in the form completely $out_data is fully and correctly populated. What is the problem with !isset? I've tried doing $_POST[$form_data[$i]] == '' which does put no_data in every instance of no data, however it throws an 'undefined index' warning for every single item on the page whether I write something in the box or not.
Really I just want to know WTF is going on, the dead line for this project is closing fast and EVERY step of the PHP gives me grief.
As far as I can tell by reading around my code is valid, but refuses to execute as advertised.
If you need more code samples please ask.
Really befuddled here, nothing works without an error, help please.
Thanks
-Sean
Instead of checking !isset(), use empty(). If the form posts an empty string, it will still show up in the $_POST as an empty string, and isset() would return TRUE.
I've replaced your incremental for loop with a foreach loop, which is almost always used in PHP for iterating an array.
$out_data = array();
foreach ($form_data as $key) {
if(empty($_POST[$key])) {
$out_data[$key] = "NO_DATA";
}
else {
$out_data[$key] = $_POST[$key];
}
}
PHP's isset returns TRUE unless the variable is undefined or it is NULL. The empty string "" does not cause it to return FALSE. empty() will do exactly what you need, though.
http://php.net/manual/en/function.isset.php
isset() will return FALSE if testing a variable that has been set to
NULL. Also note that a NULL byte ("\0") is not equivalent to the PHP
NULL constant.
Returns TRUE if var exists and has value other than NULL, FALSE
otherwise.

PHP session seems not to keep posted form values

Ladies and gents,
I found a very strange behavior which I cannot explain:
Assume that you have
multiple form elements on your page, maybe rendered by php
each form has one input field with an unique name
on the beginning of that page a session will be started
you store every posted input value in the $_SESSION variable
like this:
<?php
session_start();
$_SESSION["Test"] = "Hello";
foreach ($_POST as $name => $value) {
//echo "_POST: " . $name . ":" . $value . "<br>";
$_SESSION[$name] = $value;
//session_commit();
}
for ($i = 0; $i < 10; $i++) {
echo "<form action=\"multiform.php\" method=\"post\">Value for input $i: <input type=\"text\" name=\"input".$i."\"></form>\n";
}
print_r($_SESSION);
?>
If you use the above code, only the "Test" = "Hallo" will persist after the refresh of the page. Regardless which input value has been posted and stored into the session by the foreach, it will be gone after refresh.
Now the interesting part:
If you add a name to the form like this...
echo "<form name=\"form$i\" action=\"multiform.php\" method=\"post\">Value for input $i: <input type=\"text\" name=\"input".$i."\"></form>\n";
...the posted values will be stored then.
But why?
What has the form name to do with the persistence of the $_SESSION?
EDIT: If the input name only contains numbers, the problem seems to arraise:
<input type=\"text\" name=\"$i\">
Thanks for clarifyng this.
Jan
EDIT2:
If the accessor key for the $_SESSION array only contains numbers, php obviously does not persist the values, so something like this, won't be stored:
<?php
session_start();
for ($i = 1; $i < 10; $i++)
{
$_SESSION[$i] = "Hello $i";
}
?>
The confusing part is, if you do a
print_r($_SESSION)
just after the for loop, it will show 1-10 with Hello 1..10...
Though, after refresh it's gone...
The keys in the $_SESSION associative array are subject to the same limitations as regular variable names in PHP, i.e. they cannot start with a number and must start with a letter or underscore.
Found at http://php.net/manual/en/session.examples.basic.php
Could the problem be the integer as a form name as your edit comment suggests? If you serialize a form using PHP you end up with a variable which name is an integer and PHP's variable name cannot be a plain number. If your problem doesn't persist with a naming convention such as <input type=\"text\" name=\"sometext_$i\">, you should stop using plain numbers as a form element name.
It's also a good idea to give the form fields descriptive names. Form field named "1" or "2" doesn't really tell you anything about the containing value.
This is correct; you can not use a numeric-only key in $_SESSION. Trying to do so with error_reporting on highest level and display_errors set to true will yield a notice:
PHP Notice: Unknown: Skipping numeric key 0 in Unknown on line 0
It does store it in the $_SESSION array, but not actually in the session. Although strange behaviour, the notice is descriptive enough. The fix is easy, by the way, just create an array in $_SESSION['numbers'], for example.
<?php
session_start();
for ($i = 1; $i < 10; $i++) {
$_SESSION['numbers'][$i] = "Hello $i";
}
var_dump( $_SESSION['numbers'] );

Categories