How i use preg_replace php function in mysql - php

how to use preg_replace in MySQL query.
"SELECT * FROM video_master WHERE preg_replace( '/\s+- /', ' ', trim($title))"

You need use like this
$pattern = "/\s+- /";
$title= preg_replace($pattern,'',$string);
$query = " SELECT * FROM video_master WHERE column = '$title';";

I think you can use sprintf:
$pattern = "/\s+- /";
$query = sprintf("SELECT * FROM video_master WHERE column = '%s';", preg_replace($pattern,'',$string));
sprintf is always good for MySQL queries in PHP, you avoid create the incorrect dinamic queries, also I recommend you to use mysql_real_escape_string function, this function scapes the special characters of MySQL like apostrophe.
$pattern = "/\s+- /";
$query = sprintf("SELECT * FROM video_master WHERE column = '%s';", mysql_scape_real_string(preg_replace($pattern,'',$string)));
With this function and sprintf, you reduce the risk of a bad behavior or SQL injection attack in your application.
I hope this information helps you.
Good luck.

Related

How to manipulate text in PHP to have single quote and coma

My question must be simple but I can't figure how to do that:
$input = "Hello, Beautiful, World";
and
$expected_output = "'Hello','Beautiful','World'";
I know I can split text by explode(" ", $input);
but how to join with ', ?
Why I need it?
I need to have it to prepare MySQL query like
SELECT value FROM tab_settings WHERE name IN ('Hello', 'Beautiful', 'World')
from $input
You can use below snippet for the same
echo "'".implode("','",explode(", ", $input))."'";
Demo
You can use REGEXP
SELECT * FROM author WHERE aut_name REGEXP 'hello|benny|meny';
Read here Logical AND operator in mySql REGEXP?
This probably answers your specific question:
<?php
$subject = "Hello, Beautiful, World";
preg_match_all('/(\w+)/', $subject, $words);
$words = $words[1];
$tokens = [];
array_walk($words, function($word) use (&$tokens) {
$tokens[] = "'" . $word . "'";
});
$tokens = implode(',', $tokens);
var_dump($tokens);
The output obviously is:
string(27) "'Hello','Beautiful','World'"
But please allow us to offer a hint here:
The strategy you follow to construct sql queries in such a string based manner is ultimately a very bad idea, since it makes your code vulnerable to what is usually referred to as "sql injection attacks". You want to prevent that.
Please start reading about the advantages of using the combination of "prepared statements" and "parameter binding" to prevent such vulnerabilities.

Right way to escape string after replacing quotes?

Is this the right way to escape a string just in case or I can insert string like this without additional escaping?
$filenamefordb = preg_replace('/[^A-Za-z0-9а-яА-Я_\.\-]/u', '', $filenamefordb);
$query = "INSERT INTO file SET filename='$filenamefordb";
I don't use mysqli_escape because I also need name without any quotes in another place
Why don't you escape the string using PDO?
<?php
$conn = new PDO('sqlite:/home/lynn/music.sql3');
/* Complex string */
$string = "Co'mpl''ex \"st'\"ring";
print "Unquoted string: $string\n";
print "Quoted string: " . $conn->quote($string) . "\n";
?>
This will output
Unquoted string: Co'mpl''ex "st'"ring
Quoted string: 'Co''mpl''''ex "st''"ring'
Reference:
http://php.net/manual/it/pdo.quote.php
you can escape it with a generic php function:
$filenamefordb = mysql_escape_string ($filenamefordb);
$query = "INSERT INTO file SET filename='$filenamefordb";

PHP: Variables in a Postgresql Query

Let's say I have these two variables
$number = 1;
$word = "one";
and I want to use them in a pg_query.
This is what I've got:
$result = pg_query($con, 'UPDATE a SET z = ARRAY[{$number}] WHERE word = {pg_escape_literal($word)}');
But it doesn't work..
To use string interpolation, you have to use double quotes:
$x = 3;
"This works: $x" // This works: 3
'This does not: $x'; // This does not: $x
You also can't interpolate function calls into strings like you're attempting with {pg_escape_literal($word)}. You'll need to escape the variable before interpolating it into the string:
$word_esc = pg_escape_literal($word);
$result = pg_query(
$con,
"UPDATE a SET z = ARRAY[$number] WHERE word = $word_esc"
);
You could also use sprintf:
$result = pg_query(
$con,
sprintf(
"update a set z=ARRAY[%d] where word = %s",
$number,
pg_escape_literal($word)
)
);
But the best and safest is to use pg_query_params function, as you don't escape any parameter. And it is very easy to forget and expose your site to SQL-injection attacks.
$result = pg_query_params(
'update a set z=ARRAY[$1] where word = $2',
array($number,$word)
)
Use double instead of single quotes: Double quoted strings expand variables into their values.

Ignoring apostrophes in mysql searches

I want to take a url that does not have any apostrophes, commas or ampersands in it and match it with a record in a database that may have one of those characters.
For example:
mywebsite.com/bobs-big-boy
mywebsite.com/tom--jerry
mywebsite.com/one-two-three
rewrite to
index.php?name=bobs-big-boy
index.php?name=tom--jerry
index.php?name=bobs-big-boy
Then in php I want to use the $_GET['name'] to match the records
bob's big boy
tom & jerry
one, two, three
Now my query looks like this:
"SELECT * from the_records WHERE name=$NAME";
I can't change the records, because they're business names. Is there a way I can write the query to ignore ampersands, commas and apostrophes in the db?
Yes you can but I'm pretty sure it will ignore any indexes you have on the column. And it's disgusting.
Something like
SELECT * FROM the_records
WHERE replace(replace(replace(name, '''', ''), ',', ''), '&', '') = $NAME
By the way taking a get variable like that and injecting it into the mysql query can be ripe for sql injection as far as I know.
pg, I know you said you can't change/update the content in the database you're selecting from, but does anything preclude you from making a table in another database you do have write access to? You could just make a map of urlnames to business names and it'd only be slow the first time you do the replace method.
Greetings,
This one took me a few minutes to puzzle out! There are actually a few specifics missing on you requirements, so I've tried to work through the problem with different assumptions, as stated below.
Here is the set of assumed input from the URL, as pulled from your example, along with a MySQL injection attack (just for giggles), and variations on the business names. The keys are the expected URLs and the values are the database values to match.
<?php
$names = array(
'bobs-big-boy'=>"bob's big boy",
'tom--jerry'=>'tom & jerry',
'tomjerry'=>'tom&jerry',
'one-two-three'=>'one, two, three',
'onetwothree'=>'one,two,three',
"anything' OR 'haxor'='haxor"=>'die-haxor-die',
);
?>
One clever way to do an end-run mySQL's lack of regex replacement is to use SOUNDEX, and this approach would seem to mostly work in this case depending on the level of accuracy you need, the density of and similarity of customer names, etc. For example, this generates the soundex values for the values above:
$soundex_test = $names;
$select = 'SELECT ';
foreach ($soundex_test as $name=>$dbname) {
echo '<p>'.$name.': '.soundex($name).' :: '.$dbname.': '.soundex($dbname).'</p>';
$select .= sprintf("SOUNDEX('%s'),", $name);
}
echo '<pre>MySQL queries with attack -- '.print_r($select,1).'</pre>';
So, assuming that there are not customers named 'one, two, three' and separate one named 'onetwothree', this approach should work nicely.
To use this method, your queries would look something like this:
$soundex_unclean = $names;
foreach ($soundex_unclean as $name=>$dbname) {
$soundex_unclean[$name] = sprintf("SELECT * from the_records WHERE name SOUNDS LIKE '%s';", $name).' /* matches name field = ['.$dbname.'] */';
}
echo '<pre>MySQL queries with attack -- '.print_r(array_values($soundex_unclean),1).'</pre>';
However, here is a run that DOES deal with the injection attack (note the new line). I know this isn't the focus of the question, but ajreal mentioned the issue, so I thought to deal with it as well:
$soundex_clean = $names;
foreach ($soundex_clean as $name=>$dbname) {
// strip out everything but alpha-numerics and dashes
$clean_name = preg_replace('/[^[:alnum:]-]/', '', $name);
$soundex_unclean[$name] = sprintf("SELECT * from the_records WHERE name SOUNDS LIKE '%s';", $clean_name).' /* matches name field = ['.$dbname.'] */';
}
echo '<pre>MySQL queries with attack cleaned -- '.print_r($soundex_unclean,1).'</pre>';
If this approach does not suit, and you decided that the inline replacement approach is sufficient, then do remember to add a replacement for comma to the mix as well. As an example of that approach, I'm assuming here that the single quote, double quote, ampersand, and comma (i.e. ', ", &, and ,) are the only four special characters are included in the database but deleted from the URL, and that any other non-alpha-numeric character, spaces included, are converted to a dash (i.e. -).
First, a run that does not deal with the injection attack:
$unclean = $names;
foreach ($unclean as $name=>$dbname) {
$regex_name = preg_replace('/[-]+/', '[^[:alnum:]]+', $name);
$unclean[$name] = sprintf("SELECT * from the_records WHERE REPLACE(REPLACE(REPLACE(REPLACE(name, ',', ''), '&', ''), '\"', ''), \"'\", '') REGEXP '%s'", $regex_name);
}
echo '<pre>MySQL queries with attack -- '.print_r($unclean,1).'</pre>';
Second, a run that DOES deal with the attack:
$clean = $names;
foreach ($clean as $name=>$dbname) {
$regex_name = preg_replace('/[^[:alnum:]-]/', '', $name);
$regex_name = preg_replace('/[-]+/', '[^[:alnum:]]+', $regex_name);
$clean[$name] = sprintf("SELECT * from the_records WHERE REPLACE(REPLACE(REPLACE(REPLACE(name, ',', ''), '&', ''), '\"', ''), \"'\", '') REGEXP '%s'", $regex_name);
}
echo '<pre>MySQL queries with attack cleaned -- '.print_r($clean,1).'</pre>';
Aaaand that's enough brainstorming for me for one night! =o)
Using str_replace function we will grab the $name parameter and replace
ampersands (&) with ""
spaces (" ") with "-"
commas (",") with ""
apostrophes("'") with ""
str_replace ( mixed $search , mixed $replace , mixed $subject [, int &$count ] )
$Search = { "&", " ", ",", "'" }
$Replace = { "", "-", "", "" }
$ComparableString = str_replace($Search, $Replace, $_GET['name'])
After that we can do the sql query:
$name = mysql_real_escape_string($name, $db_resource);
SELECT * from the_records WHERE name='$name'
It's a little janky, but you could explode the GET and build a WHERE on multiple conditions.
Something like (untested):
$name_array = explode("-", $_GET['name']);
$sql_str = "SELECT * FROM the_records WHERE ";
$first_time = true;
foreach($name_array as $name){
if ($name != ""){
if ($first_time){
$sql_str .= "name LIKE \"%".$name."%\"";
$first_time = false;
}
else {
$sql_str .= " AND name LIKE \"%".$name."%\"";
}
}
}

mysql split search string by space and push into query

The search query is:
"product1 prod2 prod4"
I need to make the mysql
SELECT *
FROM tableprod
WHERE (prod LIKE '%product1%'
AND prod LIKE '%prod2%'
AND prod LIKE '%prod4%')
using the mysql_real_escape_string for the input query...
Simple string manipulation:
$terms = explode(' ', $search);
$bits = array();
foreach ($terms as $term) {
$bits[] = "prod LIKE '%".mysql_real_escape_string($term)."%'";
}
$query = "SELECT * FROM tableprod WHERE (".implode(' AND ', $bits).")";
If you can meet the constraints, you migh be better off just using a FULLTEXT index which would save you the trouble of having to split the string, plus you'd get the bonus of being able to use basic boolean operators for the search (and/or/not)
without a loop(i've always tried to avoid loops):
$str = "product1 prod2 prod4";
$sql = "select * from tableprod where (prod like '%" . str_replace( ' ', '%\' AND prod LIKE \'%', $str ) . '%\')';
if it's possible you will have more than one space inbetween items use preg_replace

Categories