Why do I see in several examples of mysql queries via php the syntax:
$q = "CREATE TABLE '$tablename' ('$t_id_name')";
or things similar to that? I'm asking about the single quotes around the variable names. Is this required in MySQL strings? If I echo the string, it seems to expand the variables whether the quotes are there or not.
And would this pose a problem if this were done for something that was intended to be an integer?
To answer your question, the quotes are necessary, but not to expand the variable. A typical SQL query would look like this:
$q = "SELECT * FROM `table` WHERE `first_name` = 'user3475234'";
Now, consider the following example:
<?php
$tablename = "users";
$user = "user3475234";
$q = "SELECT * FROM `$tablename` WHERE `first_name` = '$user'";
echo $q;
This will display: SELECT * FROM `users` WHERE `first_name` = 'user3475234'. Note that the quotes weren't necessary to output the string, but they were a necessary part of the query.
That being said, code like this opens your script to SQL injection. I won't explain too much about it, since there are plenty of resources discussing it, but consider the example where someone's username is user3475234' OR 1==1--. This username will effectively return all users in the table.
You must use backticks (`) for field or table name especially if the field or table name are same with mysql command. And you need to use single-quote (') for value.
Related
This is bizarre, I'm changing some code from mysql to mysqli functions cause of php 5.5+, in these two basic examples, mysql_query had no ' single quote nor ` backtick and worked fine.
$sql = "SELECT * FROM `".$table."`"; // requires: ` ` or fails
$result = mysqli_query($con,$sql);
$sql = "SHOW TABLES LIKE '".$table."'"; // requires: ' ' or fails
$result = mysqli_query($con,$sql);
Can someone explain why?
EDIT: I guess the essence of my question is that: Both functions worked fine without any kind of quotes with mysql_query, and both failed mysqli_query without some kind of quotes. Meaning I will have to fiddle around with half my query's when changing from mysql_ to mysqli_
In your first select statement you are trying to select a table by it's name, hence it will accept the name either with ` or without them, but now with single or double quotes. These should work :
$sql = "SELECT * FROM `table_name`";
$sql = "SELECT * FROM table_name";
In the second case you need to pass in a string to be compared by the like statement hence you need to surround it either with single ' or double " quotes:
$sql = "SHOW TABLES LIKE 'string'";
$sql = "SHOW TABLES LIKE \"string\"";
Edit:
Check out this previous answer on SO as well:
Using backticks around field names
Edit 2:
Since we (me and in comments) suggested that backticks are somehow optional, keep in mind that as a best practise use them whenever you can since although it will allow you to pass most queries without them, some queries using MySql reserved words would break when containing mysql reserved words
I checked similar questions but couldn't find any solution to my particular problem. I have a PHP method that I use as follows:
SELECT * FROM login WHERE userID = 10 //To get this
$result = query("SELECT * FROM login WHERE userID = '%d' ", $userID) //I use this
so the character set '%d' is replaced by what I post in the $userID and the result is returned as JSON. Now i am trying to use it for a search function using.
select * from login where userName like '%searchString%' //Now to get this
$result = query("SELECT * FROM login WHERE userName LIKE '%'%s'%'", $username) // I am trying this
However I got error probably due to not escaping strings properly. Is it possible for any of you to solve this with given information?
Thanks
arda
You also need to change the where clause to use LIKE instead of =
$result = query("select * from login where userName like '%%s%'", $username)
I'm assuming your query method will search/replace the %s with the value of $username.One thing to be mindful is that using "select *" results in an inefficient query execution plan, you should change the * to a list of the columns from the table you want to retrieve. Also, be mindful of SQL injection attacks. See this link http://en.wikipedia.org/wiki/SQL_injection.
you may try by changing this '%'%s'%'
select * from login where userName like '%searchString%' //Now to get this
$username=mysql_real_escape_string($username);
$result = query("SELECT * FROM login WHERE userName = '%%s%'", $username) // I am trying this
I found the solution to be easier than I thought. I simply passed %searchString% as an argument instead of plain searchString
Escaping quotes and escaping percentage signs are two different matters.
First the quotes. The bad way is to "quote the quotes", ie replace all single quotes with two single quotes. It works, but there are disadvantages. The better way is to use query parameters. I don't work with php so I don't know all the details, but I read a lot of comments and answers here on StackOverflow telling php users to use prepared statements. They may or may not escape quotes. My guess is that they do.
For percentage signs, you have to surround them with square brackets to keep them from being treated as wild cards. For example, if your where clause is:
where somefield like '75%'
and you want it to return
75% of bus passengers like singing
but not return
75 bottles of beer on the wall
then your where clause has to be:
where somefield like '75[%]%'
Noticed a small issue in the syntax of a sql query, here's how it goes:
$email = "name_lastname#server.com";
$query = "Select * From Users Where email=".$email;
This does not work, the query has been tested and works fine, however this essentially evolves to :
Select * FROM Users WHERE email=name_lastname#server.com ;
Which yields a null result.
To execute it the right way, I add a twist to the syntax of my $email variable, essentially as:
$email = "\"name_lastname#server.com\"";
Once I specify quotations within the string variable, that is when it executes as expected yielding the desired result.
I am not sure if this is the most aesthetic way to go about approaching my syntax for query execution, and I do think there are alternatives. Grateful to those who shed a light on this
Try this instead:
$query = "Select * From Users Where email='$email'";
Or:
$query = sprintf("Select * From Users Where email='%s'", $email);
Or:
Many many other ways....
String queries need a single quote around the search criteria. Assuming MySQL: http://dev.mysql.com/doc/refman/5.0/en/string-syntax.html
$email = "name_lastname#server.com";
$email = "'" . mysql_real_escape_string($email) . "'";
$query = "Select * From Users Where email=".$email;
non quoted variables like that will be read as int. Always quote all strings. you don't need to escape doubles like that when singles will suffice.
$query = "SELECT * From Users WHERE email= '".mysql_real_escape_string($email)."'";
Why not do:
$email = "name_lastname#server.com";
$query = "Select * From Users Where email = '$email'";
Your solution gets at the right principle: SQL needs the email address to be enclosed in quotes because it's a string. My suggestion for making the code more elegant would simply be to put the quotes in the string containing the query, not the one containing the email address.
$email = "name_lastname#server.com";
$query = "Select * From Users Where email=\"".$email."\"";
The quote marks aren't part of the email address, they're part of the query. If you do it this way, you won't have extraneous quotes if you try to use $email for something else, and you won't have to remember to put quotes around every other email address that you pass into the same query.
Also, you might want to check out mysqli, which handles queries in a slightly different way and as a side effect, eliminates all this fooling around with escaping your strings.
PS - I agree with the folks who suggested using single quotes instead of escaped double quotes. But SQL does accept double quotes (at least on my system) so I stuck with the convention you were using.
The best way to avoid quote problems is to prepare the statement in phpMyAdmin and then generate the PHP source query:
$email = "name_lastname#server.com";
$sql = 'SELECT * FROM `Users` WHERE `email` = '.$email;
More info:
http://www.packtpub.com/article/multi-table-query-generator-using-phpmyadmin-mysql
I have a searchable database of the House and Senate and I just want to make a simple web page that can search this database. The only problem is, while I'm comfortable writing SQL select statements, how do I properly format them for use in PHP?
For example, here's my radio button to select Senators by state:
$sql = "";
if ($_POST['pkChamber'] == "Senate") {
if ($_POST['pkParty'] == "Y") {
$sql = SELECT * FROM senateinfo
WHERE state = (Variable = "stname")
ORDER BY last_name, first_name');
}
else
{
$sql = SELECT * FROM senateinfo
WHERE state = (Variable = "stname")
ORDER BY last_name, first_name
}
}
I am not sure what you're asking for, But I have a good example of reliable and safe way for building WHERE statement dynamically:
$w = array();
$where = '';
if (!empty($_GET['rooms'])) $w[]="rooms='".mysql_real_escape_string($_GET['rooms'])."'";
if (!empty($_GET['space'])) $w[]="space='".mysql_real_escape_string($_GET['space'])."'";
if (!empty($_GET['max_price'])) $w[]="price < '".mysql_real_escape_string($_GET['max_price'])."'";
if (count($w)) $where = "WHERE ".implode(' AND ',$w);
$query = "select * from table $where";
Hope this helps.
Your query seems fine. I think you just need to understand some of the finer points of string parsing in PHP.
When you use double quotations (") to enclose a string, PHP actually will try to parse it looking for variables and/or other php code to process first. Something like this:
$sql = "SELECT * FROM table WHERE state = '{$state}' AND user = {$user->id}";
PHP will substitute out $state for whatever is defined in that variable and the same for the id of whatever user is instantiated in that class. (Also, you don't have to wrap your simple variables in {}. It does help with readability but is only required for class methods/variables.)
If you use single quotes (') to enclose a string, PHP simply treats it like normal. For your above query, I would suggest enclosing it in single quotes like this:
$sql = 'SELECT * FROM senateinfo WHERE state = (Variable = "stname") ORDER BY last_name, first_name)';
If you want to use variables later on in this query, then you will need to escape the double quotations that are in there like this:
$sql = "SELECT * FROM senateinfo WHERE state = (Variable = \"stname\") ORDER BY last_name, first_name)";
This way, PHP doesn't error out thinking you were trying to concatenate strings incorrectly when all you were doing was pasting a query.
You need to focus on one issue at a time.
Try to avoid writing SQL in PHP until you've a clear handle on strings in PHP, and how to inject variables into those strings. So:
Read up on string quoting in PHP (double quotes vs. Single quotes, and yes, HEREDOC)
Read up on variables in strings in PHP (note that if it doesn't have a $ dollar sign, it's a CONSTANT, not a string variable. Start off right with $strings and $variables where they're supposed to be used, not CONSTANTs, which only fall back to turn into strings if nothing else is available.)
Read up on binding SQL in PHP. Anything else will lead you down the path of SQL injection. If there are only naked strings used in your PHP SQL, then you are setting yourself up for failure when you finally deploy your web scripts to the harsh and unforgiving Internet. It's full of sharks ready to take advantage of SQL injection prone scripts.
Here is an example of code I use daily to bind SQL, centered around a custom function that makes it easy:
query("select * where someTable where someTable_id = :bound_id", array(':bound_id'=>13));
I can get you a function for creating bound SQL simply like that later (when I'm actually at a computer instead of mobile) if you're interested.
I use HEREDOCs for writing out non-trivial queries:
$sql = <<<EOL
SELECT blah, blah, blah
FROM table
WHERE (somefield = {$escaped_value}) ...
ORDER BY ...
HAVING ...
EOL;
Heredocs function as if you'd done a regular double-quoted string, but with the bonus of not having escape internal quotes. Variable interpolation works as expected, and you can do indentation on the text as well, so your query looks nicely formatted
I always do mine like this to keep it looking nice.
$sql = "SELECT * FROM senateinfo " .
"WHERE state = (Variable = "stname") " .
"ORDER BY last_name, first_name')";
I have a code below:
<?php
require "institution.php"
/* in this portion, query for database connection is executed, and */
$institution= $_POST['institutionname'];
$sCampID = 'SELECT ins_id FROM institution where ins_name= '$institution' ';
$qcampID = pg_query($sCampID) or die("Error in query: $query." . pg_last_error($connection));
/* this portion outputs the ins_id */
?>
My database before has no mixed-case table names, that's why when I run this query, it shows no error at all. But because I've changed my database for some reasons, and it contains now mixed-case table names, i have to change the code above into this one:
$sCampID = 'SELECT ins_id FROM "Institution" where ins_name= '$institution' ';
where the Institution has to be double quoted. The query returned parse error.
When i removed this portion: where ins_name= '$institution', no error occured.
My question is how do I solve this problem where the table name which contains a mixed-case letter and a value stored in a variable ($institution in this case) will be combined in a single select statement?
Your answers and suggestions will be very much appreciated.
You can use the double quote instead
$sCampID = "SELECT ins_id FROM \"Institution\" where ins_name= '$institution'";
<?php
require "institution.php"
/* in this portion, query for database connection is executed, and */
$institution= pg_escape_string($_POST['institutionname']);
$sQuery = "SELECT ins_id FROM \"Institution\" where ins_name= '$institution'";
$qcampID = pg_query($sQuery)
or trigger_error("Error in query: $sQuery." . pg_last_error($connection));
/* this portion outputs the ins_id */
?>
Note
pg_escape_string as it ought to be used, not to protect from any injections but as just a part of the syntax.
trigger_error which should be used instead of echo (and note proper variable name)
and double quotes or your variable won't be extrapolated ( http://php.net/types.string for ref)
and slashes at double quotes (same ref)
$sCampID = 'SELECT ins_id FROM "Institution" where ins_name= \''.$institution.'\'';
String escaping.
As another commenter posted, read about SQL injection. What I have is not injection safe, consider using something with prepared statements, preferably PDO.
To add to other answers (quote the table name, and use prepared statements to gain security and performance), read about PG and tables case sensitivity. If you have the option, you might consider to change your db schema, so that tables names (and columns and identifiers in general) are all lowercase. That would simplify a little your queries - (but require you to check all your actual quoted queries and unquote them).
What happens if $institution contains the following string: ' or 1 = 1; --
That's what we call an SQL injection attack, and it's a super-easy way for hackers to steal your data -- and get you into big trouble with your customers.
You need to escape that string using pg_escape_string() before putting it into an SQL query. I like to use sprintf() to build my queries:
$sql = sprintf("SELECT ins_id FROM \"Institution\" where ins_name= '%s'", pg_escape_string($conn, $institution));
In the above example, $conn is the connection identifier, created by calling pg_connect().