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.
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);
}
}
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) . "')";
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>";
}
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.