I like embedding variables in strings - "I like $verb $noun in strings!"
But then I was designing a database access script:
$sqlfragment = "SELECT * from " . $databasetableprefix . "_user";
Lovely. But what happened to my embedding variables in strings?!
I want to do something like this:
$sqlfragment = "SELECT * from $databasetableprefix_user";
But that will be interpreted as from the variable $databasetableprefix_user.
So I would use a space:
$sqlfragment = "SELECT * from $databasetableprefix _user";
But spaces aren't allowed in database table names, so that won't work.
(What I want is this resulting string: "SELECT * from cc_user", if cc is the prefix.)
Can I create this string using variable embeds? Perhaps a sort of 'nothing' character, that will stop PHP from thinking it is part of the variable name, but not carry through to the SQL?
$sqlfragment = "SELECT * from {$databasetableprefix}_user";
Wrap the variable in {} like so:
$sqlfragment = "SELECT * from {$databasetableprefix}_user";
You have to use curly brackets to tell PHP where the variable name begins and ends, as described in detail in the PHP manual.
$sqlfragment = "SELECT * from {$databasetableprefix}_user";
Also, be very careful using variables to generate SQL statements, as it can easily become a security risk if you don't carefully track the source of your variables or validate their values.
Related
Is it safe or not to use a POST var as below:
$stmt->bindParam(':'.$_POST[$field],$val);
or I need to check POST vars before?
You should use $_POST variables as the value, not the parameter name.
The $_POST variable could contain spaces or other characters that are not valid parts of a parameter name. I'm concerned that if you are doing what you show, that you have formed an SQL query like this:
$sql = "SELECT * FROM mytable WHERE mycolumn = :" . $_POST[$field];
Which is definitely not safe.
And there's no reason for the parameter names to be set to user input like that. Parameter names should be fixed by you, the programmer:
$sql = "SELECT * FROM mytable WHERE mycolumn = :myparam";
Then you bind using the same name. By the way, as long as you're using a reasonably recent version of PHP, you don't need the colon prefix in the bind call. You only need it in the SQL.
$stmt->bindParam("myparam", $_POST[$field]);
when I write a query for MySQL, usually use a form like this:
$column= "column_name";
$query = "SELECT * FROM table_name WHERE \"".$column."\"" = \"some_value\" ";
if I want to avoid using the \"". sequence for the variables, can I use this other form or there could be some compatibility issues or some other problem ?
$column= "column_name";
$query = "SELECT * FROM table_name WHERE \"$column\" = \"some_value\";
In both of these cases what you're doing is fine, but a few notes:
1) What you're doing in your first form is using the strings like string literals, which means you can/should use single quotation marks instead of double quotation marks, as they are parsed much faster.
$column = 'column_name';
$query = 'SELECT * FROM table_name WHERE ' . $column . ' = "some_value"';
What you're doing in the second example is also fine, it just depends on the reason you're trying to avoid using the escape character, but if you're just doing it for the sake of readability, what you have is fine.
Worth noting is that handling queries the way you're doing here is getting deprecated and you should take a look at PDO and inject your values that way.
Edit Per Comments Above - Removed " from around the column.
Yes, you can.
Strings delimited with double quotes are interpreted by the PHP parser.
to make sure, the variable is identified correctly, put it into curly brackets
Example
$variable = 1;
$array = array( 1,2 );
$object = new stdclass();
$object->member = 1;
$string = "You can basically put every kind of PHP variable into the string. This can be a simple variable {$variable}, an array {$array[0]} or an object member {$object->member} even object methods.";
If you want PHP to take the $variable literally without interpretation, put the string into single quotes.
Another method I really like to use for queries is the heredoc notation
$sqlQuery = <<< EOQ
SELECT
"field"
FROM
"table"
WHERE
"id" = '{$escapedValue}'
EOQ;
One more note:
In SQL you should delimit values with the single quote, and identifiers like table name and field names with double quotes (ANSI compatible) or the back tick ```
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 want to recober all the users with "blo" in their full name, for example: "Pablo"
I pass the "blo" parameter with user PHP parameter:
$q=mysql_query("select * From user Where fullName Like '%'".$_REQUEST['user']."'%'",$link );
something is wrong in the php SQL sentence, because when i try the sentence with the argument "blo" on my SQL database, i see that the SQL sentence is correct, because it returns me correct result, this is the sentence with the argument "blo" on it: select * From user Where fullName Like "%blo%"
i'm sure that the PHP is receiven the "blo" parameter correctly, then, it have to be a sintax error of the SQL sentence on the PHP.... but i can't find it
EDIT : OK!! the last sentence is solved, but now i have this new sentence with the same problem, it have a error but i dont know where
$query = sprintf("SELECT u.*
FROM USER u
WHERE u.fullName LIKE '%%%s%%' AND email NOT IN (select pp.fk_email2 from permission pp where pp.fk_email1='".mysql_escape($_REQUEST['mymail'])."') AND email NOT LIKE '".mysql_escape($_REQUEST['mymail'])."' ",
mysql_real_escape_string($_REQUEST['user']));
SQL requires single quotes to indicate a string for comparison, and the wildcard character (%) must be included inside of those single quotes. Double quotes are used for column and table aliasing only, if at all.
$query = sprintf("SELECT u.*
FROM USER u
WHERE u.fullName LIKE '%%%s%%'",
mysql_real_escape_string($_REQUEST['user']));
$q = mysql_query($query, $link);
Secondly, you're leaving yourself open to a SQL injection attack by not sanitizing the user request variable. Always use mysql_real_escape_string when dealing with strings being submitted to a MySQL database.
You have the quotes messed up. use this:
$q=mysql_query('SELECT *
FROM user
WHERE fullName LIKE "%' . $_REQUEST['user'] . '%"',$link );
BTW, this is bad practice. You are using un-escaped input in your query and are open to SQL injection.
It looks like your quotes are off.. try something like...
$q=mysql_query("select * From user Where fullName Like '%".$_REQUEST['user']."%'",$link);
Also, you will want to make sure that the incoming param is sql-escaped to prevent sql injection. I don't know php, but it's probably something similar to...
$q=mysql_query("select * From user Where fullName Like '%".mysql_escape($_REQUEST['user'])."%'",$link);
I think it must be ... Where fullname like '%" . $_REQUEST['user']."%'"...
with the % symbol inside the simple quotes.
#AndroidUser99: Change the query to --
$q = mysql_query("select * from user Where fullName like '%" . $_REQUEST['user'] . "%'", $link);
Update
I think we may need more code since none of the answers seem to be 'working'. Is the database link even being instantiated in $link? If there are errors what are they?
I want to write a mysql query something like this:
select * from books where title like
'$title_';
The $title is a php variable. when i run the above query, it throws an error saying
'$title_ variable not found'
How can I achieve this?
Thanks..
Use:
"... WHERE title LIKE '". mysql_escape_real_string($title) ."_'";
You could use:
WHERE title LIKE '{$title}_'";
..but there's a risk of SQL Injection attacks
Do it like this:
$query = "select * from books where title like '{$title}_';"
$result = mysql_query($query) or die(mysql_error());
By surrounding variable in {} you can specify that only $title is a variable and not the _. And the double-quote string will ensure that this variable gets expanded to its value.
Your query string must looks like:
$query = "select * from books where title like '".$title."_'";
Please note, the '".$title."_'
The error you are getting is because your query is taking $title and not the value of your php variable $title
Try:
"select * from books where title like '{$title}_';"
The curly braces first evaluate the variable and later add your wildcard _ to the variable value thereby providing sql query with your search criteria.
$query = "select * from books where title like '" . $title_ ."'";
$query = "SELECT * FROM books WHERE title LIKE '".$title."_';";
Do you have a variable $title_ or is it just $title?
If its just $title then:
$query = "select * from books where title like '".$title."_'";
The mysql query is merely a string. You just have to put the value of your $title php variable inside this string. The problem is that this string is followed by a character underscore that is valid in a variable name, hence you have to delimit the variable name or underscore will be included in the name.
There is several way to do it, for exemple:
$query = "select * from books where title like '${title}_'";
$query = "select * from books where title like '".$title."_'";
As OMG Ponies said, if $title came from some user input and not from some controlled part of your program (for exemple another table in database), the variable should also be protected or there is some risks of SQL injection attack (executing more than one query, and more specifically a query prepared by some hacker to be some valid SQL).
Beside attacks, there is also some other potential problems if you do not escape. Imagine what will happen for exemple if the title actually contains a quote...
I would usually do:
$query = "select * from books where title like '".addslashes($title)."_'";
but there is other variants depending the escaping context and what you want to protect from.