PHP inserting blanks into MySQL database - php

I have an HTML form which submits values to the following PHP file, which inserts them into a MySQL database:
<?php
$con = mysql_connect("*","*","*");
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db("*", $con);
$sql="INSERT INTO scores (hometeam, awayteam, result)
VALUES
('" . mysql_real_escape_string($_POST['hometeam']) . "',
'" . mysql_real_escape_string($_POST['awayteam']) . "',
'" . mysql_real_escape_string($_POST['result']) . "')";
if (!mysql_query($sql,$con))
{
die('Error: ' . mysql_error());
}
echo "1 record added";
mysql_close($con);
?>
Sometimes an input field in the HTML form will be left empty and in this case I do not want anything inserted into the database. I want the value to remain NULL. At the moment when I fill in my form like this:
Home team: Blue team
Away team: [empty]
Result: Won
The following is inserted into my database:
Home team: Blue team
Away team: ' '
Result: Won
What I want to be inserted/not inserted is:
Home team: Blue team
Away team: NULL
Result: Won
I've hunted hours for a solution. Can anyone help? Thank you.

You can use the NULLIF function from mysql database. What it does is, it takes 2 parameters and return null if they are same. So basically you can change your code to be like following:
$sql="INSERT INTO scores (hometeam, awayteam, result)
VALUES
(NULLIF('" . mysql_real_escape_string($_POST['hometeam']) . "', ''),
NULLIF('" . mysql_real_escape_string($_POST['awayteam']) . "', ''),
NULLIF('" . mysql_real_escape_string($_POST['result']) . "', ''))";
It will basically check if the entered value is ''(empty string), and if that's the case, it would instead save NULL in the database. You can even trim leading or trailing spaces from your variables before passing onto NULLIF, so if someone only enters spaces in your input boxes, it still saved NULL.
Also, as Michael said, it would be safer and better if you move on to PDO or mysqli extension. Hope my answer helps.

In your code, replace:
$sql="INSERT INTO scores (hometeam, awayteam, result)
VALUES
('" . mysql_real_escape_string($_POST['hometeam']) . "',
'" . mysql_real_escape_string($_POST['awayteam']) . "',
'" . mysql_real_escape_string($_POST['result']) . "')";
With:
if($_POST['awayteam'] == '')
$awayteam = 'NULL';
else
$awaytem = "'" . mysql_real_escape_string($_POST['awayteam']) "'";
$sql="INSERT INTO scores (hometeam, awayteam, result)
VALUES
('" . mysql_real_escape_string($_POST['hometeam']) . "',
" . $awayteam . ",
'" . mysql_real_escape_string($_POST['result']) . "')";

Don't quote them inside your query. Instead, build variables first, and append quotes to the escaped string values outside the query, giving you the ability to insert NULL keywords if your strings are empty:
// If any is not set or empty in the POST, assign the string "NULL" unquoted to a variable
// which will be passed to MySQL as the unquoted NULL keyword.
// Otherwise escape the value from $_POST and surround the escaped value in single quotes
$ateam = !empty($_POST['awayteam']) ? "'" . mysql_real_escape_string($_POST['awayteam']) . "'" : "NULL";
$hteam = !empty($_POST['hometeam']) ? "'" . mysql_real_escape_string($_POST['hometeam']) . "'" : "NULL";
$result = !empty($_POST['result']) ? "'" . mysql_real_escape_string($_POST['result']) . "'" : "NULL";
// Then pass the three variables (already quoted if necessary) directly to the query.
$sql="INSERT INTO scores (hometeam, awayteam, result) VALUES ($hteam, $ateam, $result);
In the long run, it is recommended to begin using a MySQL API which supports prepared statements, like PDO or MySQLi. They offer better security, can handle input NULLs more elegantly, and the old mysql_*() functions are soon to be deprecated.

Or if you have access to db alter the columns( that are optional) and set them as NULL by default.
i.e. if nothing is inserted in that column NULL will be displayed by default.

Why not replace ' ' and other invalid forms of data with 'null'?
OR
Check if $_POST['data'] is equal to ' ' or '' and if true, set them to 'null'.
Also,
Instead of mysql_real_escape_string, use the PHP function 'addslashes'.

Related

Trouble specifying my tablename inside query because of dot notation

I'm having trouble specifying my tablename inside the following query.
$sql = "INSERT INTO db269193_crud.posts (post_title,description)
VALUES ('" . $title . "','" . $description . "')";
The tablename is: db269193_crud.posts. I can't specify the table name as 'posts' because of my hostingprovider. They only allow me to specify it in conjunction with my databasename (which is db269193).
So the table name becomes: db269193(dot)posts. This dot however keeps lighting up in my editor as an incorrect syntax.
I need someone's help to tell me if I specified the table name correctly or if I have to use a variable to hide the dot notation like:
$tablename = 'db269193.crud';
$sql = "INSERT INTO $tablename (post_title,description)
VALUES ('" . $title . "','" . $description . "')";
You can put the entire name in backticks to escape it:
INSERT INTO `db269193_crud.posts` (post_title, description)
VALUES ('" . $title . "', '" . $description . "')
As for the rest of your statement, I would encourage you to use parameters instead of munging the query string. By putting random strings in the query, you are just inviting syntax errors and SQL injection attacks.
I can't specify the table name as 'posts' because of my hostingprovider. They only allow me to specify it in conjunction with my databasename (which is db269193).
I pretty much doubt that as it would require DB changes which simply make no sense. I assume that it's your fault as you did not select DB to use in the first place. Check how you connect and ensure you provide DB name as well or at least you mysqli_select_db() or equivalent.
$tablename = 'db269193.crud';
You can use backticks when name of table or column conflicts or is reserved word:
$tablename = '`db269193.crud`';
or
$tablename = '`db269193`.`crud`';
$sql = "INSERT INTO $tablename (post_title,description)
VALUES ('" . $title . "','" . $description . "')";
You are complicating simple strings with unnecessary concatentation. This will work and is less error prone:
$sql = "INSERT INTO $tablename (post_title,description)
VALUES ('{$title}','{$description}')";
however you are still seem to be vulnerable to sql injection here. I'd recommend switching to PDO.

Having issue with htmlspecialchars mysql query

What is wrong with this code...?? If i retrived data from mysql with the following code,it gives error.
$sql="select id,
'" . htmlspecialchars(question, ENT_QUOTES) . "',
'" . htmlspecialchars(option1, ENT_QUOTES) . "',
'" . htmlspecialchars(option2, ENT_QUOTES) . "',
'" . htmlspecialchars(option3, ENT_QUOTES) . "',
'" . htmlspecialchars(option4, ENT_QUOTES) . "',
'" . htmlspecialchars(correctAnswer, ENT_QUOTES) . "',
'" . htmlspecialchars(category, ENT_QUOTES) . "',
'" . htmlspecialchars(section, ENT_QUOTES) . "',
'" . htmlspecialchars(chapter, ENT_QUOTES) . "'
from $user order by id";
There are some issues here...
My Wallet Problem: Some $$$ missing (sorry, bad pun, I know):
$sql="select id,
'" . htmlspecialchars($question, ENT_QUOTES) . "',
'" . htmlspecialchars($option1, ENT_QUOTES) . "',
'" . htmlspecialchars($option2, ENT_QUOTES) . "',
'" . htmlspecialchars($option3, ENT_QUOTES) . "',
'" . htmlspecialchars($option4, ENT_QUOTES) . "',
'" . htmlspecialchars($correctAnswer, ENT_QUOTES) . "',
'" . htmlspecialchars($category, ENT_QUOTES) . "',
'" . htmlspecialchars($section, ENT_QUOTES) . "',
'" . htmlspecialchars($chapter, ENT_QUOTES) . "'
from $user order by id";
Quoting issue
Look at the answer of #bhawin, and give a +1 for spotting that!
Single quote ' is for enclosing strings, while the backtick `` ` is for enclosing names of SQL objects: columns, tables, etc...
Using PHP basic mysql functions
Newer PHP deprecated it. Don't do it... Use PDO for fun and profit!
Using string concatenation to assemble query
SQL Injection... Not funny to get attacked that way. Even if using PDO, you have to know how to use prepared statements properly...
htmlspecialchars in query -- why?
This escapes the string to be safely displayed in HTML pages. Not for building queries... That is what mysql_real_escape_string is for - but again, use PDO instead of the whole ordeal.
Relying on default encoding
Use UTF-8 (or the encoding you chose for the task) explicitly and consistently wherever deailng with strings. Like:
htmlspecialchars($correctAnswer, ENT_QUOTES, 'UTF-8')
And finally
Why on Earth are you specifying the column names this way? It doesn't make sense.
If your intent was to sanitize the results from the query, you should do that after retrieving the results... And suddenly, htmlspecialchars starts to make sense!
You are trying to escape the column name ? you escape values inserted to database , not column names or values already in database.
htmlspecialchars to select from table in mysql? htmlspecialchars is fot html not sql. you escape value when you insert them to database not when you selecting them . they already in database so why escape them ?
try this
$sql="select id,
question,
option1,
option2,
option3,
option4,
correctAnswer,
category,
section,
chapter
from $user order by id";
$sql="select `id`,
`" . htmlspecialchars(question, ENT_QUOTES) . "`,
`" . htmlspecialchars(option1, ENT_QUOTES) . "`,
`" . htmlspecialchars(option2, ENT_QUOTES) . "`,
`" . htmlspecialchars(option3, ENT_QUOTES) . "`,
`" . htmlspecialchars(option4, ENT_QUOTES) . "`,
`" . htmlspecialchars(correctAnswer, ENT_QUOTES) . "`,
`" . htmlspecialchars(category, ENT_QUOTES) . "`,
`" . htmlspecialchars(section, ENT_QUOTES) . "`,
`" . htmlspecialchars(chapter, ENT_QUOTES) . "`
from $user order by id";
i just changed ' to ` in query
I think I understand what you're trying to do, but you're going about it completely the wrong way. When you build an SQL query to send to the database, that SQL query is just a string, and contains no functionality. You can build it however you like, but the database will only see the resulting string.
In your code, you have a whole set of lines like this: htmlspecialchars(question, ENT_QUOTES) which are being interpretted by PHP to build up the query. PHP has a somewhat dubious feature that an unquoted name like question could be a constant, but if it's not will be assumed to be the string 'question'; the string 'question' has no instances of <, >, &, ", or ' in it, so htmlspecialchars will leave it untouched regardless of the options you pass in. In short, writing htmlspecialchars(question, ENT_QUOTES) is the same as writing 'question'.
You're then concatenating (.) that fixed string with another fixed string containing some single-quotes: ".... '" . htmlspecialchars(question, ENT_QUOTES) . "' ...."
So your query actually ends up like this:
$sql="select id,
'question',
'option1',
'option2',
'option3',
'option4',
'correctAnswer',
'category',
'section',
'chapter'
from $user order by id";
The next odd thing you have is that the table you are selecting from is designated with a variable. Table names don't generally change, so there isn't generally a need for a variable, although it can be useful occasionally to configure them. If that's what you're doing, I would advise a more explicit variable name, like $db_table_name_user.
Looking at the column names, though, they don't look like columns of a user, so I wonder if what your actually trying to do is retrieve from a table of questions based on some particular user. For that, you will need a WHERE clause, or possibly to JOIN onto another table. Read up on SQL if you don't know how those work.
Assuming that $user contains the name of the database table, though, the above will actually run as a successful SQL query - just not a particularly useful one, since it will select out the id of each user, along with the literal strings 'question', 'option1', etc. You need to either remove those, or replace them with back-ticks, which are what MySQL uses to quote column and table names to avoid them being interpreted as something else.
This will retrieve the details of everything in the user table, assuming that's what it is:
$db_table_name_user = 'user';
$sql="select id,
question,
option1,
option2,
option3,
option4,
correctAnswer,
category,
section,
chapter
from $user order by id";
Now we come to what you were actually trying to achieve with htmlspecialchars: handling escaping in the content you get back from the database. This has nothing to do with how you write the query, only to do with what you do afterwards. Your database table should store the exact text entered: when you insert it to the DB, you will use mysqli_real_escape_string (or a parameterised prepared query) to make sure the database doesn't interpret it as part of the query, but that is just about how you send it, not how it is stored.
Then, when you are actually displaying the text on an HTML page, after you've retrieved it from the database, you will escape it so that the browser doesn't interpret it as part of the markup. Escaping should generally happen as late as possible, so that you don't have to make assumptions about whether some string has already been escaped or not.
For instance, for a numbered list of questions, the code would be something like this:
$all_questions = get_all_questions_from_db();
echo '<ol>';
foreach ( $all_questions as $question )
{
echo '<li>' . htmlspecialchars($question['question']) . '</li>';
}
echo '</ol>';

I'm new to PHP and MySQL. I cannot figure this simple system out

<?php
$db = new mysqli("localhost","root","password","eme");
if($db->connect_errno){ echo "Not connected."; exit();}
echo $db->query("SELECT * FROM users") . "<br>";
echo $_POST[FirstName] . " " . $_POST[LastName];
$db->query("INSERT INTO users (FirstName, LastName) VALUES ('$_POST[FirstName]','$_POST[LastName]')");
echo $db->query("SELECT * FROM users") . "<br>";
?>
I cannot figure out why this code doesn't work. The only line that outputs anything is "echo $_POST[FirstName] . " " . $_POST[LastName];"
My database has a "users" table and the database is called eme. The database connects properly.
There is currently no data in the database. I figured I could add some with "INSERT," but it's failing.
You have several problems:
The query() method of mysqli returns a mysqli_result object. you need to use one of it's methods to get the actual data back from the query. For instance fetch_assoc()
In your insert, you need to either assign $_POST['FirstName'] to a variable, or explicitly add it to the string.
ie.
"INSERT INTO users (FirstName, LastName) VALUES ('" . $_POST['FirstName'] . "','" . $_POST['LastName'] . "')"
or
$first = $_POST['FirstName'];
$last = $_POST['LastName'];
"INSERT INTO users (FirstName, LastName) VALUES ('" . $first . "', '" . $last . "')"
You should also sanitize the data before inserting it to prevent major security threats.
Lastly, it's not a bug per se, but you should always use a string or integer value for an array index.
ie. You have $_POST[FirstName], it should be either $_POST['FirstName'] or $_POST["FirstName"]
It will still work, but the interpreter thinks it's a constant, which isn't defined, so assumes the literal value, throwing a warning (maybe notice, can't remember offhand). It's unnecessary overhead.
Try this...
$db->query("INSERT INTO users (FirstName, LastName) VALUES('".$_POST['FirstName']."','".$_POST['LastName']."')");
For more info on Quotes, look over this link - What is the difference between single-quoted and double-quoted strings in PHP?

SQL syntax is ok but php still throw error

My sql query when I check manually in phpmyadmin works fine, but when I try to handle it through php mysql_query throw me a syntax error. How to solve this issue?
Error message:
Invalid query:
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 'INSERT INTO scores( user_id ) VALUES (LAST_INSERT_ID( ))' at line 1
Whole query:
INSERT INTO users (id_fb, name, first_name, last_name, email, link, first_login)
VALUES ('1000001010101010', 'Bart Roza', 'Bart', 'Roza', 'lalalala#gmail.com','http://www.facebook.com/profile.php?id=1000001010101010','2011-05-07 11:15:24');
INSERT INTO scores( user_id ) VALUES (LAST_INSERT_ID( ));
My php function:
public function createUser()
{
$time = date("Y-m-d H:i:s");
$insert = "INSERT INTO users (id_fb, name, first_name, last_name, email, link, first_login) VALUES (" .
"'" . $this->me['id'] . "', " .
"'" . $this->me['name'] . "', " .
"'" . $this->me['first_name'] . "', " .
"'" . $this->me['last_name'] . "', " .
"'" . $this->me['email'] . "'," .
"'" . $this->me['link'] . "'," .
"'" . $time . "'); " .
"INSERT INTO scores( user_id ) VALUES (LAST_INSERT_ID( ));";
$result = mysql_query($insert);
if (!$result) {
$message = 'Invalid query: ' . mysql_error() . "\n";
$message .= 'Whole query: ' . $insert;
die($message);
}
}
EDIT:
Thanks for the solution!
Since mysql_query accepts only one query you need to split your query string into 2 separated queries and perform it with 2 mysql_query calls.
You can not run multiple queries in once using mysql_query function. you have to run these two queries with separate mysql_query call
mysql_query() sends a unique query
(multiple queries are not supported)
AS #zerkms and #Shakti said, mysql_query does not support multiple queries. If you want to use such functionality, consider migrating to mysqli. It supports multiple queries in a single packet by mysqli_multi_query

MySQL - Delete a row, how?

Can anyone show me a query in MySQL that would delete rows from all available columns.
I use this to insert rows:
$sql = "INSERT INTO " . KEYS . " // KEYS is a constant
(key, user_id, time, approved)
VALUES ('" . $randkey . "', '" . $user_id . "', '" . $time . "', '0')";
I need the opposite of this now, delete created rows.
delete from <table> where ....
Keep in mind that the delete statement is always for an entire row.
Using similar syntax sql = "DELETE FROM " . KEYS . " WHERE 1=1";
Replace 1=1 with the conditions for the row you want to delete or it will delete all rows.
Also, it's good to get out of the habit of just dropping variables into SQL as soon as possible, because it will open your code up to SQL Injection attacks. Look into using parameterized queries.

Categories