SQL Query Help—Confused About Quotes and Concatenating - php

I'm trying to wrap my head around writing queries in SQL and I'm having some difficulty understanding this example that I've found.
$q = "INSERT INTO `dbUsers` (`username`,`password`,`email`) "
."VALUES ('".$_POST["username"]."', "
."PASSWORD('".$_POST["password"]."'), "
."'".$_POST["email"]."')";
I guess I'm stumbling over the use of double quotes, single quotes, and the back-ticks. I compared this statement to the example on the W3 website and am just really confused as it seems much more complicated. Could you please explain to me what is going on in the above query? Thank you for your help!
$sql="INSERT INTO Persons (FirstName, LastName, Age)
VALUES
('$_POST[firstname]','$_POST[lastname]','$_POST[age]')";

The double quotes are used to define the elements that build your $q string. The single quotes identify strings within the SQL query that you are building and the backticks are used to escape object names in MySQL.

The double quotes surround the strings that will be a part of the query string. The dots between each double-quoted section are the concatenation operator. They are joining individual string pieces together.
You'll notice that there is a double-quote and dot before every $_POST[] array variable, and a dot and double-quote after.
e.g. " . $_POST["username"] . "
The first double quote ends the previous string section. The one at the end starts the next string section. Everything between the two dots is the POST variable. The reason the dots are necessary is because of the quotes around "username". In your W3 version they did not use quotes around the $_POST[] array key string (e.g. $_POST[firstname] and not $_POST["firstname"] or $_POST['firstname']) and so they did not need to use dots and quotes.
If you want to keep things simple, don't use the quotes inside of the $_POST[] variables and you won't have to use all those dots and quotes around them.
If you try version 1 without the dots and quotes the php parser will fail and you will see an error.

Backticks ` are to escape MySQL keywords (usually used for table and column names). Single or double quotes are required around any strings which are inserted.
Note that you should call mysql_real_escape_string on any string you're concatenating into a SQL query. Otherwise, it's possible to break out of quotes if $_POST also includes quotes. This can potentially be used to allow the execution of arbitrary SQL commands in what is known as a SQL injection attack.

The `back ticks` are optionally used to quote mysql field names, you will need them if you accidentally use one of mysqls reserved words to name a field - otherwise you don't need them.
When you enter a string into a field you have to 'quote it'.
The whole statement has to be quoted, but not clash with 2) above, hence the use of "double quotes".
Non scalar values such as arrays do not automatically expand, so you have to "drop out" . and . "back in" to PHP to build your string using concatenation sign a dot .

The backticks are a MySQL artifact in case you are using reserved words as your table/field names, and the single quotes delineate string literals in SQL. The double quotes are PHP-specific and separate strings in PHP. So, your query below would look like the following:
$sql="INSERT INTO Persons (FirstName, LastName, Age)
VALUES
('".$_POST["firstname"]."','".$_POST["lastname"]."','".$_POST["age"]."')";
One thing that the author above is doing is also breaking the PHP string into separate strings, probably to improve readability. MySQL server doesn't care about that.

There's actually a lot of unnecessary stuff in that first query. There are best practices to take into account but it could be re-written as such:
$q = "INSERT INTO dbUsers (username, password, email)
VALUES ('".$_POST["username"]."',
PASSWORD('".$_POST["password"]."'),
'".$_POST["email"]."')";
First thing: INSERT INTO dbUsers:
All this is doing is telling us what table we're inserting our data into.
(username, password, email)
Specifying the columns we're inserting into (order specific)
VALUES ('".$_POST["username"]."', PASSWORD('".$_POST["password"]."'), '".$_POST["email"]."')
Our values to be inserted (dependent on the order of the columns), then a terminating semicolon.
If you re-write this with hard coded values rather than concatenation, it would look like:
VALUES ('myUserName', PASSWORD('myPassword'), 'myEmail')
All of that should be self explanitory. Each value is contained within single quotes (') as they are strings. Then the password value is passed through the MySQL function PASSWORD which hashed the password for security purposes.

The double quotes are part of the PHP code, telling it that the items inside the double quotes are strings. They're not part of the SQL being built.
The single quotes are used to surround values in the resulting SQL. Ie, you're telling the database the value "bob" is used here. For some types of value (integers, boolean, etc) you don't need the single quotes. For many others (varchar, dates, etc), you need the single quotes.
The backticks perform much the same function as single quotes, except they're used around table names, field names, etc... rather than around actual values. They're used when the name in question wouldn't be interpreted by the database correctly there, for example if you had a field named count, since that's a keyword in SQL. As noted elsewhere, the backticks aren't necessary in your example, but many people put them in all the time because it doesn't hurt to have them; as a safety net, kindof.
To give a visible, simpler example
$name = "bob";
$sql = "SELECT * FROM `mytable` WHERE `name` = '" . $name . "'";
This would result in the $sql variable being
SELECT * FROM `mytable` WHERE `name` = 'bob'
As you can see, the double quotes are not part of the string.. they're just used in creating it. In the resulting SQL, the backticks surround the table/field names, and the single quotes surround the actual value bob.
As a complete side note, using the POST values directly in created SQL is dangerous as it allows for SQL injection attacks. The values should be escaped or a parametrized query should be used.

Related

Inserting single (') into the database failed

I have an input field named "eventName". everytime I will put single quote (e.g uncle's birthday) it won't be inserted to the database. I mean no data at all will be posted to database. the system will just say that the event was saved but no data is being stored in the database.
You need to escape the single quote. The escape character used in this case of a '\', you can use inbuilt functions like mysqli_escape_string or add-slashes.
When you add a single quote in a variable and add it to a query, this will change your query by considering the single quote as a comment. e.g
Insert into Table ('name') values ('uncle's birthday');
Your query got ended at uncle and the part after that won't be considered, essentially this would result in failure. You should check what the error code as well depending on which database you are using.
Update:
$eventName = add_slashes($_POST['eventName']);
Rather than simply adding slashes, consider prepared statements, thus preventing SQL injection attacks. More details about this here: How can I prevent SQL injection in PHP?
It's good practice to escape values before writing them to your database.
$escapedName = mysqli_real_escape_string($_POST['eventName']);

how to use variable as table name to insert data

$tablename = "channel";
mysql_query("INSERT INTO '".$tablename."' (episode_name,episode_title,episode_date)
values ('$videoname','$videotitle','$date')");
In PHP a double quoted string literal will expand scalar variables. So that can be done like this
$sql = "INSERT INTO $tablename (episode_name,episode_title,episode_date)
values ('$videoname','$videotitle','$date')";
I assume you thought that the single quotes were requred around the table name, they are not in fact they are syntactically incorrect.
You may wrap the table name and the columns names in backtick like this
$sql = "INSERT INTO `$tablename` (`episode_name`,`episode_title`,`episode_date`)
values ('$videoname','$videotitle','$date')";
The reason that the Values(....) are wrapped in single quotes is to tell MYSQL that these are text values, so that is not only legal syntax but required syntax if the columns are defined as TEXT/CHAR/VARCHAR datatypes
However I must warn you that
the mysql_ database extension, it
is deprecated (gone for ever in PHP7) Specially if you are just learning PHP, spend your energies learning the PDO database extensions.
Start here its really pretty easy
And
Your script is at risk of SQL Injection Attack
Have a look at what happened to Little Bobby Tables Even
if you are escaping inputs, its not safe!
Use prepared statement and parameterized statements
Dont use quotes arround table name or use backtick
mysql_query("INSERT INTO $tablename (episode_name,episode_title,episode_date)
values ('$videoname','$videotitle','$date')");
"INSERT INTO `$tablename` (episode_name,episode_title,episode_date) values ('$videoname','$videotitle','$date')";
OR
"INSERT INTO `".$tablename."` (episode_name,episode_title,episode_date) values ('$videoname','$videotitle','$date')";

How to properly escape a string via PHP and mysql

Can someone explain what is the difference between using mysql_real_escape_string on a string or wrapping `` around the column.
For example "insert into table (``column``) values ('$string')"
or
$escapestring = mysql_real_escape_string($string);
"insert into table (column) values ('$escapedstring')"
What is the difference between these two and what should I use? Thanks.
There's a difference between the backtick ` and the single quote '.
The backtick is intended to escape table and field names that may conflict with MySQL reserved words. If I had a field named date and a query like SELECT date FROM mytable I'd need to escape the use of date so that when MySQL parses the query, it will interpret my use of date as a field rather than the datatype date.
The single quote ' is intended for literal values, as in SELECT * FROM mytable WHERE somefield='somevalue'. If somevalue itself contains single quotes, then they need to be escaped to prevent premature closing of the quote literal.
Those two aren't related at all (as far I know anyway)
From the manual : http://php.net/manual/en/function.mysql-real-escape-string.php
Escapes special characters in the
unescaped_string, taking into account
the current character set of the
connection so that it is safe to place
it in a mysql_query().
So essentially what it does is, it will escape characters that are unsafe to go into mysql queries (that might break or malform the query)
So o'reily will become o\'reily

When to surround SQL fields with apostrophes?

I notice that when I INSERT and SELECT values to and from a database I have to surround the fields with single quotes, like so:
mysql_query("INSERT INTO employees (name, age) VALUES ('$name', '$age')");
However, if I were to update the age, I would not use single quotes:
mysql_query("UPDATE employees SET age = age + 1 WHERE name = '$name'");
Also, it seems when adding the date to a SQL database I do not have to surround it with single quotes either:
mysql_query("INSERT INTO employees (name, date) VALUES ('$name', NOW())");
Also, when using operators like CONCAT it seems not to be necessary either:
mysql_query("UPDATE employees SET name=CONCAT(name,$lastName) WHERE id='$id'");
Perhaps I am just coding poorly but I seem to recall if I did not surround a field with single quotes when inserting and selecting it the operation failed.
You need to surround the values with quotes when field data type is of string eg text, char, varchar, etc or date types such as date, time, datetime.
For numerical types such as int, bigint, decimal, etc or SQL functions such as now(), current_date, you don't need quotes.
"age" exists in the question as both a php variable ($age) and as a MySQL column name. Column names shouldn't be quoted (generally speaking) but the contents of a column, used in a select or insert statement, ought to be quoted.
In particular, if the contents of a php variable haven't been set, the variable itself will vanish and this can break your syntax. Surrounding php variables with single quotes will at least protect the syntax in case the variable vanishes.
SELECT * from something where age = $age;
If for some reason $age wasn't set, such as the user didn't enter it on input, it will simply vanish and this line of code will produce a syntax error at run time because it becomes "where age = ;"
SELECT * from something where age = '$age';
If for some reason $age wasn't set, it will disappear but won't generate an error because it will become "where age = '';" and is still good syntax.
SQL injection is still possible in this instance of course but that's a different question.
You have to make a distinction between what kinds of things you see in a query:
reserved sql keywords: SELECT, UPDATE, WHERE, NULL, ... (not case-sensitive, but mostly used uppercase)
(sql) operators, and syntax tokens: + - / * . ( ) etc etc
sql functions: NOW(), CONCAT(), ...
fields, table names, database names: employees, age, name, date, ... which should be quoted using backticks, like `field`, to avoid confusion e.g. if you name a field ORDER
values
The last group, the values, can be string literals like 'John' or "John", or numbers like 1, 10, 1e9, 1.005. NULL is a special value, which you can loosely describe as "not set".
Numbers don't have to be enclosed in quotes, but string literals do.
This description is far from complete or perfect, but it should give you a beginning of understanding.
String values (including single characters) must be enclosed in single quotes. This includes date constants represented using strings. Numeric values do not need quotes.

MySql + InnoDB + PHP Single Quote Discrimination?

Okay, I've recently converted a number of tables to the InnoDB storage engine and I've been getting errors whenever I use a single-quote ' in the column list of the INSERT statement:
INSERT INTO 'Table' ('Col1', 'Col2') VALUES ('Val1', 'Val2')
When I tired using phpMyAdmin to generate a proper statement, it looked virtually the same, so I pasted it in my app, and it worked. Then my next statement had the same error so I started to get suspicious. After a bit of playing around I found that the problem was that the query needed a back-tick instead of single-quotes, but not for the whole thing.
INSERT INTO `Table` (`Col1`, `Col2`) VALUES ('Val1', 'Val2')
works, so it's not like MySql doesn't understand the single-quote. What is going on here? I also can't just leave the columns unquoted like before with MyISAM (ie: Table(Col1, Col2))
That's because single quotes denote string literals, whereas backticks denote database/table/column identifier escapes.
Removing backticks causes an error because TABLE is a reserved word, so in order to use it as a table name you have to include backticks.
You put single quotes around string values, and you use backticks around object names. The backticks are technically not necessary though unless that name of your table/column is a reserved word or has spaces/funny characters in it.

Categories