PHP SQL Remove/ignore spaces, tabs etc from search input - php

I am trying to remove the spaces, whitelines and tabs from the user his input when he searches in the sql database.
So basicly he searches 'Test' (two spaces behind the string) it gives zero results while 'Test' is a correct result in the database. How do I make php / sql use only the word 'Test' as keyword in the sql statement so the result is generated even when the user post spaces before or behind the string. We use a lot of copy and paste when searching so spaces and stuff are in the paste a lot of the time.
I am aware of the questions that are allready here. And I tried all I could implent (as you can see in the overkill tryout..) but none seem to do the trick..
Please help, what am I doing wrong here?
$searchresult = trim(filter_var(isset($_POST['usearch10'])?$_POST['usearch10']:'' , FILTER_SANITIZE_STRING));
$save = trim(filter_var("%{$_POST['usearch10']}%", FILTER_SANITIZE_STRING));
$safedef = trim($save);
$stmt2 = $mysqli->prepare("SELECT * FROM table WHERE `colomn` LIKE trim(?)");
$stmt2->bind_param("s",$safedef);
$stmt2->execute();
$result = $stmt2->get_result();
while ($obj = $result->fetch_assoc()) {

You need to do two things. One is remove the spaces, and trim is enough for that. Unless you're copy-pasting from Microsoft Word, where you could get hidden whitespaces, nonbreaking spaces, and possibly snakes. To get rid of those you might need to use a regular expression (requiring UTF8/mbstring support),
$search = preg_replace('#^\\s*(.*)\\s*$#', '\\1', $search);
I am not sure, but maybe if you copy and paste from HTML you might even encounter a " " instead of a space, so you might want to also use html_entity_decode (after verifying you need it - it can be quite the source of other troubles).
Then you need to specify an inclusion; do that after the filtering, just in case, like this
$search = trim($search);
$search = "%{$search}%"; // search term anywhere
WHERE `column` LIKE ? # You wrote 'colomn' but I assume it was a typo
This simply has to work, but you could also do it this way:
...WHERE `column` LIKE CONCAT('%', ?, '%');
to be sure that MySQL understands what you're trying to tell it.
Try also printing the search term and the query and running it by hand to see what happens. And always check that the query did run successfully. To be even safer, dump the json_encode($search). So, if you forgot a semispace, you'll see not the expected "Test" but something like, if memory serves, "Test\u00a0".
If the absolute worst comes to the worst, activate the session-level "general_log" in MySQL and inspect the actual query MySQL gets sent in the MySQL log_file.

I have never used trim in SQL, but if that is changing something or not, your problem could be that you are not searching like LIKE ”%STRING_TO_SEARCH%". % at the beginning will tell to match anything before it, and the same character at the end will tell to also match anything after your desired string.

Related

Pervasive SQL with WHERE - matching spaces

Our accounting application is using Pervasive SQL 10. I need to fetch data of products from it. Problem is that the "name" column has fixed length of 12 and the application is filling the rest with spaces.
So every time I use my PHP script to fetch data, I need to fill the rest of the name with spaces to match it in WHERE clause.
Example data in the column:
65LD11
42BRD03
65LD112
(space)65LD12
165LD12
I have been using: SELECT * FROM products WHERE name LIKE '65LD12%';. Which is not perfect, but the biggest problem is with the name with space as first character, because I can't use _ or % as it would match both 65LD12 and 165LD12 name.
There can be any number of spaces at the beginning or at the end. In MySQL I would use REGEXP_LIKE to match only the spaces, but here in Pervasive I am kind of lost. Is there some way how to do this?
I don't know about Pervasive, but in Standard SQL you can do a simple
WHERE TRIM(name) = '65LD12'
Of course it would be better to clean the data and remove unnecessary leading spaces, TRIM will prevent the usage on an index. And then name = '65LD12' should return the correct data regardless of trailing blanks (again, I don't know if Pervasive implements that correctly)
edit based on comments:
There's no TRIM in Pervasive, but LTRIM:
WHERE LTRIM(name) = '65LD12'
If this is still not returning the correct rows (i.e. Pervasive implemented string comparison in a wrong way) you have to add RTRIM, too:
WHERE RTRIM(LTRIM(name)) = '65LD12'
Try this:
SELECT * FROM products WHERE REPLACE(name,' ','') LIKE '65LD12%';
You can use the Replace function. http://help.pervasive.com/display/DI1025/StrReplace+Function

Is there a typo in this str_replace code? / Am I reading it correctly?

Here is the line of code from a PHP file, specifically it is from zstore.php which is a file include as part of the "Zazzle Store Builder" toolset from Zazzle.com
The set of files allows someone like me, who has products for sale on Zazzle and massage that data into a nicer "storefront" which I can set up my way instead of being confined by the CMS structure of Zazzle.com where they understandably want to keep the monkeys (uhmmm... users like myself) from causing too much mayhem.
So... here is the code:
$keywords = str_replace(" ",",",str_replace(",","",$keywords));
Two questions:
Am I understanding what it does and
Is there an extra single or double quote in the string that does not need to be there?
Here is what I think the line of code is saying:
Take the string of characters that the user inputs (dance diva) and assign it to the variable called
$keywords
then run the following function on that character string
= str_replace
(" ","," <<< look for spaces. If you find a space, replace it with a comma
,str_replace(",","" <<< this is the bit I don't understand or which may have a typo
I THINK that it is saying " if you find commas, leave them alone, but I'm not certain.
,$keywords)); <<< then put the edited string of characters backing to the variable called $keywords.
What lead me to look at this was that I was inputting the following:
dance,diva which is what I THOUGHT the script was wanting from me based on the commented text in the README.txt file:
// Search terms. Comma separated keywords you can use to select products for your store
So..
Am I understanding what this line of code is supposed to do?
which, assuming I am correct, and I'm pretty sure that the first half is supposed to work as I've described, now brings me to my second question:
Why isn't the second bit working? Is there a typo?
To review:
dance diva produces results
dance,diva does not
Both, SHOULD work.
Thanks in advance for your help. I have a lot of HTML experience and computer experience but PHP is new to me.
$keywords = str_replace(" ",",",str_replace(",","",$keywords));
You can split into
$temp = str_replace(",","",$keywords);
$keywords = str_replace(" ",",",$temp);
First it replaces all comas with empty string, it is removes all comas. Then replaces all spaces with comas.
For "dance diva" there are no comas so first does nothing, then it replaces space and result is "dance,diva"
For "dance,diva" it removes coma, you get "dancediva" and there in no space to replace next so it is Your result.

Why not backslash every empty space to prevent mysql injections

I've been wondering this for maybe a few months now but I still don't know an answer, other then possible speed performance. So long story short, instead of having all this PDO codes everywhere, why not just put a backslash between every character?
$String = $_POST["attack"]; // SOME THING' OR 1 = 1 --
$String = fFilter( $String ); // \S\O\M\E\ \T\H\I\N\G\'\ \O\R\ \1\ \=\ \1\ \-\-
Now I haven't been into this SQL stuff in awhile, so I can't give a perfect example, but basically the sql string should look like this SELECT * FROM account WHERE id = '\S\O\M\E\ \T\H\I\N\G\'\ \O\R\ \1\ \=\ \1\ \-\-' and something like that just always seemed pretty safe, but I haven't heard of anyone using it, or even why not to use it. I always see things like filtering html and etc isn't good, but I don't see why not just filter every single character. Since any attack would look like \a\t\t\a\c\k.
Because placing a backslash before certain characters changes their meaning entirely. For instance, \t is a tab character, not t, so \a\t\t\a\c\k would be transformed to:
a ack
A full list of such sequences is given at:
http://dev.mysql.com/doc/refman/5.5/en/string-literals.html
As several other people have mentioned, use parameterized queries, not input escaping.

Wrapping words in a SQL query string with regex

I have a database class that is written in PHP and it should take care of some things I don't want to care about. One of these features is handling the decryption of columns that are encoded with the AES function of MySQL.
This works perfect in normal cases (which in my opinion means that there is no alias in the query string "AS bla_bla"). Lets say that someone writes a query string that contains an alias, which contains the name of a column the script should decrypt, the query dies, because my regex wraps not only the column, but the alias as well. That is not how its supposed to be.
This is the regex I've written:
preg_replace("/(((\`|)\w+(\`|)\.|)[encrypted|column|list])/i", "AES_DECRYPT(${0},'the hash')"
The part with the grave accents is there because sometimes the query does contain the table name which is either inside of grave accents or not.
An example input:
SELECT encrypted, something AS 'a_column' FROM a_table;
An example output:
SELECT AES_DECRYPT(encrypted, 'the hash'), something AS 'a_AES_DECRYPT(column, 'the hash')' FROM a_table;
As you can see, this is not going to work, so my idea was to search only for words, that are not right after the word 'as' until a special character or a white space appears. Of course i tried it hours to work, but I don't get the correct syntax.
Is it possible to solve this with pure regex and if yes how would it look like?
This should get you started:
$quoted_name = '(\w+|`\w+`|"\w+"|\'\w+\')';
preg_match("/^SELECT ((, )?$quoted_name( AS $quoted_name)?)* FROM $quoted_name;$/", "SELECT encrypted, something AS 'a_column' FROM a_table;", $m);
var_dump($m);
The replacement parts should be easy to spot an write after you study the var_dump.

php mysql LIKE with special characters does not work properly

So i am trying to do a LIKE query and get some results but the text that i pass has some special characters that break the query.
if we assume that the text is something like this:
var test `select` `query`="$newval + "dsadsa$ ? "$test ?
and i also have exactly the same text inside a column as VARCHAR
and then executing the query
SELECT * FROM table WHERE column LIKE '%$text%'
says that there is no rows to return.
EDIT: when i post the data inside the database i simply use mysql real escape string and when i show the text where i click to search i put htmlentities on the text
then i substr it from 0 to 50 and do the search query
You can use mysql_real_escape_string() which will escape any special characters in your string.
Try to avoid writing variables directly into string, it may cause problems (+ it's really not nice):
mysql_query("SELECT * FROM table WHERE column LIKE '%" . $text . "%'");
Of course make sure that the $text variable is really correct (echo $text), characters escaping may cause problems too and of course there can be many other things causing problems (this depends on architecture of your application - where you work with $text).

Categories