How can i store the value from a SELECT MySQL statement into a PHP variable?
for example:
$myvariable = SELECT * FROM X WHERE id = X
Thanks
you need to look at the php manual for the mysql/mysqli wrapper functions.
http://us3.php.net/manual/en/book.mysql.php
http://us3.php.net/manual/en/book.mysqli.php
If the code you provided was written with proper syntax (you need single/double quotes around string literals in php) your variable would contain the sql query string. You need to send that to the database via some kind of wrapper.
You may wont to search around for some general php and php/mysql tutorials.
Related
I have a problem in my website, I'm trying to fetch some data from a table that has courses names. I search by the name of that course. some of the names contain '&' in them, for example "Formal Languages & Automata" and I need to fetch all the records related to this course.
When I try the below SQL statement, it fails in getting what I want:
SELECT * FROM tablename WHERE course = 'Formal Languages & Automata'
The query searches for "Formal Languages " only and neglects the & and anything after it.
Does anyone have a solution to this?
Thanks
My guess is that this could happen in is if you're passing the value you're searching by in a GET query string or a POST request body without URL-encoding it, thus when PHP receives the request, the part after & is considered the next variable in the request. In case you make the request from PHP, you need to use urlencode() and if it's in Javascript, it's the encodeURIComponent function.
You should escape the ampersand (&) character in your string:
SELECT * FROM tablename WHERE course = 'Formal Languages \& Automata'
You can use LIKE
SELECT * FROM tablename WHERE course LIKE 'Formal Languages%'
This statement will find every course that begins with 'Formal Language' and it can have any characters in the end.
http://dev.mysql.com/doc/refman/5.0/en/string-comparison-functions.html#operator_like
More about string comparsion can be found at link above. Also before puting some data to query you should escape it or use prepared statements and binding parameters which engines that have already escaping built in. For example mysqli, pdo.
Example PDO
$sth = $dbh->prepare('SELECT * FROM tablename WHERE course = :search');
$sth->bindParam(':search', 'Formal Languages & Automata', PDO::PARAM_STR);
$sth->execute();
More info about PDO here
I have a function that takes an array and creates a SQL statement based on they key/value pairs of the array. For example:
name=>SomeKittens
It'd turn into
(`name`) VALUES ('SomeKittens')
The only problem is when I use a MySQL string function such as NOW().
creation_date=>NOW()
turns into
(`creation_date`) VALUES ('NOW()')
Note that NOW() is escaped. Is there any way to detect if the value is a MySQL string function? (besides of course $value === "NOW()")
I'm using the Joomla DBO but am open to PDO/MySQLi solutions as well.
(relevant chat discussion)
If you allow functions with arguments I don't think you will be able to protect your db against SQL injections.
If you allow only functions w/o arguments (like NOW()) you might as well hardcode a list.
You may simply want to define a constant like MYSQL_NOW that when creating your query you know to convert to a NOW() function call rather than 'NOW()' string.
I have the following MySQL query that I execute from a .php page
SELECT * FROM servers WHERE name LIKE '%$value%'
which, when executed, selects 0 rows (However, the query runs successfully, so I can't use mysql_error() to debug). When I run the query in PHPMyAdmin it selects the appropriate rows. Other queries such as
SELECT * FROM servers
work fine. I can put my code up here if it will help.
Edit: Here's something offering an improvement based on Marek's answer below. Please see the comments regarding the practice of putting variables directly into queries and consider using prepared statements. Anyway, here it goes.
PHP substitutes variables inside doubly-quoted strings, but not inside singly-quoted strings.
One quote character is just treated as an ordinary character within a string delimited by the other.
Putting that together, you can write:
$q = "SELECT * FROM servers WHERE name LIKE '%$value%'"; //Fine
You cannot write:
$p = 'SELECT * FROM servers WHERE name LIKE "%$value%"'; //Broken!
$q works because it's a doubly-quoted string, and the apostrophes are just ordinary characters. $p does not work because it's a singly-quoted string.
As pointed out by GoodFather below, you can also say ${value} to avoid ambiguities with the ambient string, e.g. $r = "ABC${value}DEF";.
You really need to look at doing this query more safely. This will help with your issue as well. As it stands, you are vulnerable to SQL injection. Look at the examples from the PHP manual for how to do it right:
http://php.net/manual/en/function.mysql-query.php
EDIT: From your comments you mentioned that you are already taking care of the string properly, which is great. The code below should fix your problem.
For example, you could rewrite your query statement (in PHP) like so:
$query = sprintf("SELECT * FROM servers WHERE name LIKE '%". mysql_real_escape_string($value) . "%'");
That will clean up your code and it will also handle the issue with your LIKE statement not working properly.
Here is another good article on the subject:
http://joshhighland.com/blog/2008/07/06/php-sprintf-sql-like/
Are you expecting a case-sensitive or case-insensitive query? I'm betting case-insensitive since you're expecting results but not seeing them. Take a look at your database's default collation or the table's specific collation and make sure it ends in _ci, whatever it is.
I have a php file which at the start, assigns some variables from what was sent using $_GET.
It then does some mysql queries, processes the output, then echos out some text and variables.
The only protection I have set in the code is mysql_real_escape_string on the GETs.
Is that enough to prevent attacks?
What else can be done?
Well, you take mysql_real_escape_string awfully wrong.
It's not your fault though - its one of wickedest delusions among PHP society. Even official man page put it all wrong.
This function has nothing to do with securing anything in general and GET variables in particular
This function is merely escaping string delimiters, to make string delimiters unable to break a string. Thus, 2 most important consequences:
not only GET variables but ALL variables being put into query in quotes should be processed with mysql_real_escape_string(), no matter of their source or origin or possible dangerousness
it will have effect on the quoted strings only. It's totally useless to use this function for any other part of query, LIMIT clause variables for example.
Thus, to secure your SQL query, you have to follow whole set of rules, not just deceiving "sanitize your data with mysql_real_escape_string".
You can learn how to protect your SQL from my earlier answer on the similar topic: In PHP when submitting strings to the database should I take care of illegal characters using htmlspecialchars() or use a regular expression?
update
a scenario to show why mysql_real_escape_string is not a silver bullet
being given with url
http://www.example.com/news.php?offset=99999+UNION+SELECT+password+FROM+users+--
a code
$offset = mysql_real_escape_string($_GET['offset']);
$sql = "SELECT title FROM news LIMIT $offset,20";
Will result if not in not so pompous as little bobby tables' one but in somewhat no less disastrous.
No, there are plenty of attacks that you might not have protection for. One example is CSRF. It's a big field, so I recommend reading up on this stuff on the Owasp site:
http://www.owasp.org/
Using this is definitely not sufficient. It is not even sufficient when you only consider sql injection. It is sufficient when you consider sql injection on strings only, but as soon as you have an integer (say an id) it goes wrong:
http://example.com/foo.php?id=10
Goes through:
$q = "SELECT * FROM foo where id = " + mysql_real_escape_string($_GET['id'])
Which results in de SQL query:
SELECT * FROM foo where id = 10
This is easily exploitable, for instance:
http://example.com/foo.php?id=10%3B%20DROP%20TABLE%20foo
Goes through:
$q = "SELECT * FROM foo where id = " + mysql_real_escape_string($_GET['id'])
Which results in de SQL query:
SELECT * FROM foo where id = 10;DROP TABLE foo
I hope this clarifies why it isn't enough.
How you should solve this? Define what input is allowed, and check that the input is indeed of that form, for instance:
if(preg.match("^[0-9]+$",$_GET['id']){
// your code here
}else{
// invalid id, throw error
}
But the best way to be on the safe side (regarding SQL Injection) is using prepared statements:
http://php.net/manual/en/pdo.prepared-statements.php
mysql_real_escape_string will only protect you agains SQL Injections when you use the return value in a MySQL string declaration like:
'SELECT foo FROM bar WHERE quux="'.mysql_real_escape_string($val).'"'
It won’t protect you if you use it in any other context (specifying the sorting order with ASC/DESC, row limits, table/row names, etc.). In that case you’ll need to validate/filter/sanitize the value separately.
And if the user data can also be part of the query result that you are about to output, use htmlspecialchars to replace any HTML special character.
you have if the get variables have values using the isset() and empty() functions
I come across this sql code in a php software.
What does the #section_filter mean?
Is that a valid mysql syntax? or just a templating system?
$filterid = ac_sql_select_one("
SELECT
id
FROM
#section_filter
WHERE
userid = '$ary[userid]'
AND
sectionid = 'article'
AND
conds = '$conds_esc'
");
Thanks
It is a valid sql syntax but the problem i suspect is that hash # character creates comments in sql queries hence this query might not execute.
Another possiblity is that the program that you saw this query in should be able to dynamically replace the #section_filter with some table name before it gets to mysql engine and then the query should run fine. This is the highest possibility in my view.
The # symbol is one way to express a comment in MySQL. So, this isn't a valid SQL statement as written, since the line:
#section_filter
would be completely ignored.