Hi I have a MYSQL query which counts the number of times www.google.com appears in a database field, which works fine, what I am trying to find is a way that it will identify Google, whether it is www.google.com, www.google.co.uk, etc, etc
Below is my code,
$result = mysql_query("SELECT * FROM data WHERE referer='www.google.com' and member ='$site_id'");
Any suggestions would be appreciated, thanks.
You can use LIKE to search a string with wildcard syntax: % for zero or more of any character:
WHERE referer LIKE 'www.google.co%'
You can make that search more specific or less as well.
By the way your code is vulnerable to injection. You should use properly parameterized queries with PDO or mysqli.
You could try a simple LIKE query:
SELECT * FROM data WHERE referer LIKE 'www.google.%' and member ='$site_id'
This will match on any value of referer that starts with the string "www.google.".
Also, the mandatory suggestion that you not use the mysql_* functions... which are being deprecated. Use PDO or mysqli instead.
Related
One day I was googling to understand when a prepared statment should be used. As I searched online many claimed that you should use always prepared statments. Now the question I have is... does this also count for LIMIT? I mean it is possible (I tried) but is it really that rational? Same question on ORDER BY too.
When the database does not allow you to use a parameter on a specific location of the SQL statement you need to assemble the query on the fly, by the use of Dynamic SQL. That is... concatenating strings to get a full functioning SQL query.
Now, the trick is to make it safe against SQL Injection. To do this:
Make sure the value for LIMIT is an integer, and not something unsafe coming right from the UI like 3; DROP TABLE EMPLOYEE.
For the ORDER BY clause make sure the columns are not coming from the UI "as is"; use some kind of projection. For example, if there are 50 columns to order by, the UI can display them all, but then just send a number (from 1 to 50) to the backend; the backend receives this number and reconstitutes the ordering column(s) from it.
Normally the LIMIT parameters must be literals, not values that can be substituted for placeholders, so you would have to validate that they're integers before substituting into the string.
However, if you use PDO rather than mysqli, it allows you to perform parameter substitution in the LIMIT clause, by using the PDO::ATTR_EMULATE_PREPARES option. This is automatically enabled for a specific prepared statement if it contains parameters in this clause. See How to apply bindValue method in LIMIT clause? for the specific details.
I've seen lots of good answers in general to the problem of NULL datetime fields, and the answer is don't use '', just put NULL directly.
That's all great, but all my MySQL queries are built up by doing a str_replace, like so:
$query = "SELECT * FROM ##t1 WHERE ##f1=##v1"
I then use table, field and value arrays with the actual content that will be replaced in
For every thing else it works 100% great
For this I can't find a way of getting a NULL in there without quotes around it
Anything obvious I'm missing?
You shouldn't use str_replace for constructing sql because actually it doesn't work 100% of the time.
Use prepared statements instead
http://php.net/manual/en/mysqli.quickstart.prepared-statements.php
An example of where str_replace fails
What if your table name, field name or data contains one of those "##" tokens? Then you are in trouble because it could get replaced with parameters, depending on what order you do your replacements.
With prepared statements the database handles all of this for you. You also get automatic escaping done correctly, query precompilation for better performance and other security protection that you and I probably haven't even thought about.
I have a weird problem.
I have a table which has a title field.
I am inserting values into this title field using mysql_real_escape_string. Inserting is working fine for values with single quotes.
Some other place I am doing a select using title filed in the where clause as below
SELECT * FROM table WHERE title=mysql_real_escape_string(Girish's Photo);
This query is returning empty result set even when I inserted Girish's Photo.
---- Editing to put some code
$photo_title=mysql_real_escape_string($_POST[photo_title]);<br/>
$sql = "INSERT INTO photos values($id,'$photo_title');<br/>
using this from a form I have inserted Girish's Photo into photo_title. It worked fine.
...
..
..
Then at some other place in PHP
$title="Girish's Photo";
$sql = "SELECT photo_id,photo_title FROM photos WHERE photo_title ='" . mysql_real_escape_string($title)."'" ;
But this query is returning empty result set.
Using phpMyAdmin, if I try to run the above query .. the result is empty. If I browse the table I see value Girish\'s Photo
Now if I run the query on phpMyAdmin replacing where clause with where photo_title='Girish\''s Photo' I am getting the record.
$data = "Girish's Photo";
$query = "SELECT * FROM table WHERE title='".mysql_real_escape_string($data)."'";
mysql_real_escape_string() is a PHP-function, which should be used as follow:
"SELECT * FROM table WHERE title='".mysql_real_escape_string("Girish's Photo")."'";
However, this is bad practice.
Okay so you're going to want to use PDO for all queries. Primarily for the following reasons:
mysql_* is being deprecated.
It's not safe from SQL Injection.
PDO is capable of accessing numerous database engines making it much more flexible without changing the API.
Please take a look at this post to get a look at how to issue a SELECT using PDO.
Parameterized SELECT queries via PDO?
I had a similar problem recently which I solved by using htmlentites() instead of mysql_real_escape_string() check it out in the manual or w3 schools
EDIT: this is a valid answer because he's using mysql_real_escape_string() in the wrong context in the first place. if you read the question, he's escaping a FILENAME and therefore he's not at risk of injection. If you're going to downvote at least say why..
The value in your database should not contain backslashes. That's why your query doesn't match. Girish's Photo does not match Girish\'s Photo. Sounds like you are a victim of magic quotes. Read the manual and get rid of them.
I'm trying to match up profiles in my MySQl database with the names and skillsets that are dropped into my droppable div, See HERE. I come across two problems one being the error mysql_fetch_array() expects parameter 1 to be resource, boolean given which I believe means my query is returning false. That takes me to the other problem, my $data not matching anything. How can I match the names and skills dropped into the droppable div with the names and skills in my database?
if (isset($_POST['data'])){
$data = $_POST['data'];
$query = mysql_query("SELECT * FROM gradesheet WHERE 'firstname','lastname','grade' LIKE '{$data}'");
while($row=mysql_fetch_array($query)){
$firstname=$row['firstname'];
$lastname=$row['lastname'];
$gradet=$row['grade'];
$user_id=$row['user_id'];
echo $firstname;
I used %Like% thinking it would give me a better chance than MATCH AGAINST. I would appreciate any knowledge or ideas on matching my query better and having it return something. As well as any tips in general.
You need to do a LIKE for each of the columns in your WHERE statement, and choose either AND or OR to bring them together. The percent symbol % is a wildcard.
SELECT * FROM gradesheet
WHERE 'firstname' LIKE '%term%'
OR 'lastname' LIKE '%term%'
OR 'grade' LIKE '%term%'
You should also avoid using the mysql_* PHP extensions as they have been deprecated; use PDO or mysqli instead. Aside from using deprecated extensions, your code is also wide open for a SQL injection attack. You should always filter data from request variables before sticking it into a query.
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.