Changing MySQL TINYINT(1) with an html checkbox and PHP - php

I am trying to change the bool preset in MySQL using an html form which calls to a PHP page to input the information into the table.
Here's the code:
addEvent.php
$all_day = mysqli_real_escape_string($con, $_POST['all_day']);
if ($all_day != '1')
{
$all_day = '0';
}
$sql="INSERT INTO db . table (title, start, end, all_day)
VALUES ('$title', '$start', '$end', '$all_day')";
html form:
All Day?: <input type="checkbox" name="all_day" inputValue="1">
The issue I am having is that no matter what I try and do the value of "$all_day" isn't changing from 0 to 1. If anyone could point out the issue it would be much appreciated.

You are using a wrong attribute. Use value="" instead of inputValue.
$con = new mysqli('localhost', 'username', 'password', 'database');
if(isset($_POST['submit'])) {
$all_day = isset($_POST['all_day']) ? $_POST['all_day'] : 0;
// defaults to 0 if not checked
$prepare = 'INSERT INTO `table_name` (title, start, end, all_day) VALUES (?, ?, ?, ?)';
$stmt = $con->prepare($prepare);
// assuming $title, $start, $end is declared on your end
$stmt->bind_param('sssi', $title, $start, $end, $all_day);
$stmt->execute();
if($stmt->affected_rows > 0) {
// inserted
} else {
// it did not insert
}
}
?>
<form method="POST">
<!-- inputValue? no! the correct attribute is "value" -->
All Day?: <input type="checkbox" name="all_day" value="1">
<input type="submit" name="submit" />
</form>
Just to clear things:
That checkbox value will not change to zero if the checkbox is unchecked, what happens is upon form submission, if that checkbox is unchecked, it will be undefined in $_POST.
So if it is checked, just get the value, if not, just default to 0.

Use mysqli_real_escape_string() for strings. all_day is not a string. You should convert it to 0 or 1 with $all_day = (int)(bool)$_POST['all_day'] instead. It will be automatically set to 0 if empty or 0 and 1 if anything else.
Howover, note that if the checkbox is not checked, $_POST['all_day'] is not set at all and reading it will throw a Notice (that might be suppressed depending on your PHP settings). So you might want to do this instead:
$all_day = (int)isset($_POST['all_day']);

Try changing inputValue to value:
<input type="checkbox" name="all_day" value="1">

Thats nothing to do with php. It can be done by using value="" attribute. It specifies the value of an element. Use the code given below
All Day?: <input type="checkbox" name="all_day" value="1">

You are assigning during your if clause
If ($var! = '1')
You are doing two things wrong.
1) assigning var to 1 where you should be using !==
And 2) trying to validate var as a string instead of an integer (lose the quotes)

Related

Handling Nulls from form input to SQL

So,
I am trying to create dynamic SQL queries where we assume:
If the _GET or _POST doesn't have a variable set we call it NOT SET
If the _GET or _POST is set but the value is empty then we call it EMPTY
If the _GET or _POST is set but the value is not empty then we call it NON-EMPTY
Now we can easily store the EMPTY and NON-EMPTY variables in MySQL as they are (because we know the intention of the end user since the variables have been set)
OUR Mapping so far:
EMPTY & NON-EMPTY = whatever the value is...
(for date column in MySQL since it doesn't allow empty we put in 0000-00-00 00:00:00. We use this logic for both the INSERTS and UPDATES
NOT-SET in PHP = NULL in database? (since we don't know anything about the value)
Now this works perfectly for situations where data doesn't already exist for example INSERT statements, but what about UPDATE STATEMENTS?
What if the record already has a value?
I am thinking of using NOT SET variable as to be ignored in UPDATE statements?
So if, lets say POST["name"] is not set on INSERT, then we still insert it as a null
INSERT INTO person (name) VALUES (POST["name"]);
but, if it is an UPDATE statement, we ignore it completely.
UPDATE person
isNull(POST["name"]) ? SET name = POST["null"]
My dilemma is what do we do for INSERTS and UPDATES when these variables are NOT SET?
<html>
<body>
<form method="post">
<label for="field_1">Field 1</label>
<br />
<input type="text" name="field_1">
<br />
<br />
<label for="field_1">Field 2</label>
<br />
<input type="text" name="field_2">
<br />
<br />
<label for="field_1">Field 3</label>
<br />
<input type="text" name="field_3">
<br />
<br />
<input type="submit" name="submit" value="submit">
</form>
<?php
// BASIC IDEA:
// (This example assumes all incoming post values are strings,
// if you have, for example, integers, you'd need to remove the
// single quotes around the values in the SQL statement)
// Loop through POST array
// foreach _POST variable as key => value
foreach($_POST as $k => $v) {
// if not null, blank, or "submit"
if(!is_null($v)&& $v != ''&& $v != 'submit') {
if(!isset($strSQL)) {
// If this is the first value, start off the sql string w/ UPDATE
$strSQL = "UPDATE your_table " ."SET " .$k ." = '" .$v ."'";
} else {
// For subsequent values, include a comma and space before new value
$strSQL = $strSQL ."', SET " .$k ." = '" .$v ."'";
}
}
}
// Finish off SQL Command, if one was ever started
if(isset($strSQL)){
$strSQL = $strSQL ." WHERE some_field meets_your_conditions;";
// Run SQL Command (echo just used for example)
echo $strSQL;
}
?>
</body>
</html>
In case of no set:
Insert:
INSERT INTO person (name) VALUES (NULL);
Update:
Don't call update if no set as the value can either be :
1) Null : If null no need to update it
2) Not Null: If not null, then you will be loosing values if you assign it null.
PS: This is my suggestion as per understanding of the requirement, but
it may differ as per actual requirements.

Save datas from multiple checkbox in a database

2 Questions about saving data from multiple checkbox (I have few of them in my form) in a database with PDO (PHP). I just show the relevant parts of the code to make it more simple for everyone.
A) The code I wrote works (still saving all data correctly) but it gives me still a failure message, which you can see below. Why, or what can I do better?
B) It saves the checked checkboxes as an array in the database. Later on I want to change data by getting the data from the database back into my original form - will it make problems, if its saved like an array? If yes, what would you recommend to do then better.
Warning: implode ( ) : Invalid arguments passed on line ... for
$p2 = implode(',',$product_2);
$p3 = implode(',',$product_3);
$p1 = implode(',',$product_1); which I defined first seems to be fine
<?php
if(isset($_POST['send']))
{
require("php/tconnect.php");
$id = $_POST['id'];
$name = $_POST['name'];
$date = $_POST['date'];
$p1 = implode(',',$product_1);
$p2 = implode(',',$product_2);
$p3 = implode(',',$product_3);
$sql = "INSERT INTO database (id, name, date) VALUES (:id, :name, :date, '$p1', '$p2', '$p3')";
$stmt = $dbh->prepare($sql);
$stmt->bindValue(':id', $id);
$stmt->bindValue(':name', $name);
$stmt->bindValue(':date', $date);
$stmt->execute();
echo "Datas saved";
}
?>
HTML
<input type="checkbox" name="product_1[]" value="apple" id="product_1_apple">
Apple
</label>
<label class="checkbox-inline">
<input type="checkbox" name="product_1[]" value="Banana" id="product_1_banana">
Banana
</label>
and the next tables looks similar
<input type="checkbox" name="product_2[]" value="water" id="product_2_water">
Water
</label>
<label class="checkbox-inline" >
<input type="checkbox" name="product_2[]" value="juice" id="product_2_juice">
Juice
</label>
Since $product_1, $product_2 and $product_3 seems to be related with the input arrays from the HTML I suppose that you have in another part of the code something like this:
$product_1 = $_POST['product_1'];
$product_2 = $_POST['product_2'];
$product_3 = $_POST['product_3'];
Now, the problem is that those variables are related to an array of checkboxes, but when no checkbox is selected in the page for a group, instead of getting an empty array for that group the array is not added to $_POST (you can see it using var_dump($_POST)).
I suspect that in your tests you were only marking checkboxes for product_1, so you get an array for that product but no for the other ones. To prevent the error you can fill each of the products variables using something like this:
if(isset($_POST['product_1'])) // if the array is defined in $_POST
$product_1 = $_POST['product_1']; // fill with the array from the form
else $product_1 = array(); // fill with empty array, you get the empty string with implode()
// repeat for product_2 and product_3
Also, you are mixing prepared statements, which are good, with inserting the values directly in the query string, which is bad because it can lead to SQL Injection, you should use bindValue() for all the values of the table:
$sql = "INSERT INTO database (id, name, date) VALUES (:id, :name, :date, :p1, :p2, :p3)";
$stmt = $dbh->prepare($sql);
$stmt->bindValue(':id', $id);
$stmt->bindValue(':name', $name);
$stmt->bindValue(':date', $date);
$stmt->bindValue(':p1', $p1);
$stmt->bindValue(':p2', $p2);
$stmt->bindValue(':p3', $p3);

Updating to database using php

The only way I got this to work was if I used the empty. However, this is not what I want. I want to be able to leave something empty if I have to. Does anyone know how I should change the code for this to work?
Edit page:
<form name="homePage" action="update.php" method="POST">
<Strong>Change home title:</Strong>
<p>
<input style="width: 300px;" type="text" name="homeTitleChange" value="<?php echo $homeTitle ?>">
<input type="hidden" name="rowHomeID" value="<?php echo $getHomeID?>">
</p>
<Strong>Change home subtitle:</Strong>
<p>
<input style="width: 600px;" type="text" name="homeSubtitleChange" value="<?php echo $homeSubtitle ?>">
<input type="hidden" name="rowHomeID" value="<?php echo $getHomeID?>">
</p>
<input type="submit" class="btn btn-skin" name="homepage" value="save" />
</form>
Query Page:-
include("../conn.php");
include("../conn.php");
if(isset($_POST['homepage'])){
if(
!empty($_POST["homeTitleChange"])&&
!empty($_POST["homeSubtitleChange"]) &&
!empty($_POST["rowHomeID"])
){
$homeTitleUpdate = $_POST["homeTitleChange"];
$homeSubtitleUpdate = $_POST["homeSubtitleChange"];
$homeEditRow = $_POST["rowHomeID"];
$query = "UPDATE Home SET
title = '$homeTitleUpdate',
subtitle ='$homeSubtitleUpdate'
WHERE homeID = '$homeEditRow' ";
$result = mysqli_query($conn, $query) or die(mysqli_error($conn));
if ($result) {
echo "<p> - Success!</p>";
}else{
echo "<p> - Something went wrong</p>";
}
}
}
Thanks!
Precursors:
You have included your connection script twice.
You are including the hidden form field <input type="hidden" name="rowHomeID" value="<?php echo $getHomeID?>"> twice. This is inefficient.
Your form should have enctype='multipart/form-data' . Read Here
Without seeing your MySQL error we can't absolutely diagnose your problem, so instead I will give you the parts I know need to be fixed:
By default PHP string types will hold an empty string '' rather than a NULL value so I don't think your issue is empty values being inserted incorrectly (at least, not as described in your question).
$homeEditRow is the only required value. Because UPDATE table SET column=value WHERE column=<empty> will result in an error (or at the very least, no update).
Therefore replace:
if(
!empty($_POST["homeTitleChange"])&&
!empty($_POST["homeSubtitleChange"]) &&
!empty($_POST["rowHomeID"])
)
with:
if(!empty($_POST["rowHomeID"]){
//run MySQL Update query.
}
Also, if the value is meant to be an integer, you can simply do this:
$homeEditRow = (int)$_POST['rowHomeID']; //force to int.
if($homeEditRow > 0 ){
//run MySQL Update query.
}
Your other two values can be empty if you wish, that's fine.
BUT what these values can not contain is unescaped special characters in MySQL, typically (but by no means exclusively) ` , ', --, # characters.
So, it's best to clean unsafe characters from your user input.
Never Ever Trust User Input to be "safe"
$homeTitleUpdate = mysqli_real_escape_string($conn,$_POST["homeTitleChange"]);
$homeSubtitleUpdate = mysqli_real_escape_string($conn,$_POST["homeSubtitleChange"]);
//assuming to be integer required
$homeEditRow = (int)$_POST["rowHomeID"];
This means any single quotes, or other unsafe characters do not interefere with your query execution. using Prepared statements is much safer than this method and is the recommended way of doing these things, you can use either PDO or MySQLi and there are many, many fine examples on Stack Overflow of these systems.
If you reach this point and you are still having issues, then you need to read what your MySQL error output is saying to you :
//after your query regardless of outcome:
var_dump(mysqli_error($conn));
You may have issues such as you have a primary index column with two non-unique values (etc, etc). But we won't know for sure until you can output the MySQL error.
Finally, be careful with your IF statements checking if the Update Query was carried out because if nothing changed, there was no change to update, MySQL will not run the query, so could potentially return false when everything in fact ran correctly.
Without specifying your errors, we can only assume your problem. Only you can debug your program, so for future notice please execute the following lines of code at the top of your scripts and tell us your errors.
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
Moving on, your script contains a condition that checks the values at the index in $_POST is !empty() but doesn't wrap around your Query. This meaning, whether or not the values are empty or set, your query will execute.
Assuming you only want to the query to run when there are values set, you can wrap this with an if expression:
// an array of all the index's
$index = ['homeSubtitleChange', 'homeTitleChange', 'rowHomeID'];
// loop through each index and check they're not empty
foreach($index as $_index)
{
if( empty( $_POST[$_index] ) && !isset( $_POST['homepage'] ) )
{
// if empty - halt the program with an error
die("Expected POST index: $_index or homepage.");
}
}
unset($_index); //cleanup
// if it got here - all index's have values
// as Martin said in the comments, I assume you can wrap mysqli_real_escape_string()
// and intval() ensuring the value is type (int) to protect
// your database against SQL attacks
$subtitle = mysqli_real_escape_string($conn, $_POST[$index[0]]);
$title = mysqli_real_escape_string($conn, $_POST[$index[1]]);
$row_id = intval($_POST[$index[2]]);
// consider upgrading to a PDO driver and using prepare() statements
// this SQL statement is prone to SQL injections
$sql = "UPDATE Home SET title = '$title', subtitle = '$subtitle' WHERE homeID = '$row_id'";
if( mysqli_query( $conn, $query ) )
{
die("Success.");
}
die("Failed.");
If I understand correctly, you want to allow empty string as input.
If so, what you want is isset() instead of !empty().
So, this part in your code:
!empty($_POST["homeTitleChange"])&&
!empty($_POST["homeSubtitleChange"]) &&
!empty($_POST["rowHomeID"])
replace it with this:
isset($_POST["homeTitleChange"],$_POST["homeSubtitleChange"],$_POST["rowHomeID"])
and you're good to go.
As everyone else has said, please sanitize your user input; putting it directly into the database like that is very unsafe.
As for your question, from what I can understand you are trying to work out to make sure the values are set, but you also want to be able to pass an empty string!?
If so, I think you want isset.
//...
if(
isset($_POST["homeTitleChange"])&&
isset($_POST["homeSubtitleChange"]) &&
isset($_POST["rowHomeID"])
){
//...
This will make sure you POST values are set, which they should be anyway if they submitted the form; however it will also return true if the $_POST["rowHomeID"] = 0, which may not be what you want, so you may want to go back to using !empty for that which will mean it can't be an empty string or equal to 0.

default value for $_POST[];

I have a problem with default value for $_POST[];
So i have a html form with textboxes and the informations is sent to a php script. The php script has a sql query that is being sent to my database. But if my textbox in html form is empty the query doesnt have a value. So i want to set my post to a default value 0 so it returns a value atleast.
So here is an example of html form (This is not my actuall script. Just an example.
<form action="testscript.php" method="POST">
<input type="id" name="ID"/>
<input type="text" name="test"/>
<input type="submit" value="Send"/>
</form>
Ok so this script will send both id and test textboxes will always have a number value. And it sends the information to testscript.php
Here is testscript.php example
$conn = mysqli_connect('host', 'dbuser', 'dbpass', 'dbname');
$id = $_POST['id'];
$test = $_POST['test'];
$sql = "INSERT INTO test_table (id, test) VALUES ($id, $test)";
if (mysqli_query($conn, $query)) {
echo "Success";
} else {
echo "Failed" . mysqli_error($conn);
}
Alright so now if i submit my html form to php script without inserting any text to the textboxes the query will look like this
INSERT INTO test_table (id, test) VALUES ( , )
But the query should be like this
INSERT INTO test_table (id, test) VALUES (0, 0)
So. I know i can use value attribute in the html tag but then the value will be visible in the textbox and i dont want that.
And i know i can do an if statment to make a default value like this
if (isset($_POST['test'])) {
$test = $_POST['test'];
} else {
$test = 0;
}
But now the problem is that i would have to do that if statment for every textbox and my html form have more than 100 textboxes. So i dont want to make an if statment for every textbox because then my script will be way to big and it will take hours.
So is there any way to set a default value for all the textboxes without using if statment in php or value attribute in html form?
I know it seems like a pain but you MUST check that all inputs are valid. You can simplify the amount of code by using a ternary operator like this.
$id = isset($_POST['id']) ? $_POST['id'] : 0;
$test = isset($_POST['test']) ? $_POST['test'] : 0;
....
And no, it won't take hours even with hundreds of them.
To make this slightly less painful to code you can use the power of looping with PHP's variable variables
The most painful part will be creating an array with all your field names
$fields = array('id', 'test', 'extra', 'more', ..., 'one_hundred');
Then loop through that array creating variable names and at the same time escaping the strings - if they are there - otherwise set a value of 0 (zero). You might want/need to set this to "" (empty string)
foreach($fields as $field_name)
{
${$field_name} = isset($_POST[$field_name]) ? mysqli_real_escape_string($conn, $_POST[$field_name]) : 0;
}
You now have the variables $id, $test, $extra, $more, ...., $one_hundred available for your use.
If your checkboxes have unique names, then you'll need to check them on the server side to see if they actually have values in them one by one by using the ternary
isset($_POST["test"]) ? $_POST["test"] : 0
However, if your checkboxes are in array form:
<input type="checkbox" name="courses[]" value="1">
<input type="checkbox" name="courses[]" value="2 >
Then you could do the following:
foreach($_POST['courses'] as $course) {
echo $course; // etc etc etc
}
You can also set database defaults.
Another note, your code is prone to SQL injection. Although the question you have might simply be an example, you might just keep in mind there are better and safer ways of querying a database see PDO connections.
You can easily use null check and define your default value like this :
$name = $_POST['name'] ?? 'John';
in my case the default value is John if the name is not defined. It gives the same result like this :
$name = isset($_POST["name"]) ? $_POST["name"] : 'John';

How to combine "add" and "edit" forms into 1 "script"?

I've always found myself creating two separate php files/scripts for adding a certain data and editing this data. These files weren't that much different, so I figured there should be a way how to make them into one file.
Here I'll present a very simple example to illustrate my point:
add.php:
<?php
$title = $_POST['title']; // ignore the unescaped data, this is a simple example
$text = $_POST['text'];
mysqli_query($connection,
"INSERT INTO `articles` (`title`, `text`) VALUES ('$title', '$text')");
echo'
<form>
<input type="text" name="title" value="'.$_POST['title'].'" />
<input type="text" name="text" value="'.$_POST['text'].'" />
<input type="submit" value="Add" />
</form>
';
?>
edit.php:
<?php
$id = $_GET['id'];
$title = $_POST['title']; // ignore the unescaped data, this is a simple example
$text = $_POST['text'];
// save data
mysqli_query($connection,
"UPDATE `articles` SET `title` = '$title', `text` = '$text'
WHERE `id` = $id");
// get current data
$q = mysqli_query($connection,"SELECT * FROM `articles` WHERE `id` = $id");
$d = mysqli_fetch_array($q);
$title = $d['title'];
$text = $d['text'];
echo'
<form>
<input type="text" name="title" value="'.$title.'" />
<input type="text" name="text" value="'.$text.'" />
<input type="submit" value="Add" />
</form>
';
?>
As you can see, the add and edit forms/codes are very similar, except that:
add inserts the data, while edit updates it
add inserts $_POST values into the form (if there's an error, so that the submitted data remains in the form, while edit inserts the current database values into the form (after the save is complete and the page refreshes, so that the form has the current db values)
Can these two somehow be merged into one file/code, so that if I want to add/change the form values, I don't need to edit two files separately, but will change the form only once?
You can use a INSERT ON DUPLICATE KEY UPDATE which roughly gave you :
<?php
$id = $_GET['id'];
$title = $text = '';
if ($_POST)
{
$title = $_POST['title'];
$text = $_POST['text'];
// save data
$query = "INSERT INTO `articles` (`id`, `title`, `text`)
VALUES ('$id', '$title', '$text')
ON DUPLICATE KEYS UPDATE title = title, text = text"
mysqli_query($connection, $query);
}
else if ($id)
{
// get current data
$q = mysqli_query($connection, "SELECT * FROM `articles` WHERE `id` = $id");
$d = mysqli_fetch_array($q);
$title = $d['title'];
$text = $d['text'];
}
echo '
<form>
<input type="text" name="title" value="'.$title.'" />
<input type="text" name="text" value="'.$text.'" />
<input type="submit" value="Add" />
</form>';
If it's a POST and no $id present : a new row is inserted just like an INSERT.
If it's a POST and an $id is present : if $id already exist in the table than the row is updated otherwise it's an INSERT.
If you only have an $id : show the form with existing data in it.
If it's not a POST and $id isn't populated : show an empty form.
You could use a combination of GET and POST parameters do achieve what you want. Use the GET parameters to distinguish between edit and add, i.e. /post?action=add or /post?action=edit. Based on the value of $_GET['action'] you'd know whether to render an empty form to add a post or to populate the form in with data from the DB. Then you could have a hidden field in your form, which you'd fill in with the value of $_GET['action'] and so you'd be able to know whether to INSERT or UPDATE when processing the form after submitting it.
It might be worth though to start using some framework, i.e. CakePHP, CodeIgniter, Zend Framework, etc.
I tend to make an interface for inserting and updating data which has only one method for inserting and updating. The key point for that to work is the user form that is being submitted must contain the id of the row being updated.
public method save( Object obj )
if obj.id is in database
query = "update table set attrA = obj.a, attrB = obj.b where id=obj.id"
else if obj.id < 1
query = "insert into table (a,b,c) values (obj.a,obj.b,obj.c)"
This implies that when you create a new object to be submitted, it must have id initialized to 0 or -1 (1 is the first key row for a table with int primary keys). Likewise, a form in a html file must have an <input type=hidden value=row.id name=DBID> that is populated either with a default value (null, 0, -1) or a valid id of the object being edited.
Essentially this means that the user may update arbitrary rows in the table, but granted they have authenticated themselves, this should not be a problem. Also, it is usually enough to know that the id > 0 to to an INSERT, and UPDATE otherwise. It is not necessary to verify that the id being submitted is in the database table, because when you insert you do not set the id, but rather let the DB auto-increment the primary key.
update
wow so many silly typos after only 3 beers. I hope this is readable
Here's an idea how it should look like using OOP (in my opinion).
Let's assume you have some class that represents form element called FormElement.
Then you have some generic form that should support what? Let's assume MVC:
displaying itself
adding elements
setting default values
parsing request values
getting values
validating values
So you'll build yourself an interface like
interface IForm {
public function Display();
public function AddElement( FormElement $element);
public function SetValues( array);
public function FetchPostValues();
public function GetValues();
public function Validate();
}
Then, what's common for both those forms (let's say that you want to prohibit change of email)? Everything except FetchPostValues()
So you'll build a class with one pure virtual method which will do everything that is similar:
abstract class FormArticle implements IForm {
// All methods implemented except FetchPostValues
abstract public function FetchPostValues();
}
And then just build two small classes that will define how to fetch post data:
class FormArticleEdit extends FormArticle {
public function FetchPostValues(){
if( isset( $_POST['email'])){
throw new Exception('What are you trying to achieve?');
}
// ...
}
}
And one more tip (two actually):
Implement abstract class like FormAbstract that will provide all generic methods like AddElement(), Display(). This will save you copying of those general methods every time, but will still provide you with ability to start from scratch (when using database or so directly to cache items).
Rather use framework that already has model for reusing forms (Zend is my personal favorite).

Categories