POST checkbox name even if its not checked - php

Is it possible to POST checkbox name even if its not checked?
<input type='checkbox' class='tinyField' name='alert_by_email' value="1" <?PHP echo $alert_by_emailChecked ?> />
foreach ($_POST AS $field => $value)
$sql[] = $field." = '". $value."'";
$sql = implode(' , ',$sql);
$query = "UPDATE user_setup SET ".$sql." WHERE (userID = ".$userID.") " ;
$res = mysql_query($query);
So when I PRINT_R the POST i will get the field, but it will be empty
Array ( [alert_by_email] => '' )

Add this before your checkbox.
<input type='hidden' name='alert_by_email' value="" />

The straight forward answer is no.
The HTML form wont send the checkbox if it's not checked.
However, there are some workarounds:
use js to Generate a hidden input for each checkbox you have, set the value to 0 or '', and whenever you check them, remove the hidden input.
you could simply test if the key exist in the post like so:
if (isset($_POST['alert_by_email']))

In Short, No this is not possible if you are posting FORM without using any Javascript.
Also, Your code may be injected easily as you are relying on user provided column names without validating those. I am posting alternative way to do that. Hope that helps:
Suppose you have this HTML Form:
<form method="POST">
First name:<br />
<input type="text" name="firstname" />
<br />
Last name:<br />
<input type="text" name="lastname" /><br />
<input type="submit" />
</form>
Now, if you want to update values using PHP, your code should be:
<?php
$columnArray = array('firstname' => NULL, 'lastname' => NULL); // This is list of columns which can be updated using form input values (NULL is default value here)
$submittedValues = array_intersect_key($_POST, $columnArray);
// Above code will produce an array like `array('firstname' => 'anyname', 'lastname' => 'anylastname')
//--> Now you can generate your SQL using `$submittedValues`
$sql = array();
foreach ($submittedValues as $field => $value)
{
$sql[] = $field." = '". $value."'";
}
$sqlString = implode(' , ',$sql);
Using this way, hacker will not be able to add extra columns which shouldn't be updated by user i.e. last_login_date or something.

Related

PHP foreach Construct Confusion

I am having a hard time wrapping my head around the foreach construct. I have found numerous examples of course, but I never seem to be able to adapt them to my needs.
Please consider this working example I have:
I am collecting two dates in an HTML form:
<form method="post">
<legend>Minutes and Records</legend>
<label for="FirstAGMDate">First AGM Date (only if known)</label>
<input type="text" name="FirstAGMDate" value="2014-01-01" />
<label for="MinutesInspectedFromDate">Minutes Inspected From Date</label>
<input type="text" name="MinutesInspectedFromDate" value="2014-01-02" />
<input type="submit" name="submit" />
</form>
On submit the values are being pushed to the mysql database with a PDO prepared statement:
if (isset($_POST['submit'])) {
$sql = "UPDATE jobsinglevalues SET Date = :FirstAGMDate WHERE FormId = 0;
UPDATE jobsinglevalues SET Date = :MinutesInspectedFromDate WHERE FormId = 1;";
$sth = $db->prepare($sql);
$sth->execute(array(':FirstAGMDate'=>($_POST['FirstAGMDate']), ':MinutesInspectedFromDate'=>($_POST['MinutesInspectedFromDate'])));
}
This works no problem, but it's not very clever when I need to repeat this for a dozen inputs. What I want to do is achieve this with only one line of sql; looping for each <input type="text" name="Value" />.
How can I place this into a foreach loop?
In my head it works like this:
On submit each input updates the value in the database based on FormId, which increments by 1 each loop starting at 0. FormId is not a primary key, it simply mirrors the order in which the form elements are displayed.
Update - working example
if (isset($_POST['submit'])) {
$FormId = 0;
foreach($_POST['Value'] as $avalue){
$sql = "UPDATE jobsinglevalues SET Date = :Value WHERE FormId = :FormId";
$sth = $db->prepare($sql);
$sth->execute(array(':Value'=>($avalue), ':FormId'=>($FormId)));
++$FormId;
}
}
This seems to logically work to me! Is the correct solution similar? Please let me know if I need to clarify anything.
Thankyou,
Sam
Let's start by making sure all our values are in an array after posted; if you don't care about the keys you can just use name="Values[]", but I'll use name="Value[FirstAGMDate]" etc so we know what key a value belongs to.
<form method="post">
<legend>Minutes and Records</legend>
<label for="FirstAGMDate">First AGM Date (only if known)</label>
<input type="text" id="FirstAGMDate" name="Value[FirstAGMDate]" value="2014-01-01" />
<label for="MinutesInspectedFromDate">Minutes Inspected From Date</label>
<input type="text" id="MinutesInspectedFromDate" name="Value[MinutesInspectedFromDate]" value="2014-01-02" />
<input type="submit" name="submit" />
</form>
Now we can process the posted array of values. If we want to do something with the key, we can use foreach($_POST['Value'] as $akey => $avalue), if we are only interested in the values then foreach($_POST['Value'] as $avalue) suffices.
$sql = "UPDATE jobsinglevalues SET Date = :Value WHERE FormId = :FormId;";
$sth = $db->prepare($sql);
foreach($_POST['Value'] as $akey => $avalue) {
$sth->execute(array(':Value' => $avalue, ':FormId'=> $FormId ));
++$FormId;
}
[edit] As per edit-suggestion by #AravindKishore, creating the prepared statement is better done before the loop. Prepare once, enjoy forever.

Using an array to populate other variables using a foreach

In simple terms I have a form which has three identical entry fields. The names are different; however, when posted they have the same structure just different name prefix (ie three systems have different name prefixes: they would be windowstitle, mactitle, linuxtitle etc).
Currently I have a process that will only work one namesake out ie windowstitle (if the form is filled out, of course)
The code looks something like this:
<?php
$title = $_POST['windowstitle'];
//validate info or redirect
if ($title != "" ) {
$title = mysql_real_escape_string($title);
$sql = "insert into newwindows (title) values ('$title');
$result = mysql_query($sql) or die ("Could not insert data into DB: " . mysql_error());
?>
Also the form block looks something like this
<form action="newuserprocess.php" method="post" enctype="multipart/form-data">
<div class="form">
<h3>Windows</h3>
<!-- title of system name -->
<p><label for="windowstitle"> edition of system </lable></p>
<input type="text" name="windowstitle" size=20 /><br />
</div>
<div class="form">
<h3>Mac</h3>
<!-- title of system name -->
<p><label for="mactitle"> edition of system </lable></p>
<input type="text" name="mactitle" size=20 /><br />
</div>
<p><input type="submit" id="submit" class="bigbutton" value="Upload" /></p>
</form>
However, that leaves other forms left out with the only difference being the db I wanted entered and the post value prefix different.
So I came up with what I thought was a clever solution:
<?php
$arr = array('windows', 'mac', 'linux');
foreach ($arr as &$value) {
$title = $_POST['$valuetitle'];
//validate info
if ($title != "" ) {
$title = mysql_real_escape_string($title);
$sql = "insert into new$value (title) values ('$title');
$result = mysql_query($sql) or die ("Could not insert data into DB: " . mysql_error());
}
?>
However, this does not work. I know partly why; because '' makes the variable appear as is, thus my $_Post will always come back as $value. Another reason is the same with my new$value database name. What is the proper format for this? How do I make this work?
you probably want
$title = $_POST[$value . 'title'];
and
$sql = "insert into new$value (title) values ('$title')";
Another reason is the same with my new$value database name. My question is what is the proper format for this?
I'd surround $value in brackets {$value} for clarity. Your format works but could be clearer. See some tests: http://ideone.com/A2kWU
Also, if you are not changing the values in array $arr then you should just use
foreach ($arr as $value) { //...
to prevent accidental changes. In this case it won't be a big deal, though, since you're just using the array once.
Edit your code like:
<?php
$arr = array('windows', 'mac', 'linux');
foreach ($arr as $value) {

Can I use $_POST & $_GET at the same time?

I have a following form:
<form action="doThis.php?warehouse=12" method="post">
<input name="field1" type="text" />
<input name="field2" type="text" />
</form>
And doThis.php:
$field1 = mysql_real_escape_string($_POST['field1'], $mysql);
$field2 = mysql_real_escape_string($_POST['field2'], $mysql);
$warehouse = $_GET['warehouse'];
if ( !someTableNameValidation($warehouse) ) {
someErrorHandling();
}
$qry = "INSERT INTO table".$warehouse." ( field1, field2 ) VALUES( '$field2', '$field2') ";
$result = #mysql_query($qry, $mysql);
As you can see, I'm using $_POST to get data from the form, and $_GET to get variable $warehouse which is used to indicate table number.
Can I use both $_POST & $_GET at the same time? Is this kind of usage correct?
Yes you could. $_GET['warehouse'] will be taken from the query string, $_POST variables from submitted POST values.
Yes, this is possible. But you could also use a hidden field:
<form action="doThis.php">
<input type="hidden" name="warehouse" value="12" />
<input name="field1" type="text" />
<input name="field2" type="text" />
Please be aware that your code is very vulnerable to sql injections!
Yes I always do that.
Also note you should never use mysql_query. Search for php PDO. Not to mention the awful # for suppressing error
Yes, however it should be:
$field1 = $_POST['field1'];
$field2 = $_POST['field2'];
$warehouse = $_GET['warehouse'];
$qry = "INSERT INTO table".$warehouse." ( field1, field2 ) VALUES ('".mysql_real_escape_string($field2)."', '".mysql_real_escape_string($field2)."')";
$result = #mysql_query($qry);
(Fixed syntax)
I frequently use POST and GET together, so that the PHP side can know whether it was a normal form submission or via AJAX.
<form action='dest.php'>
.
.
.
vs
ajaxSubmit( 'dest.php?a=1', ... );

How to work with checkboxes in relation to database?

Hi I am trying to build a form with checkboxes and upon submitting the form, I want to see which checkboxes were checked and update the database accordingly. How is this done? I've tried so many different code and none of them worked. The closest I've gotten was to update only the checked ones. I also need to update the database if they are unchecked as well like a toggle.
So far my code is like this for the form
<form action="" method="post">
<input type=checkbox" value="<?php echo member['id']; ?>" name="member[]" />
<input type="submit" name="update" value="Update" />
</form>
And for the PHP loop I have (excerpt)
foreach ((array)$_POST['test'] as $member) :
$sql = "UPDATE `sp_members` SET `allow_test` = '1' WHERE `id` = '$member'";
Since I think the loop only picks up the checkboxes that are checked, it doesn't pick up the ones that were orignally checked and now unchecked...
Any help appreciated!
Simply update everything instead of trying to figure out what changed - if you programmed it yourself, you would have to make your code a lot more complicated, and as the database is already optimized for speed, it's better to just stuff it in the DB and let it handle it.
You could use a ternary operator to set the correct value.
$sql = "UPDATE `sp_members` SET `allow_test` = '"
. ( $_REQUEST['checkbox'] ? 1 : 0 )
. "' WHERE `id` = '" . mysql_real_escape_string( $member ) . "'";
It checks $_REQUEST['checkbox'] for a non-null, non-zero string and if true, returns 1, if false, returns 0.
(($_post['member']) ?$allow_test = 1 : $allow_test = 0;
$sql = "UPDATE `sp_members` SET `allow_test` = $allow_test WHERE `id` = '$member'";
The reason why this hasn't been working (and won't in the already provided answers) is because checkboxes that are not checked won't exist in the $_POST/$_REQUEST arrays. The other side of that is if they do exist, they must be true.
When you're doing the check to see what the value is, you are causing an error because the key to the array doesn't exist.
Instead, you need to know the available checkboxes and then check if each isset() in the array.
Webform:
<form action="foo.php" method="post">
<input type="checkbox" value="<?php echo $value1; ?>" name="checkbox1" />
<input type="checkbox" value="<?php echo $value2; ?>" name="checkbox2" />
<input type="submit" name="update" value="Update" />
</form>
PHP:
$checkboxes = array(
'column1' => 'checkbox1',
'column2' => 'checkbox2',
);
foreach ($checkboxes as $column => $checkbox)
{
$value = (isset($_POST[$checkbox]) ? 1 : 0);
$sql = "UPDATE `table` SET `$column` = '$value' WHERE `id` = '$member'";
}
When confronted with this, I usually punt and rely on a transaction to update this stuff for me. As you've discovered, unchecked checkboxes won't get submitted with the form, so you'd have to do tedious comparisons to figure out what's changed each time and build up an appropriate update and/or delete query sequence.
Instead, I fire up a transaction, delete all the old checkbox values stored in the DB, and then insert the new ones submitted with this request. Unless you've got the checkboxes acting as foreign keys and/or triggers set on them at the DB level, this is a relatively lightweight option and saves you the trouble of having to compare the old and new lists for changes.

Inserting checkbox values into database

I have a form with several checkboxes which values are pulled from a database.
I managed to display them in the form, assign an appropriate value to each, but cannot insert their values into other database.
Here's the code:
<form id="form1" name="form1" method="post" action="">
<?php
$info_id = $_GET['info_id'];
$kv_dodatoci = mysql_query("SELECT * FROM `dodatoci`") or die('ERROR DISPLAYING: ' . mysql_error());
while ($kol = mysql_fetch_array($kv_dodatoci)){
$id_dodatoci = $kol['id_dodatoci'];
$mk = $kol['mk'];
echo '<input type="checkbox" name="id_dodatoci[]" id="id_dodatoci" value="' . $id_dodatoci . '" />';
echo '<label for="' . $id_dodatoci.'">' . $mk . '</label><br />';
}
?>
<input type="hidden" value="<?=$info_id?>" name="info_id" />
<input name="insert_info" type="submit" value="Insert Additional info" />
</form>
<?php
if (isset($_POST['insert_info']) && is_array($id_dodatoci)) {
echo $id_dodatoci . '<br />';
echo $mk . '<br />';
// --- Guess here's the problem ----- //
foreach ($_POST['id_dodatoci'] as $dodatok) {
$dodatok_kv = mysql_query("INSERT INTO `dodatoci_hotel` (id_dodatoci, info_id) VALUES ('$dodatok', '$info_id')") or die('ERROR INSERTING: '.mysql_error());
}
}
My problem is to loop through all checkboxes, and for each checked, populate a separate record in a database.
Actually I don't know how to recognize the which box is checked, and put the appropriate value in db.
You can tell if a checkbox is selected because it will have a value. If it's not selected, it won't appear in the request/get/post in PHP at all.
What you may want to do is check for the value of it and work based on that. The value is the string 'on' by default, but can be changed by the value='' attribute in HTML.
Here are a couple snippets of code that may help (not exactly production quality, but it will help illustrate):
HTML:
<input type='checkbox' name='ShowCloseWindowLink' value='1'/> Show the 'Close Window' link at the bottom of the form.
PHP:
if (isset($_POST["ShowCloseWindowLink"])) {
$ShowCloseWindowLink=1;
} else {
$ShowCloseWindowLink=0;
}
.....
$sql = "update table set ShowCloseWindowLink = ".mysql_real_escape_string($ShowCloseWindowLink)." where ..."
(assuming a table with a ShowCloseWindowLink column that will accept a 1 or 0)
As an extra note: You're using the wrong HTML syntax for IDs and <label>. <label>'s "for" attribute should point to an ID, not a value. You also need unique IDs for each element. The code you have posted would not validate.
Also, you're not validating your code at all. At the very least, do a htmlspecialchars() or htmlentities() on the input before you output it and a mysql_real_escape_string() before you insert data into the DB.
2nd Answer:
You might do something like this:
HTML:
echo '<input type="checkbox" name="id_dodatoci[]" value="'.$id_dodatoci.'" />';
PHP:
if ( !empty($_POST["id_dodatoci"]) ) {
$id_dodatoci = $_POST["id_dodatoci"];
print_r($id_dodatoci);
// This should provide an array of all the checkboxes that were checked.
// Any not checked will not be present.
} else {
// None of the id_dodatoci checkboxes were checked.
}
This is because you are using the same name for all of the checkboxes, so their values will be passed to php as an array. If you used different names, then each would have it's own post key/value pair.
This might help too:
http://www.php-mysql-tutorial.com/php-tutorial/using-php-forms.php
This is the loop that I needed. I realized that I need a loop through each key with the $i variable.
if(isset($_POST['id_dodatoci'])){
$id_dodatoci=$_POST['id_dodatoci'];
$arr_num=count($id_dodatoci);
$i=0;
while ($i < $arr_num)
{
$query="INSERT INTO `dodatoci_hotel`(id_dodatoci,info_id)
VALUES ('$id_dodatoci[$i]','$info_id')";
$res=mysql_query($query) or die('ERROR INSERTING: '.mysql_error());
$i++;
}
}
Well, as Eli wrote, the POST is not set, when a checkbox is not checked.
I sometimes use an additional hidden field (-array) to make sure, I have a list of all checkboxes on the page.
Example:
<input type="checkbox" name="my_checkbox[<?=$id_of_checkbox?>]">
<input type="hidden" name="array_checkboxes[<?=$id_of_checkbox?>]" value="is_on_page">
So I get in the $_POST:
array(2){
array(1){"my_checkbox" => array(1){[123]=>"1"}}
array(1){"array_checkboxes" => array(1){[123]=>"is_on_page"}}
}
I even get the second line, when the checkbox is NOT checked and I can loop through all checkboxes with something like this:
foreach ($_POST["array_checkboxes"] as $key => $value)
{
if($value=="is_on_page")
{
$value_of_checkbox[$key] = $_POST["my_checkbox"][$key];
//Save this value
}
}
Also something that few people use but that is quite nice in HTML, is that you can have:
<input type="hidden" name="my_checkbox" value="N" />
<input type="checkbox" name="my_checkbox" value="Y" />
and voila! - default values for checkboxes...!

Categories