I'm having an issue trying to bind and execute a PDO statement using PHP and a REGEXP for a SQLite database. I have a column containing string words separated by spaces, and I am using the following REGEXP (?<!\S)WORD(?!\S) to match complete words that are surrounded by white space. The following SQL query works when I run in SQLite studio and gives me the desired results:
SELECT * FROM Questions WHERE Tags REGEXP '(?<!\S)WORD(?!\S)'
However, when I try to use it in a PDO statement, it keeps failing. So far I have tried:
$sql = "SELECT * FROM Questions WHERE Tags REGEXP :tags";
$tags = '(?<!\S)WORD(?!\S)';
$statement = $db -> prepare($sql);
$statement -> bindParam(':tags', $tags);
and I have also tried escaping backslashes as well as running the query directly without using any prepared statements and simply using a known working query and it still seems to fail.
Ex w/o binds:
$sql = "SELECT * FROM Questions WHERE Tags REGEXP '(?<!\S)TAG(?!\S)'";
$statement = $db -> query($sql);
However that doesn't seem to work with the REGEXP either. If I change it to a simple SELECT * from the entire table or any non-REGEXP query everything seems to work fine until I add in those REGEXPs. I'm pretty new to PHP so I'm not entirely sure what is going on here or where to look. Any help would be appreciated!
Related
I have a question.
I have the following query:
$query = "select * from module,bloc where module.id_bloc = ?";
I tried to bind the value so I did:
$stmt = $this->db->prepare($query);
$stmt->bindValue(1, "bloc.id_bloc");
But, when I test I don't get any result on my browser.
It's weird because when I replace directly inside like the following code:
$query = "select * from module,bloc where module.id_bloc = bloc.id_bloc";
I get the the right result on my browser.
Could someone explain to me why it doesn't work when I am doing a bindValue?
It will not work because, when bound, a string will be quoted. (Or, for all intents and purposes, work as if it were quoted, however PDO may handle it behind the scenes.) Then, your query is interpreted as:
select * from module,bloc where module.id_bloc = 'bloc.id_bloc'
That is: It will be interpreted as a literal string, rather than a reference to a table column, and will obviously not give you the expected result. There is no need for binding it to begin with.
If, for some reason, you need to run a query with a variable table/column name from an unsafe source, you will have to manually format/sanitize it; see here for an example of how to do it.
I am integrating Sphinxsearch into my site, and rewriting my old code to use Sphinx.
The problem i got is with special characters inside MATCH in SphinxQL.
Example : want to search for H&M
With plain mysql i get thousand of records, so im quite sure i got title's containing that word in my database.
I don't need extended query syntax in MATCH.
$q = "h&m";
$spxq = "SELECT * FROM sphinx_index WHERE MATCH(:query) LIMIT 0,10";
$stmt = $DB->prepare($spxq);
$stmt->bindValue(':query', $q, PDO::PARAM_STR);
$stmt->execute();
$res = $stmt->fetchAll(PDO::FETCH_ASSOC);
This isn't returning any results.
After this i tried escaping $q so :
$q = "h\&m";
Still not working.Tried with double escaping too, still not working.
Any help would be appriciated.
Ok, i got this, if anyone in the future has this same problem.
The solution is to add the special characters you want to be able to search for in the sphinx.conf file, in the charset_table.
So for my case of H&M, you need to add the & character (U+026) in to the charset table.
I have this database I created with a phpMyAdmin client. Specific queries like SELECT * FROM TagData LIMIT 0,10 in my php code runs perfect. But when I add a wildcard to the query like SELECT * FROM TagData WHERE Device_Name LIKE 'Valve%' LIMIT 0,10 it doesn't work. The strange thing is that the exact same SQL works perfect in the phpMyAdmin tool.
This is how I run my query in php:
$query="SELECT * FROM TagData WHERE Device_Name LIKE 'Valve%' LIMIT 0,10";
$tmpResult=mysql_query(sprintf($query));
I have a strong feeling that the quote characters in the $query string are the problem. Can someone please explain me what I am doing wrong and why I am doing this wrong.
The result mysql_error() gives is:
Query was empty
You dont need sprintf when you dont insert any custom parameters.
Just leave it raw.
Your query was emtpy because the string you gave to sprintf was malformed and sprintf returned null/ an empty string.
You need parameters to place in sprintf otherwise this has no use. And % is a control character for sprintf, to escape this you would have to place %% instead of % but my advice here ins aslong as you do not have any parameters, just dont use it!
To make your query work just fire it raw
$query= "SELECT * FROM TagData WHERE Device_Name LIKE 'Valve%' LIMIT 0,10";
$tmpResult = mysql_query($query);
And now, please have a look what sprintf actually does:
http://php.net/manual/en/function.sprintf.php
However please consider upgrading to MySQLi or PHP/PDO extension because MySQL class is outdated, deprecated, unsave, slow and will be removed from PHP in the future.
http://php.net/manual/en/book.mysqli.php
http://php.net/manual/en/book.pdo.php
I've been looking through a bunch of topics but haven't found anything that works yet - or maybe it does, but I'm pretty new to PHP/MySQL, so maybe I'm just missing something.
I've got a page that allows users to type in the name of an item to look it up in the (MySQL) database. It then generates a table of results and displays those, and turns some of the data into links. The linked terms are then used as queries to search other fields of the database.
Everything works... except when one of the search terms contains an apostrophe. Obviously I want to prevent injection issues, but I also need to search with the apostrophes. Here's the code I have:
$query = mysql_real_escape_string($query);
$query = htmlspecialchars($query);
$queryentered = $query;
$query = strtolower($query);
And here's the URL that's it's passing to the query:
echo " from <a href='index.php?volume=".$results2['book']."' class='where'>"
.$results2['book']."</a>";
And the query:
$raw_results = mysql_query("SELECT * FROM $database1 WHERE $wh LIKE '%$query%'
ORDER BY displayname") or die(mysql_error());
What am I not encoding right? When I run a search, it displays "No results found for [search term]", where I'm getting \' for any apostrophes.
This snippet is in exactly the wrong order:
$query = mysql_real_escape_string($query);
$query = htmlspecialchars($query);
$queryentered = $query;
$query = strtolower($query);
Escaping should be done last, right before the database query string concatenation. In this case it's irrelevant as strtolower does not undo the escaping. More severe is actually the HTML escaping, which does not belong in SQL context. Don't overwrite your main variable, instead:
$queryentered = htmlspecialchars($query);
$query = strtolower($query);
$query = mysql_real_escape_string($query);
The cumbersome database escaping, btw, is easy to avoid. Look into PDO and prepared statements.
problem is in this line:
$query = htmlspecialchars($query);
If you search for Death's book your final $query would be death\'s book!
By removing htmlspecialchars your query would be fine!
I'd STRONGLY recommend using prepared statements and the PDO library.
Really easy to learn
Will make your question easier to solve
Works with (most) any database
Goes a long way to prevent the injection issues you mention
Skill set will be applicable to other languages you may learn
All you have to do is write the query, then prepare a connection string (with the database type and details) and then fire off the query. An array of parameters is sent with the query, to decouple the data.
Helpful links:
http://net.tutsplus.com/tutorials/php/why-you-should-be-using-phps-pdo-for-database-access/
http://id1.php.net/pdo
This question already has answers here:
How do I create a PDO parameterized query with a LIKE statement?
(9 answers)
Closed 3 years ago.
I am new to PHP, and am trying to learn to use PDO to connect to a test MySQL db. I have the following:
try {
$db = new PDO('mysql:dbname=MYDBNAME;host=MYHOST', 'USERNAME', 'PASSWORD');
$query = "select * from books where ? like '%?%'";
$stmt = $db->prepare($query);
$stmt->execute(array($searchtype, $searchterm));
} catch(PDOException $e) {
echo 'PDOException: ' . $e->getMessage();
}
When I try it I get the following warning:
Warning: PDOStatement::execute() [pdostatement.execute]: SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens
When I remove the like clause, and the $searchterm param, it returns the result properly. I thought -- like '%?%' -- might not be a legal way to create this query under double quotes, so I tried escaping ', which did not work. I looked around for a solution, and found that someone moved '% and %' down to where $searchterm is:
$query = "select * from books where ? like ?";
...
$stmt->execute(array($searchtype, '\'%'.$searchterm.'%\''));
I got the same result.
Any help is appreciated. Thanks!
/ UPDATE ****/
I found on example 12 of http://us3.php.net/manual/en/pdo.prepared-statements.php
Example #12 Invalid use of placeholder
<?php
$stmt = $dbh->prepare("SELECT * FROM REGISTRY where name LIKE '%?%'");
$stmt->execute(array($_GET['name']));
// Below is What they suggest is the correct way.
// placeholder must be used in the place of the whole value
$stmt = $dbh->prepare("SELECT * FROM REGISTRY where name LIKE ?");
$stmt->execute(array("%$_GET[name]%"));
?>
I tried this, and even though I no longer get a Warning, I do not get any results. However when I execute the query directly I will get a couple of results. Any thoughts?
Don't add the quotes when binding prepared variables and dont bind the column name
$query = sprintf( "select * from books where %s like ?", $searchtype );
...
$stmt->execute(array($searchtype, '%'.$searchterm.'%'));
$stmt->execute(array($searchtype, '\'%'.$searchterm.'%\''));
This isn't how parameterised queries work. Inserted parameters act as literal strings already, you don't have to add quote delimiters around them or escape them (that's the whole point), and if you try, you're literally comparing against the string single-quote-searchterm-single-quote.
Consequently if you are (as I suspect) intending to compare a particular column against a literal string, you don't parameterise the column name. At the moment you are comparing a literal string to another literal string, so it'll either always be true or always false regardless of the data in the row!
So I think what you probably mean is:
$query= "SELECT * FROM books WHERE $searchtype LIKE ?";
$like= "%$searchterm%";
$stmt->execute(array($like));
thought naturally you will have to be very careful that $searchtype is known-good to avoid SQL-injection. Typically you would compare it against a list of acceptable column names before using it.
(Aside: there is a way of putting arbitrary strings in a schema name that you can use for a column, but it's annoying, varies across databases and there isn't a standard escaping function for it. In MySQL, you backslash-escape the backquote character, quotes and backslashes and surround the name with backquotes. In ANSI SQL you use double-quotes with doubled-double-quotes inside. In SQL Server you use square brackets. However in reality you vary rarely need to do any of this because really you only ever want to allow a few predefined column names.)
(Another aside: if you want to be able to allow $searchterm values with literal percents, underlines or backslashes in—so users can search for “100%” without matching any string with 100 in—you have to use an explicit escape character, which is a bit tedious:)
$query= "SELECT * FROM books WHERE $searchtype LIKE ? ESCAPE '+'";
$like= str_replace(array('+', '%', '_'), array('++', '+%', '+_'), $searchterm);
$stmt->execute(array("%$like%"));
The problem I see is if you had written a wrapper for PDO, then you would have to somehow handle this separately. The answer I had found and loved was write your query and concat the % to the parameter. i.e. "WHERE column like concat('%', :something, '%')"