This question already has answers here:
When to use single quotes, double quotes, and backticks in MySQL
(13 answers)
Closed 7 years ago.
So, I want to upload a file and choose (for example) "Value 1" from select tag. And then when I click Publish button I want from script to check if I selected Value 1, and if I did, then I want to put the file ("file_name") it in column "columndb", if I selected Value 2 I want to put it in some other column and so on.
<div><input type="file" name="file_name">
<div><input type="file" name="inputname">
<select id="select_id" name="select_name">
<option value="null">None</option>
<option value="value1" name="value1name">Value 1</option>
<option value="value2" name="value2name">Value 2</option>
</select></div>
<div>
<div><input type="submit" name="submit" value="Publish"></div>
</div>
<?php
if(isset($_POST['submit'])){
$filename = $_FILES['file_name']['name'];
$filename_tmp = $_FILES['file_name']['tmp_name'];
$select_tag = $_POST['select_name'];
move_uploaded_file($filename_tmp, "somewhere/$filename");
if($select_tag == 'value1name'){
$insert_db = "insert into mydb ('columndb') values ('$filename')";
$run_db = mysqli_query($db, $insert_db, MYSQLI_STORE_RESULT);
}
}
?>
Options shouldn't have names, only values.
So you would verify as follows:
if($select_tag == "value1")
{
//...
//You're also using apostrophes in the query, on the column name, which is wrong.
//Change to this:
$insert_db = "insert into mydb (`columndb`) values ('$filename')";
}
If $select_tag is correctly holding the 'value' of your selection as the column name, then the following should be suitable:
$insert_db = "insert into mydb (`$select_tag`) values ('$filename')";
As a note though, using the value from the form as the column name is very bad security-wise. Someone malicious could manually submit a value which causes data to be put into another field, or perform an sql injection (because you do not escape the $select_tag or $filename before performing your SQL query.
You'd be better off having a block of 'if' statements, or a 'switch', which chooses a column depending on a predefined set of values.
Example:
$target_column = ""; // input column
switch($select_tag) {
case "column1":
$target_column = "columndb";
break;
case "column2":
$target_column = "anothercolumn";
break;
default:
$target_column = "column1";
break;
}
$filename = mysql_escape_string($filename); // mysql_escape_string is deprecated in later php versions... Use an alternative like mysqli_real_escape_string()
$insert_db = "insert into mydb (`$target_column`) values ('$filename')";
$run_db = mysqli_query($db, $insert_db, MYSQLI_STORE_RESULT);
if ($_POST['select_tag'] == 'Something') {
I think this is what you want
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 am referencing to a question here: Can I concatenate multiple MySQL rows into one field?
In this question multiple rows of a column are listed and separated by a "," using the GROUP_CONCAT function. I want to achieve something in reverse by concatenating multiple user inputs into a single database entry. Something like this:
<form action="server.php" method="POST">
<div>
<input type="text" name="value1">
<input type="text" name="value2">
<input type="text" name="value3">
<button type="submit" name="submit">submit</button>
</div>
</form>
and php:
<?php
if (isset($_POST['submit'])) {
$value1 = mysqli_real_escape_string($conn, $_POST['value1']);
$value2 = mysqli_real_escape_string($conn, $_POST['value2']);
$value3 = mysqli_real_escape_string($conn, $_POST['value3']);
$sql = "INSERT INTO database (col1)
VALUES GROUP_CONCAT('$value1', '$value2', '$value3');";
mysqli_query($conn, $sql);
header("Location: ../web_page/client_database_page.php?add_client=success");
}
?>
I know some of you will say that it would not be good practice to do this and I should have an individual column for each user input, however there is a reason for not doing it this way. The user inputs are added based on the number of variables from another database. In this database a user can insert additional user inputs from the website, but it would not automatically add a column to the input database. So a single column row should be able to contain all the user inputs and than later be separated for interpretation when called from the database.
Anybody have any ideas?
How about grouping your input values as an array then using implode() function in PHP before you insert into DB, like:
<form action="server.php" method="POST">
<div>
<input type="text" name="values[]">
<input type="text" name="values[]">
<input type="text" name="values[]">
<button type="submit" name="submit">submit</button>
</div>
</form>
Then, in PHP:
if (isset($_POST['submit'])) {
$values = $_POST['values'];
$escaped_values = array_map([$conn, 'mysqli_real_escape_string'], $values);
$concat_values = implode(",", $escaped_values);
$sql = "INSERT INTO database (col1) VALUES ('$concat_values');";
mysqli_query($conn, $sql);
header("Location: ../web_page/client_database_page.php?add_client=success");
}
Here, I used comma , as separator on each values. Just change it to your preference.
EDIT:
Another solution would be to use JSON for this so you can easily access the data when retrieved. Depending on your MySQL version, you can use the JSON data type for the col1 column/field.
ALTER TABLE `table_name` CHANGE COLUMN `col1` `col1` JSON;
Then modify the code to:
$json = json_encode($_POST['values']);
$sql = "INSERT INTO database (col1) VALUES ('$json');";
And then later when you retrieve the data you can do something like:
$values = json_decode($row['col1'], true);
Which you can then iterate to echo multiple <input> tags with values taken from the db.
You can simply concat values using PHP. No need to use GROUP_CONCAT for this.
Try code like below:
$sql = "INSERT INTO database (col1) VALUES ('$value1 $value2 $value3');";
Note: Values can be separated by comma , or any other separator instead of space.
I'm looking for a way to get lots of user inputs, concatenate them into one sql query, and return the results from my database. I have tried a few different techniques so far including putting all the variables into an array then using implode() but I couldn't get it to work. For simplicity sake I have decided to just go with a couple of if statements to check if each variable has a value in it or not. If it does then it should add some sql. My error message from this is as follows:
You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use
near 'AND type = AND (city LIKE '%%') OR (addressLineOne LIKE
'%%') OR (`addres' at line 1
It appears that $type is not being picked up even though I gave it a input during the test. I have not given any other inputs values besides $type and $bedroom.
Any help and improvement on the code would be greatly appreciated. I'm new to PHP and SQL so sorry if it's something stupid, but I have tried to fix this for ages.
HTML
<form action="searchresults.php" method="get">
<fieldset>
<legend><h3>Search</h3></legend>
<p>Please enter criteria for your search.</p>
<label for="location">Location</label>
<input type="text" name="location" />
<select name="type">
<option value="Studio Flat" selected>Studio Flat</option>
<option value="Flat">Flat</option>
<option value="Detached">Detached</option>
<option value="Semi-detached">Semi-detached</option>
<option value="Terraced">Terraced</option>
<option value="Bungalow">Bungalow</option>
</select>
<label for="bedroom">Bedrooms</label>
<select name="bedroom">
<option value="1" selected>1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
<option value="9">9</option>
<option value="10">10</option>
</select>
<label for="min">Min Price</label>
<input type="number" name="min" />
<label for="max">Max Price</label>
<input type="number" name="max" />
<br />
<input type="submit" value="Search" />
</fieldset>
</form>
PHP
<?php
session_start();
include './auth.php'; // connection to db
$location = trim($_POST['location']);
$location = strip_tags($location);
$location = htmlspecialchars($location);
$bedroom = trim($_POST['bedroom']);
$bedroom = strip_tags($bedroom);
$bedroom = htmlspecialchars($bedroom);
$type = trim($_POST['type']);
$type = strip_tags($type);
$type = htmlspecialchars($type);
$max = trim($_POST['max']);
$max = strip_tags($max);
$max = htmlspecialchars($max);
$min = trim($_POST['min']);
$min = strip_tags($min);
$min = htmlspecialchars($min);
// build query
$query = "SELECT * FROM Listings WHERE `bedroom` = ".$bedroom." AND `type` = ".$type."";
if(isset($location)){
$query .= " AND (`city` LIKE '%".$location."%') OR (`addressLineOne` LIKE '%".$location."%') OR (`addressLineTwo` LIKE '%".$location."%') OR (`county` LIKE '%".$location."%')";
}
if(isset($max)){
$query .= " AND (`price` <= '%".$price."%')";
}
if(isset($min)){
$query .= " AND (`price` >= '%".$price."%')";
}
$query .= "ORDER BY price;";
// send query to database and return error if it fails
$input = mysqli_query($connect, $query) or die(mysqli_error($connect));
// output results
if(mysqli_num_rows($input)>0){ // if one or more results returned do this code
while($result = mysqli_fetch_array($input)){ // puts data in array then loops the following code
echo "<p><h3>".$result['addressLineOne']." ".$result['addressLineTwo']."
".$result['location']."</h3><h4>£".$result['price']."</h4>".$result['information']."</p><br /><hr />";
}
}else{ // no results then print the following
echo "Sorry, we couldn't find any results.
Please refine your search and try again.";
}
echo $query;
// close the connection
mysqli_close($connect)
?>
I know you're currently using mysqli, but PDO makes building dynamic queries much easier, so I strongly suggest you switch to it, if you're not very far along on this project.
In a mysqli prepared statement, you have to call mysqli_stmt::bind_param(), passing every parameter in the argument list. In contrast, PDO requires no binding, and the parameters are all passed to PDOStatement::execute() in an array. This answer will show you how your code would work with PDO.
<?php
$connection = new \PDO("mysql:host=$db_host;dbname=$db_name", $db_user, $db_pass);
$query = "SELECT * FROM Listings WHERE bedroom = :bed AND type = :type AND (city LIKE :loc OR addressLineOne LIKE :loc OR addressLineTwo LIKE :loc OR county LIKE :loc)";
$parameters = [
":bed" => $_POST["bedroom"],
":type" => $_POST["type"],
":loc" => "%$_POST[location]%",
];
if(!empty($_POST["max"])) {
$query .= " AND price <= :max";
$parameters[":max"] = $_POST["max"];
}
if (!empty($_POST["min"])) {
$query .= " AND price >= :min";
$parameters[":min"] = $_POST["min"];
}
$query .= " ORDER BY price";
$stmt = $connection->prepare($query);
$stmt->execute($parameters);
$results = $stmt->fetchAll(\PDO::FETCH_ASSOC);
if (empty($results)) { // no results then print the following
echo "Sorry, we couldn't find any results. Please refine your search and try again.";
}
foreach ($results as $result) {
//escape for HTML output
$result = array_map("htmlspecialchars", $result);
echo <<< HTML
<p>
<h3>$result[addressLineOne] $result[addressLineTwo] $result[location]</h3>
<h4>£$result[price]</h4>
$result[information]
</p>
<br />
<hr />
HTML;
}
I've also simplified your HTML output by using a heredoc string, but you should really have your HTML and PHP separated.
If this is part of a much bigger existing project, you will likely be sticking with mysqli, in which case I urge you to learn how to use prepared statements; the days of building queries with string concatenation are long behind us!
Using PDO and bound parameters as #miken32 suggests is a possibility, but I advise against it because it has several downsides:
You are currently using mysqli, which also supports bound parameters, so no reason to switch to PDO just to get parameter binding
#miken32's solution uses a named parameter (something only PDO supports) multiple times in the query. This only works when client-side parameter binding is enabled (i.e. PDO::ATTR_EMULATE_PREPARES set to true) which itself has multiple problems:
I could not quickly find out what the default for PDO::ATTR_EMULATE_PREPARES is, apparently "it depends on the driver".
With PDO::ATTR_EMULATE_PREPARES switched on, you cannot use bound parameters in your LIMIT clause anymore
The errors returned from PDO are completely different depending on whether you use client-side or server-side parameter binding, a missing parameter for example causes an SQLSTATE of HY000 with server-side and HY093 with client-side parameter binding. This complicates proper error handling.
There is no way to see the actual query, an ability that can be very useful (essential in my opinion) for debugging.
So, I say go ahead and build your query manually, but in a clean and safe way. To do that you need to understand these concepts:
HTML encoding
In general, the only place where you need htmlspecialchars() is when you pass data (for example from the database) to the browser.
So, change every
$location = trim($_POST['location']);
$location = strip_tags($location);
$location = htmlspecialchars($location);
to
$location = trim($_POST['location']);
There is no need for strip_tags() nor htmlspecialchars() at this point. Form data from the browser arrives on the PHP side without any encoding. Of course, if someone would actually enter some<br>city into the location field, he would not find any rooms, but it will not break anything if you get the rest of your application right.
Also change every
echo "<p>".$result['addressLineOne']." ... </p><br /><hr />";
to
echo "<p>".htmlspecialchars($result['addressLineOne'])." ... </p><br /><hr />";
Otherwise the people entering the data into the database could run a "cross site scripting attack" - maliciously or accidentally.
SQL encoding
When sending data to the database as part of a query, you have to encode it in a way that the database knows that it's variable data and not part of the SQL command.
So, instead of for example
$query .= " AND (`city` LIKE '%".$location."%') ";
you have to write
$query .= " AND (`city` LIKE '%".addslashes($location)."%') ";
this makes sure that if there is a quote character (') inside your $location variable it will be escaped, so it does not end the string at that point.
If you work with a character set other than UTF-8, you should use mysql_real_escape_string() instead of addslashes() but you are probably using UTF-8, so it's just fine.
Furthermore in this case you might want to remove or escape % and _ in the value, because they have a special meaning in a LIKE query.
You have two more problems in your code:
$query = "SELECT * FROM Listings WHERE `bedroom` = ".$bedroom." AND `type` = ".$type."";
Here you not only have to add addslashes() but also the quotes around the value:
$query = "SELECT * FROM Listings WHERE `bedroom` = '".addslashes($bedroom)."' AND `type` = '".addslashes($type)."'";
And here:
$query .= " AND (`price` <= '%".$price."%')";
Obviously the percent signs make no sense here, you clearly meant:
$query .= " AND (`price` <= '".addslashes($price)."')";
Libraries and template engines
Later on you would be well advised using a library or framework that does those things for you (because it's very easy to forget an addslashes() somewhere), but it can't hurt to do it manually at first in order to learn how it works under the hood.
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';
I have a dropdown lists which the default value is selected. If there is a value there the if statements allow an update to the data. If no value then instead a whole row will be inserted. It works if I hard code the third value as 1. However when I set this to $category_of_taxom1 the insert doesn't work. The Update works fine, so If I manually create the record within the DB, I can update it via the update SQL shown below. But if I try INSERT no luck? (I Have hard coded the first 3 items to be inserted, the third should be the variable mentioned above.
I have this select list
<select name="categorySelect1fromDB" >
<option value ="">EMPTY</option>';
<option value="1" <?php echo ($category_of_taxom1 == 1)?"selected":""; ?>>A</option>
<option value="2" <?php echo ($category_of_taxom1 == 2)?"selected":""; ?>>B</option>
<option value="3" <?php echo ($category_of_taxom1 == 3)?"selected":""; ?>>C</option>
<option value="4" <?php echo ($category_of_taxom1 == 4)?"selected":""; ?>>D</option>
</select>
And this set of statements.
if(isset($_POST['save']))
{
$category_of_taxom1 = $_POST['categorySelect1fromDB'];
$number_of_taxom1 = $_POST['number_of_taxom1'];
if (!empty($category_of_taxom1)){ //This is the value fromDB if not empy then do below else do last
pg_query("UPDATE record_tbl SET category_of_taxom ='$category_of_taxom1', number_of_taxom ='$number_of_taxom1' WHERE sheet_id = '$sheet_id' AND line = 1");
echo "Updated!";
} else
{
pg_query("INSERT INTO record_tbl (line, taxom_id, category_of_taxom, number_of_taxom, sheet_id) VALUES (1,1,'$category_of_taxom1','$number_of_taxom1','$sheet_id')");
echo "New Record ?Saved!";
}
}
This is an example of a working pgsql line I use else where in my site:
$sql8 = "INSERT INTO record_tbl (line, taxom_id, category_of_taxom, number_of_taxom, sheet_id) VALUES (8,8,'$_POST[gammarus_numbers]','$_POST[countgammarus]','$sheetid')";
$result = pg_query($sql8);
The datatype for the field 'category_of_taxom' is most likely set to varchar, meaning it should have quotes around the value when using INSERT. So you can either:
1) Change the datatype of category_of_taxom to integer in your database
2) Include quotes around the value in your INSERT statement:
('1','1','1','$number_of_taxom1',$sheet_id)
Related documentation:
mysql - quote numbers or not?
I should probably delete this question: The quotes were correct, I needed them on each variable. However because the code was so long, i couldnt post it all on here. I had accidentally called that variable twice. So at one point of time it does have something in, but within the same code it may also not. So i ended up having to rename my variable. Not really a good answer, but going to delete it anyway. As this will be too narrow for anyone else.