Just wondering if anyone can point out where I'm going wrong with the code below. I'm trying to gather the text from the form and UPDATE a field within the database with the text.
I have tested the SQL statement alone and it is updating the column correctly, but seems to be an issue with the PHP syntax as when i click on the submit button, it only insets '1' into the columns.
PHP:
$SubmitComments = isset($_POST['SubmitComments']);
$AddComment = isset($_POST['AddComment']);
if ($SubmitComments){
mysql_query ("UPDATE `table` SET `column` = '$AddComment' WHERE `column` = '$.....'") or die(mysql_error());
echo 'Comment added';
}
HTML:
<tr>
<td>Add Comment</td>
<td align="center"><form name="form1" method="POST" action=""><input name="AddComment" type="text" id="AddComment" autocomplete="off" placeholder="Add comments..." size="45px"><br />
<input type="submit" name="SubmitComments" id="SubmitComments" value="Submit"></form></td>
</tr>
Right, from the top. isset returns a bool, so $SubmitComments would only equal true or false, it will never equal the POST variable (Same with $AddComment). Consider instead:
if(isset($_POST['SubmitComments'])&&isset($_POST['AddComment']))
{
$SubmitComments = $_POST['SubmitComments'];
$AddComment = $_POST['AddComment'];
//Rest of Code
}
Second, table and column names do not need single quotes around them. And finally, as addressed in the comments, think about using MySQLi instead as if your script does eventually work, one malformed comment will erase your entire database.
Example:
If their comment is even just butts';-- It will make the SQL:
UPDATE table SET column = 'butts';--' WHERE column = '$.....'
Which is the equivalent of:
UPDATE table SET column = 'butts';
Making all of your comments just the word "butts", and that's just a humorously childish attack, compared to stealing usernames/passwords, trashing the database etc
Related
I have used an sql select statement to fill in a select field in an html form, now I would like to take the value generated by the select field and insert it into my foreign key column.
I have checked all my field names to make sure they are spelt correctly and double checked my code, I think there might be a problem with the 'escape_string', but I'm not sure how to fix it. I've tried to use 'intval' but it gives me errors. Line 86 it mentions is the '$result' line.
<?php
if( isset($_POST['submit']) )
{
$category_id = $mysqli->escape_string($_POST['fk_cat_port_id']);
$project_title = $mysqli->escape_string($_POST['proj_title']);
$description_brief = $mysqli->escape_string($_POST['des_brief']);
$description_steps = $mysqli->escape_string($_POST['des_steps']);
$description_conclusion = $mysqli->escape_string($_POST['des_conclusion']);
$project_link = $mysqli->escape_string($_POST['proj_link']);
$project_date = $mysqli->escape_string($_POST['proj_date']);
$disclaimer = $mysqli->escape_string($_POST['disclaimer_rights']);
//insert into database
$query = "INSERT INTO
company_profile (fk_cat_port_id, proj_title, des_brief, des_steps,
des_conclusion, proj_link, proj_date,
disclaimer_rights)
VALUES ('$category_id', '$project_title', '$description_brief',
'$description_steps', '$description_conclusion',
'$project_link', '$project_date', '$disclaimer')
";
$result = $mysqli->query($query) or query_error($query, __LINE__, __FILE__);
}
?>
<div class="form-group">
<label for="fk_cat_port_id">Choose Category:</label>
<select class="form-control" name="fk_cat_port_id" value="">
<?php
$query_cat = "SELECT id_cat_port, port_cat_name
FROM portfolio_categories
ORDER BY port_cat_name DESC";
$result_cat = $mysqli->query($query_cat);
if(!$result_cat)
{
query_error($query_cat, __LINE__, __FILE__);
}
// Do while loop to create option for each row in the database
while ($row_cat = $result_cat->fetch_object())
{
echo '<option value="' . $row_cat->id_cat_port . '">' . $row_cat->port_cat_name . '</option>';
}
?>
</select>
</div>
Unknown column 'fk_cat_port_id' in 'field list' Line:86
File:/customers/b/f/b/tabithabjorkman.com/httpd.www/admin/pages/portfolio_create.php
INSERT INTO
company_profile (`fk_cat_port_id`, `proj_title`, `des_brief`, `des_steps`, `des_conclusion`, `proj_link`, `proj_date`,
`disclaimer_rights`)
VALUES ('2', 'test', 'test',
'test', 'test', 'www.test.rg', '2019-10-21T11:09:43', 'test')
screenshot of database
I'd like to thank those who took the time to try to answer my question.
After looking over it again and again, I found the answer.
There was an error in the sql query and I had put the wrong table name in the query. The wrong table name was similar enough that it got through my checks.
However, I learned a lot about working with stackoverflow, so no regrets and since I use this platform a lot to get answers to problems, I hope that my mistake here can help someone else to remember to check EVERYTHING and remember that it's worth it to make the extra effort to name your tables, classes, ids, etc. using the naming conventions as a guide.
https://launchbylunch.com/posts/2014/Feb/16/sql-naming-conventions/
your query is correct so check column name in your table.
I have tried many different solutions to no avail you will see the attempts.
The columns in question are tinyint 1 pass and 0 fail. From poweradapter down. The textarea goes into the database just fine. I've tried enumerating the boolean and print_r($_POST and now im just lost.
*Also put through mysqli_real_escape
if (isset($_POST['submit'])) {
$tester = $_POST['tester'];
$manufacturer = $_POST['manufacturer'];
$model = $_POST['model'];
$serial = $_POST['serial'];
$poweradapter = $_POST['poweradapter'];
$query = "INSERT INTO tested (tester, manufacturer, model, serial, poweradapter)
VALUES ('$tester','$manufacturer','$model','$serial','$poweradapter');";
<div class="fb-radio-group form-group field-poweradapter"><label for="poweradapter" class="fb-radio-group-label">Power Adapter<span class="fb-required">*</span><span class="tooltip-element" tooltip="Plug into Laptop - Charges the Battery">?</span></label>
<div class="radio-group"><div class="radio"><label for="poweradapter-0"><input name="poweradapter" id="poweradapter-0" required="required" aria-required="true" value="1" type="radio">Pass</label></div>
<div class="radio"><label for="poweradapter-1"><input name="poweradapter" id="poweradapter-1" required="required" aria-required="true" value="0" type="radio">Fail</label></div>
</div></div>
Unless MariaDB works quite a bit differently than regular MySQL, it looks to me like you are only storing a MySQL statement in a variable without actually executing it.
You may want to do something like:
$query = $db->query("INSERT INTO tested (tester, manufacturer, model, serial, poweradapter)
VALUES ('$tester','$manufacturer','$model','$serial','$poweradapter')";
With $db containing your database connection.
So I suppose I'll just rewrite the form as the issue isn't the radio button entirely rather when I mix one of the textareas with it. Thank you all
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.
I'm trying to creat a form dynamically depending on the number of rows of a table in a database. I tried this and it's nor working:
require_once('mysqli_connect.php');
//I select the colum w_spanish from the table selected by the user
$q="SELECT w_spanish FROM ".$_GET['name'];
$r=#mysqli_query($dbc, $q);
echo '<FORM METHOD="POST" ACTION="Correction.php">';
echo '<TABLE BORDER="1">';
//Here is where I generate dinamically a table that can be filled by user
while ($row=mysqli_fetch_array($r, MYSQLI_ASSOC)){
$aux=$row['w_spanish'];
echo '<TR><TD>'.$aux.'</TD><TD><INPUT TYPE="TEXT" NAME="Sol_'.$aux.'" SIZE="20"></TD></TR>';
}
echo '</TABLE>';
echo '<P><INPUT TYPE="SUBMIT" VALUE="Submit" ></P></FORM>';
mysqli_close($dbc);
So when I press submit, the information is not sent to "Correction.php", and I think it's because I creating the HTML form inside php code. How could I do it right??
First off - remove the # from the #mysqli statement as it is masking any errors that maybe happening.
Secondly take the generated code and paste it into http://validator.w3.org/#validate_by_input and see if there are any HTML errors and adjust where necessary.
Thirdly, since the user can select which table to read then your data needs to be super-sanitised as you certainly don't want sql injection attacks here.
The problem may be the query you are running. Without knowing more information, my guess would be your query isn't getting anything. Try dumping the row in each iteration and see what spits out. You may be looking for something like:
$q="SELECT w_spanish FROM tableName WHERE name = " . $_GET['name'];
If that's not it, it could also be the fact that since you are only grabbing one column from the database, you don't need access the information with $aux=$row['w_spanish'];. You can just use:
$aux=$row;
That I'm not 100% on though. Try dumping each row with var_dump() and see what pops out.
First declare $row, then use a do-while loop.
$row = mysqli_fetch_array($r, MYSQLI_ASSOC) do{
$aux=$row['w_spanish'];
echo '<TR><TD>'.$aux.'</TD><TD><INPUT> TYPE="TEXT"NAME="Sol_'.$aux.'" SIZE="20"></TD></TR>';
}while ($row=mysqli_fetch_array($r, MYSQLI_ASSOC))
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).