Undefined Offset Notice With Update Query - php

I have a form that displays a Selection ID, Selection, and Definition pairing from a database. The form is dynamic...depending on the user, there could be any number of these pairings. Here is an example of three pairings:
Selection ID, Selection, Definition
Selection ID, Selection, Definition
Selection ID, Selection, Definition
The page displays just fine, but if the user wants to edit a Selection or Definition, I receive the following error when the form is submitted (Note: Line 41 is my Update query):
"Notice: Undefined offset: 3 in (link to my php file) on line 41"
I assume that the notice is telling me that the query is not reading the information in my three arrays...but I don't know what I should be putting in my query so it will read properly. Thank you very much for your help.
if(isset($_POST['submit'])){
$selection_id = array();
$selection = array();
$definition = array();
foreach ($_POST as $key => $value){
// If array variable starts with "pd_selection_id_for_" save to $selection_id array, otherwise continue to the next array.
if(strpos($key, 'pd_selection_id_for_') !== false){
$selection_id[] = mysql_real_escape_string($value);
}else if(strpos($key, 'selection_for_') !== false){
$selection[] = mysql_real_escape_string($value);
}else if(strpos($key, 'definition_for_') !== false){
$definition[] = mysql_real_escape_string($value);
}
}
// Count one of the arrays to select the paired fields and update the database.
$total = count($definition);
for ($i=1; $i <= $total; $i++){
// Update query for the paired selections and definitions.
$query = mysql_query("UPDATE `pd_selections` SET `pd_selection` = '$selection[$i]', `pd_definition` = '$definition[$i]' WHERE `pd_selection_id` = '$selection_id[$i]' ") or die(mysql_error());
}
}

Minor syntax error the fix for Line 41 is below:
$query = mysql_query("UPDATE `pd_selections` SET `pd_selection` = '".$selection[$i]."', `pd_definition` = '".$definition[$i]."' WHERE `pd_selection_id` = '".$selection_id[$i]."'") or die(mysql_error());

Undefined Offset error means that the position that you are trying to access in your array is not set and therefore its not defined.
Problem you have is that your arrays are not initialized at the index you are trying to access from loop, try this:
$i = 0;
foreach ($_POST as $key => $value){
//initialize array at position $i
$selection_id[$i] = $selection[$i] = $definition[$i] = '';
if(strpos($key, 'pd_selection_id_for_') !== false){
$selection_id[$i] = mysql_real_escape_string($value);
}else if(strpos($key, 'selection_for_') !== false){
$selection[$i] = mysql_real_escape_string($value);
}else if(strpos($key, 'definition_for_') !== false){
$definition[$i] = mysql_real_escape_string($value);
}
$i++;
}
this way you know that all your arrays size are same and therefore will be set on same positions that other arrays are set.

Related

How to differentiate between each isset and update a specific table row in PHP

The first part of my code creates some entries in a table using $_POST.
foreach ($_POST['form_item'] as $key => $value) {
$item = $_POST['form_item'][$key];
$barcode = $_POST['form_barcode'][$key];
$task = $_POST['form_task'][$key];
$bottom_items = $pdo->prepare("INSERT INTO carpet_items_extra (`item_id`,`item_task`, `item_barcode`) VALUES ('$log_id', '$task', '$barcode')");
$bottom_items->execute();
The next part contains the data I need to update the entries with.
if(isset($_POST['form_price_standard'][$key]) && $_POST['form_price_standard'][$key] != ''){
$price_standard = $_POST['form_price_standard'][$key];
}
else{
$price_standard = 0;
}
if(isset($_POST['form_price_daily_1'][$key]) && $_POST['form_price_daily_1'][$key] != '' && isset($_POST['form_duration_2'][$key]) && $_POST['form_duration_2'][$key] != ''){
$price_daily_1 = $_POST['form_price_daily_1'][$key];
$duration_2 = $_POST['form_duration_2'][$key];
}
else{
$price_daily_1 = 0;
$duration_2 = 0;
}
$update = $pdo->prepare("UPDATE carpet_items_extra SET `price_standard` = '$price_standard', `price_daily_1` = '$price_daily_1', `duration_2` = '$duration_2' WHERE item_id = '$log_id AND item_task = '$task' AND item_barcode = '$barcode'");
$update->execute();
}
The problem is when the data is only from the first isset it's saved as it should be, but when there's data in the second isset as well, only the first row in the table gets update.
How can I differentiate between the two?
I have tried using for to execute the query once for every $barcode item, as well as using nested foreach.
The result though was multiple extra entries in the database table.

Cannot access empty property error in php

I have some text stored in a table. I want to replace all the expressions that look like this : [%parameter_name] with the corresponding value stored in another table.
All the parameters and in which column I must fetch their value are stored in a third column.
I tried to make a function to put all the needed patterns and their value in an array. However, it gives me a fatal error. Why?
Here is the code :
$search = $db->prepare("
SELECT *
FROM table
WHERE id = ?");
$search->execute(array($id));
$search->setFetchMode(PDO::FETCH_OBJ);
while($result = $search->fetch()){
$search2 = $db->prepare("
SELECT parameter_name,
read_from
FROM pattern
WHERE type = ?");
$search2->execute(array(strtolower($result->type)));
$search2->setFetchMode(PDO::FETCH_OBJ);
while($pattern = $search2->fetch()){
array_push($patterns, '/\[%'.$result->type.'\.'.$pattern->parameter_name.'\]/i');
$column = explode(',', $pattern->read_from);
if(count($column) == 1){
$col = $column[0];
// ERROR ON THE LINE BELOW
$value = $result->$col;
}
else{
$value = 0;
foreach($column as $col){
// BUT NOT ON THE ONE BELOW
$value += $result->$col;
}
}
array_push($replacements, $value);
}
}

Loop through an array to create an SQL Query

I have an array like the following:
tod_house
tod_bung
tod_flat
tod_barnc
tod_farm
tod_small
tod_build
tod_devland
tod_farmland
If any of these have a value, I want to add it to an SQL query, if it doesnt, I ignore it.
Further, if one has a value it needs to be added as an AND and any subsequent ones need to be an OR (but there is no way of telling which is going to be the first to have a value!)
Ive used the following snippet to check on the first value and append the query as needed, but I dont want to copy-and-paste this 9 times; one for each of the items in the array.
$i = 0;
if (isset($_GET['tod_house'])){
if ($i == 0){
$i=1;
$query .= " AND ";
} else {
$query .= " OR ";
}
$query .= "tod_house = 1";
}
Is there a way to loop through the array changing the names so I only have to use this code once (please note that $_GET['tod_house'] on the first line and tod_house on the last line are not the same thing! - the first is the name of the checkbox that passes the value, and the second one is just a string to add to the query)
Solution
The answer is based heavily upon the accepted answer, but I will show exactly what worked in case anyone else stumbles across this question....
I didnt want the answer to be as suggested:
tod_bung = 1 AND (tod_barnc = 1 OR tod_small = 1)
rather I wanted it like:
AND (tod_bung = 1 OR tod_barnc = 1 OR tod_small = 1)
so it could be appended to an existing query. Therefore his answer has been altered to the following:
$qOR = array();
foreach ($list as $var) {
if (isset($_GET[$var])) {
$qOR[] = "$var = 1";
}
}
$qOR = implode(' OR ', $qOR);
$query .= " AND (" .$qOR . ")";
IE there is no need for two different arrays - just loop through as he suggests, if the value is set add it to the new qOR array, then implode with OR statements, surround with parenthesis, and append to the original query.
The only slight issue with this is that if only one item is set, the query looks like:
AND (tod_bung = 1)
There are parenthesis but no OR statements inside. Strictly speaking they arent needed, but im sure it wont alter the workings of it so no worries!!
$list = array('tod_house', 'tod_bung', 'tod_flat', 'tod_barnc', 'tod_farm', 'tod_small', 'tod_build', 'tod_devland', 'tod_farmland');
$qOR = array();
$qAND = array();
foreach ($list as $var) {
if (isset($_GET[$var])) {
if (!empty($qAND)) {
$qOR[] = "$var = 1";
} else {
$qAND[] = "$var = 1";
}
$values[] = $_GET[$var];
}
}
$qOR = implode(' OR ', $qOR);
if ($qOR != '') {
$qOR = '(' . $qOR . ')';
}
$qAND[] = $qOR;
$qAND = implode(' AND ', $qAND);
echo $qAND;
This will output something like tod_bung = 1 AND (tod_barnc = 1 OR tod_small = 1)
As the parameter passed to $_GET is a string, you should build an array of strings containing all the keys above, iterating it and passing the values like if (isset($_GET[$key])) { ...
You could then even take the key for appending to the SQL string.
Their are a lot of ways out their
$list = array('tod_house', 'tod_bung', 'tod_flat', 'tod_barnc', 'tod_farm', 'tod_small', 'tod_build', 'tod_devland', 'tod_farmland');
if($_GET){
$query = "";
foreach ($_GET as $key=>$value){
$query .= (! $query) ? " AND ":" OR ";
if(in_array($key,$list) && $value){
$query .= $key." = '".$value."'";
}
}
}
Sure you have to take care about XSS and SQL injection
If the array elements are tested on the same column you should use IN (...) rather than :
AND ( ... OR ... OR ... )
If the values are 1 or 0 this should do it :
// If you need to get the values.
$values = $_GET;
$tod = array();
foreach($values as $key => $value) {
// if you only want the ones with a key like 'tod_'
// otherwise remove if statement
if(strpos($key, 'tod_') !== FALSE) {
$tod[$key] = $value;
}
}
// If you already have the values.
$tod = array(
'tod_house' => 1,
'tod_bung' => 0,
'tod_flat' => 1,
'tod_barnc' => 0
);
// remove all array elements with a value of 0.
if(($key = array_search(0, $tod)) !== FALSE) {
unset($tod[$key]);
}
// discard values (only keep keys).
$tod = array_keys($tod);
// build query which returns : AND column IN ('tod_house','tod_flat')
$query = "AND column IN ('" . implode("','", $tod) . "')";

PHP Selectbox function not working quite right?

I have a table teamtrack_activity that holds id and activity_name.
I have table teamtrack_entry that holds all team daily entries. This table has a field "activity_id" that I want to store the teamtrack_activity id. I have this part working.
However I am having 2 issues:
Displaying activity_name instead of id. When I try to do this then activity_name gets passed and this of course doesn't work.
When I go back to edit the entry it does not show the value in the database. It just shows the select box anew.
if ($key == "activity_id")
{
$query="SELECT id, activity_name FROM teamtrack_activity Order By id";
$res = sql_query($query);
if ($res === FALSE)
{
trigger_error(sql_error(), E_USER_WARNING);
fatal_error(FALSE, get_vocab("fatal_db_error"));
}
$select_options["entry.$key"] = array();
for ($i = 0; ($row = sql_row_keyed($res, $i)); $i++)
{
$select_options["entry.$key"][$row['id']] = $row['id'];
}
}
Change:
$select_options["entry.$key"][$row['id']] = $row['id'];
into
$select_options["entry.$key"][$row['id']] = $row['activity_name'];
to get a dropdown with the activity ame, which submit the activity ID for your script.
Based on your comment;
It might be the parsing of your $select_options.
In a foreach loop you would want to
foreach($select_options["entry.$key"]) as $key => $label)
{
echo "<option value=".$key.">".$label."</option>";
}

How to use foreach to create an array and later update a database

I have a dynamic form that populates a questionnaire rating scale from information saved in my database. Each rating consists of a "selection" and a "definition". A scale can consists of any number or ratings. Here is an example of a 5 rating scale:
Strongly Agree = I strongly agree with this statement.
Agree = I agree with this statement.
Neither Agree nor Disagree = I neither agree nor disagree with this statement.
Disagree = I disagree with this statement.
Strongly Disagree = I strongly disagree with this statement.
Once the form is populated, the user can edit any of the selections or definitions. My form populates just fine, but I cannot figure out how to correctly populate the POST data into an array if the user submits a change or use that array to edit the information in my database.
Here is my PHP:
if(isset($_POST['submit'])){
$fields = "";
$values = "";
foreach($_POST as $key => $value) {
$fields = mysql_real_escape_string($key);
$values = mysql_real_escape_string($value);
$entry .= "[". $fields . "=" . $values . "]";
//Here is the start of the query that I'm building
//$query = mysql_query("UPDATE `pd_selections` SET `pd_selection` = ' ', `pd_definition` = ' ' WHERE `pd_selection_id` = '$pd_selection_id' ") or die(mysql_error());
}
}
If I echo the "entry" variable, this is what I receive:
[selection_for_1=Strongly Agree][definition_for_1=I strongly agree with this statement.][selection_for_2=Agree][definition_for_2=I agree with this statement.]
How do I pull the selection and the definition out of the array for each rating?
How is that used to update the database?
Am I even on the right track...LOL!?
Thank you very much for any help you can provide.
For security purpose you should keep a list of keys you would accept to prevent the user from modifying it, this will keep people from adding non valid data to your form as well as keeping out fields you may not want.
Create an array for selection another for definition, and use it to store the key/value while checking for valid fields:
$accept = array('selection_for_1', 'definition_for_1',
'selection_for_2', 'definition_for_2');
$selection = array();
$definition = array();
foreach ($_POST as $key => $value)
{
// if not valid go to next field/value
if(!in_array($key, $accept))
continue;
// if start with selection save to $selection array
// otherwise to definition array
if (strpos($key, 'selection') !== false)
{
$selection[] = mysql_real_escape_string($value);
}
else
{
$definition[] = mysql_real_escape_string($value);
}
}
// count one of the array to select the paired fields
// and insert or update into database
$total = count($definition);
for ($i=0; $i < $total; $i++)
{
// Update query for the paired selection and definition
$query = mysql_query("UPDATE pd_selections
SET pd_selection = '{$selection[$i]}',
pd_definition = '{$definition[$i]}'
WHERE pd_selection_id = '{$pd_selection_id}'")
or echo("Could not insert or update selection '{$selection[$i]}', definition '{$definition[$i]}', failed with error:", mysql_error());
}
Live DEMO.

Categories