How to implement REGEXP in foreach the right way? - php

Hello,
How to add regexp the right way in this code in order to search for exact word in database?
$condition = '';
$name = "he is mad";
$query = explode(" ", $name);
foreach($query as $text) {
$condition .= "test LIKE '%".mysqli_real_escape_string($conn, $text)."%' OR ";
}
$condition = rtrim($condition, " OR ");
$sql_query = "SELECT * FROM test WHERE " . $condition;
$result = mysqli_query($conn, $sql_query);
if ($result->num_rows > 0) {
echo "1";
} else {
echo "0";
}
$conn->close();
I want to add this to the php code
SELECT
*
FROM
`table`
WHERE
Description regexp '(^|[[:space:]])pen([[:space:]]|$)';
It only works with me like this without foreach:
$sql_query = "SELECT * FROM test WHERE test regexp '(^|[[:space:]])$condition([[:space:]]|$)'";

You just need to remove the last " OR " from your $condition
<?php
$condition = '';
$name = "Hello world i am so sad";
$query = explode(" ", $name);
foreach($query as $text) {
$condition .= "test LIKE '%".mysqli_real_escape_string($conn, $text)."%' OR ";
}
// HERE REMOVE LAST " OR " FROM STRING
$condition = rtrim($condition, " OR ");
$sql_query = "SELECT * FROM test WHERE " . $condition;
$result = mysqli_query($conn, $sql_query);
if ($result->num_rows > 0) {
echo "1";
} else {
echo "0";
}
$conn->close();

If you have a phrase that is separated by spaces and you want to see if there is any overlap with the words, you can possibly use regular expressions:
where col regexp replace($name, ' ', '|')
Note that you should be passing $name in as a parameter.
If you care about word boundaries, you can introduce them into the regular expression. However, the exact form may depend on which regular expression library MySQL is using. The idea is:
where col regexp concat('\\b', replace($name, ' ', '\\b|\\b'), '\\b')

Related

PHP prepared SQL with multiple LIKE condition

I want to do a search in a table with search words defined by a user.
I'm doing this by splitting the string an constructing the sql.
But i can't seem to make it work. It works fine, if only one word is entered, but with two or more words it's crashing.
$q = $_GET['q']; //Search word
$q = htmlspecialchars($q);
$q_exploded = explode ( " ", $q );
foreach( $q_exploded as $search_each ) {
$where .= "content LIKE ? OR ";
$bind .= "s";
$param .= "%$search_each%, ";
}
$where = rtrim($where,'OR ');
$param = rtrim($param,', ');
$sql = "SELECT ads_id FROM search_index WHERE ".$where."";
echo $sql . "<br>".$param."<br>".$bind."<br>";
$stmt = $dbconn->prepare($sql);
$stmt->bind_param($bind, $param);
$stmt->execute();
$result = $stmt->get_result();
while ($row = $result->fetch_assoc()) {
echo $row['ads_id'];
}
This is my error
SELECT ads_id FROM search_index WHERE content LIKE ? OR content LIKE ?
%word1%, %word2%
ss
Warning: mysqli_stmt::bind_param(): Number of elements in type
definition string doesn't match number of bind variables
You issue is here:
$stmt->bind_param($bind, $param);
What you're doing is:
$stmt->bind_param("ss", $param);
While you may intend param to satisfy both of the strings it doesn't you need to pass a variable for each one. I would try looking into explode for this.
Someone posted an answer earlier, but deleted it again. That answer actually worked, i just needed to change from mySQLi to DPO.
Solution:
$q = htmlspecialchars($q);
$q_exploded = explode ( " ", $q );
$where = [];
$bind = [];
foreach ($q_exploded as $idx => $search_each) {
$key = ':val' . $idx;
$where[] = "content LIKE " . $key;
$bind[$key] = "%$search_each%";
}
$sql = "SELECT ads_id FROM search_index WHERE " . implode(" OR ", $where);
$stmt = $pdo_conn->prepare($sql);
$stmt->execute($bind);
$result = $stmt->setFetchMode(PDO::FETCH_ASSOC);
while ($row = $stmt->fetch()) {
echo $row['ads_id'] . "<br>";
}

Split sentence into words and check MySQL for occurance

I have a variable that is a sentence for example this is a sentence. I have a MySQL database which has rows where one column contains the following:
"random sentences"
"few random words"
"this is cool"
"a car"
"nice placement"
I need to print out occurrences of any word in the sentence existing in the database rows. For the example sentence given above, the result would be:
"random sentences"
"this is cool"
"a car"
This is what I have tried so far:
<?php
$servername = "localhost";
$username = "dsfdsfds";
$password = "sdfdfsdsf";
$dbname = "sdf";
$conn = new mysqli($servername, $username, $password, $dbname);
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$galleries = "This is a sentence";
$sql = "
SELECT *
FROM rawwords
WHERE origin LIKE '%" . $galleries. "%'
";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
while($row = $result->fetch_assoc()) {
echo "id: " . $row["id"]. " - location: " . $row["sentence"]. " <br><br>";
}
} else {
echo "0 results";
}
$conn->close();
?>
Create the right sql :D
$galleries ="This is a sentence";
$arr = explode(" ", $galleries);
$sql = "SELECT * FROM rawwords WHERE origin LIKE";
$lenght = count($arr);
for ($i=0; $i<$lenght; $i++) {
if ($i == 0) {
$sql .=" '% " . $arr[$i]. " %'";
} else {
$sql .=" or '% " . $arr[$i]. " %'";
}
}
You could use REGEXP to fin words in your sentences using [[:<:]]word[[:>:]] (word boundaries). You could split your string to get words, then use array_map() to transform them for the query. Finally, you could use implode() with " or " glue:
$galleries = "This is a sentence" ;
$words = preg_split('~\W~', $galleries, -1, PREG_SPLIT_NO_EMPTY);
$words = array_map(function($word) {
return ' origin REGEXP "[[:<:]]'.$word.'[[:>:]]" ';
}, $words);
$where = implode(' OR ', $words);
$sql = "SELECT * FROM rawwords WHERE $where";
Will generate the query:
SELECT * FROM rawwords
WHERE origin REGEXP "[[:<:]]This[[:>:]]"
OR origin REGEXP "[[:<:]]is[[:>:]]"
OR origin REGEXP "[[:<:]]a[[:>:]]"
OR origin REGEXP "[[:<:]]sentence[[:>:]]"
Important, you should have an attentive look to parameterized queries.
Please read this article with several examples: How can I prevent SQL injection in PHP?

SQLite3::query(): Unable to prepare statement: 1, unrecognized token ""

I am trying to create a PHP search query that searches by each word from the database. But i get this error when search query is submitted.
Warning: SQLite3::query(): Unable to prepare statement: 1, unrecognized token: "'%export%" in C:\xampp\htdocs\xport\searchresult.php on line 107
Below is my code.
For the search page
if (isset($_POST['mainSearch']))
{
if (!empty($_POST['mainSearch']))
{
$searchquery = $_POST['mainSearch'];
$query = str_replace(" ", "+", $_POST['mainSearch']);
header("Location: searchresult.php?mainSearch=" . $query);
}
}
Page to display search result.
if (isset($_GET["mainSearch"]))
{
$condition = '';
$query = explode(" ", $_GET['mainSearch']);
foreach ($query as $text)
{
$condition .= "question LIKE '%".SQLite3::escapeString($text)."%' OR answer LIKE '%".SQLite3::escapeString($text)."%'";
}
$condition = substr($condition, 0, -4);
$sql_query = "SELECT * FROM questions WHERE " . $condition;
$result = $db->query($sql_query);
if ($result)
{
while ($row = $result->fetchArray(SQLITE3_ASSOC))
{
echo '<div class="quesbox_2">
<div class="questitle">
<h2>'.$row["question"].'</h2>
</div>
<div class="quesanswer">'.$row["answer"].'</div>
</div>';
}
}
else
{
}
}
What is the reason for this error. I think its because the string is not properly escaped, if this is the reason how do i mysqli_real_escape_string() in SQLite3 (this is the database i am using). If not, Please how do i fix this.
Change the number of substring to -3.
So change
$condition = substr($condition, 0, -4);
to the new
$condition = substr($condition, 0, -3);
This should do the trick.
Try it this way if you are trying to search by each word
<?php
if (isset($_GET["mainSearch"]))
{
$condition = '';
$query = explode(" ", $_GET["mainSearch"]);
foreach ($query as $text)
{
//change condition query
$condition .= "question LIKE '%".SQLite3::escapeString($text)."%' OR ";
}
$condition = substr($condition, 0, -4);
$sql_query = "SELECT * FROM questions WHERE " . $condition;
$sql_query_count = "SELECT COUNT(*) as count FROM questions WHERE " . $condition;
$result = $db->query($sql_query);
//count query result to display something else if no records where found.
$resultCount = $db->querySingle($sql_query_count);
if ($resultCount > 0)
{
if ($result)
{
while ($row = $result->fetchArray(SQLITE3_ASSOC))
{
echo '<div class="quesbox_3">
<div class="questitle">
<h2>'.$row["question"].'</h2>
</div>
<div class="quesanswer">'.$row["answer"].'</div>
</div>';
}
}
}
else
{
echo "No results found";
}
}
?>
Seems you need an OR condition in your WHERE clause that will fetch all results matching any of the words. Just add OR at the end of your query part and you should be fine.
foreach ($query as $text)
{
$condition .= "question LIKE '%".SQLite3::escapeString($text)."%' OR answer LIKE '%".SQLite3::escapeString($text)."%' OR ";
}
// Will chop 4 characters ' OR ' from end of the string
$condition = substr($condition, 0, -4);
To make it little clean, you can escapeString once when retrieved from the parameter to avoid escaping it again and again in the loop.
$mainSearch = SQLite3::escapeString($_GET['mainSearch']);
$query = explode(" ", $mainSearch);
foreach ($query as $text)
{
$condition .= "question LIKE '%$text%' OR answer LIKE '%$text%' OR ";
}
// Will chop 4 characters ' OR ' from end of the string
$condition = substr($condition, 0, -4);

Multi word search in PHP/MySQL

I'm struggling to create a search that searches for multiple words. My first attempt yielded no results whatsoever and is as follows:
require_once('database_conn.php');
if($_POST){
$explodedSearch = explode (" ", $_POST['quickSearch']);
foreach($explodedSearch as $search){
$query = "SELECT *
FROM jobseeker
WHERE forename like '%$search%' or surname like '%$search%'
ORDER BY userID
LIMIT 5";
$result = mysql_query($query);
}
while($userData=mysql_fetch_array($result)){
$forename=$userData['forename'];
$surname=$userData['surname'];
$profPic=$userData['profilePicture'];
$location=$userData['location'];
echo "<div class=\"result\">
<img class=\"quickImage\" src=\"" . $profPic. "\" width=\"45\" height=\"45\"/>
<p class=\"quickName\">" . $forename . " " . $surname . "</p>
<p class=\"quickLocation\"> " . $location . "</p>
</div>";
}
}
I also tried the following, which yielded results, but as you can imagine, I was getting duplicate results for every word I entered:
if($_POST){
$explodedSearch = explode (" ", $_POST['quickSearch']);
foreach($explodedSearch as $search){
$query = "SELECT *
FROM jobseeker
WHERE forename like '%$search%' or surname like '%$search%'
ORDER BY userID
LIMIT 5";
$result .= mysql_query($query);
while($userData=mysql_fetch_array($result)){
$forename=$userData['forename'];
$surname=$userData['surname'];
$profPic=$userData['profilePicture'];
$location=$userData['location'];
echo "<div class=\"result\">
<img class=\"quickImage\" src=\"" . $profPic. "\" width=\"45\" height=\"45\"/>
<p class=\"quickName\">" . $forename . " " . $surname . "</p>
<p class=\"quickLocation\"> " . $location . "</p>
</div>";
}
}
}
I'm pretty much at a loss as to how to proceed with this, any help would be greatly appreciated.
EDIT:
if($_POST){
$quickSearch = $_POST['quickSearch'];
$explodedSearch = explode (" ", trim($quickSearch));
$queryArray = array();
foreach($explodedSearch as $search){
$term = mysql_real_escape_string($search);
$queryArray[] = "forename like '%" . $term . "%' surname like '%" . $term . "%'";
}
$implodedSearch = implode(' or ', $queryArray);
$query="SELECT *
FROM jobseeker
WHERE ($implodedSearch)
ORDER BY userID
LIMIT 5";
$result = mysql_query($query);
while($userData=mysql_fetch_array($result, MYSQL_ASSOC)){
$forename=$userData['forename'];
$surname=$userData['surname'];
$profPic=$userData['profilePicture'];
$location=$userData['location'];
echo "<div class=\"result\">
<img class=\"quickImage\" src=\"" . $profPic. "\" width=\"45\" height=\"45\"/>
<p class=\"quickName\">" . $forename . " " . $surname . "</p>
<p class=\"quickLocation\"> " . $location . "</p>
</div>";
}
}
I've been working on the same subject (search with keywords) for a while and this how i did it :
$words = $_POST['keywords'];
if(empty($words)){
//redirect somewhere else!
}
$parts = explode(" ",trim($words));
$clauses=array();
foreach ($parts as $part){
//function_description in my case , replace it with whatever u want in ur table
$clauses[]="function_description LIKE '%" . mysql_real_escape_string($part) . "%'";
}
$clause=implode(' OR ' ,$clauses);
//select your condition and add "AND ($clauses)" .
$sql="SELECT *
FROM functions
WHERE
user_name='{$user_name}'
AND ($clause) ";
$results=mysql_query($sql,$connection);
if(!$results){
redirect("errors/error_db.html");
}
else if($results){
$rows = array();
<?php
while($rows = mysql_fetch_array($results, MYSQL_ASSOC))
{
// echo whatever u want !
}
?>
-- Now this is how it look when i tried to run it with FULLTEXT search :
But you should set the table type as "MyISAM"
<?php
$words = mysql_real_escape_string($_POST['function_keywords']);
if(empty($words)){
redirect("welcome.php?error=search_empty");
}
//if the columns(results)>1/2(columns) => it will return nothing!(use "NATURAL LANGUAGE"="BOOLEAN")
$sql="SELECT * FROM functions
WHERE MATCH (function_description)
AGAINST ('{$words}' IN NATURAL LANGUAGE MODE)";
$results=mysql_query($sql,$connection);
if(!$results){
redirect("errors/error_db.html");
}
else if($results){
$rows = array();
while($rows = mysql_fetch_array($results, MYSQL_ASSOC))
{
// echo
}
}
?>
Perhaps what you are looking for is a MySQL full-text search.
For your example, you could do something like:
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$search = $_POST['quickSearch'];
// Todo: escape $search
$sql = "
SELECT
*,
MATCH (`forename`)
AGAINST ('{$search}' IN NATURAL LANGUAGE MODE) AS `score`
FROM `jobseeker`
WHERE
MATCH (`forename`)
AGAINST ('{$search}' IN NATURAL LANGUAGE MODE)";
// Todo: execute query and gather results
}
Note that you will need to add a FULLTEXT index to the column forename.
Take a look at MySQL fulltext searches, if you must use MySQL. Otherwise take a look at SOLR, which is a fulltext search engine. You can use MySQL and SOLR in combination to provide enterprise level search capabilities for your apps.
here's what i did
if (isset($_POST['search'])){
$words = mysql_real_escape_string($_POST['searchfield']);
$arraySearch = explode(" ", trim($words));
$countSearch = count($arraySearch);
$a = 0;
$query = "SELECT * FROM parts WHERE ";
$quote = "'";
while ($a < $countSearch)
{
$query = $query."description LIKE $quote%$arraySearch[$a]%$quote ";
$a++;
if ($a < $countSearch)
{
$query = $query." AND ";
}
}
$result=mysql_query($query) or die(error);
//you could just leave it here, short and sweet but i added some extra code for if it doesnt turn up any results then it searches for either word rather than boths words//
$num = mysql_num_rows($result);
if ($num == 0){
$a = 0;
$query = "SELECT * FROM parts WHERE ";
while ($a < $countSearch)
{
$query = $query."description LIKE $quote%$arraySearch[$a]%$quote ";
$a++;
if ($a < $countSearch)
{
$query = $query." OR ";
$msg = "No exact match for: $words. Maybe this is what you're looking for though? If not please try again.";
}
}
}
$result=mysql_query($query) or die($query);
if (mysql_num_rows($result) == 0){
$msg = "No results, please try another search";
}
}

mysql search using for loop from php

i am a beginner. but I'm practicing a lot for few days with php mysql, and I am trying to use for loop to search an exploded string, one by one from mysql server.
Till now I have no results.
I'm giving my codes,
<?php
// Example 1
$var = #$_GET['s'] ;
$limit=500;
echo " ";
echo "$var";
echo " ";
$trimmed_array = explode(" ", $var);
echo "$trimmed_array[0]"; // piece1
echo " ";
$count= count($trimmed_array);
echo $count;
for($j=0;$j<$count;$j++)
{
e cho "$trimmed_array[$j]";;
echo " ";
}
echo " ";
for($i=0; $i<$count ; $i++){
$query = "select * from book where name like \"%$trimmed_array[$i]%\" order by name";
$numresults=mysql_query($query);
$numrows =mysql_num_rows($numresults);
if ($numrows == 0)
{
echo "<h4>Results</h4>";
echo "<p>Sorry, your search: "" . $trimmed_array[i] . "" returned zero results</p>";
}
if (empty($s)) {
$s=0;
}
$query .= " limit $s,$limit";
$result = mysql_query($query) or die("Couldn't execute query");
echo "<p>You searched for: "" . $var . ""</p>";
echo "Results<br /><br />";
$count=1;
while ($row= mysql_fetch_array($result)) {
$name = $row["name"];
$publisher=$row["publisher"];
$total=$row["total"];
$issued=$row["issued"];
$available=$row["available"];
$category=$row["category"];
echo "<table border='1'><tr><td>$count)</td><td>$name </td><td>$publisher </td><td>$total </td><td>$issued </td><td>$available </td><td>$category </td></tr></table>" ;
$count++ ;
}
}
?>
In your case, you do for every record in your array ($trimmed_array) a new select. Thats not really good.
It would be better when you create just one select...
For example this:
// you need 1=1 for example when $i<count is false...
$baseQuery = "select * from book where 1=1";
$query = $baseQuery;
for($i=0; $i<$count ; $i++){
$query .= " OR name like ?";
}
// do your ordering:
$query.= " order by name";
But what does this "?" mean?
--> Do you know what sql-injection means? somebody could really easy put some information in this array wich could give any information about your database.. therefore you have to escape every userinput...
i like the mysqli package in php5. watch this example:
$query = "SELECT `id` FROM employees WHERE `name`=?";
// Setup parameter to be bound into query
$name = "Joey";
// Get instance of statement
$stmt = $mysqli->stmt_init();
// Prepare Query
if($stmt->prepare($query)){
// Bind Parameters [s for string]
$stmt->bind_param("s",$name);
// Execute statement
$stmt->execute();
// Bind result variables
$stmt->bind_result($employee_id);
// Fetch Value
$stmt->fetch();
// Echo results
echo "$name has an ID of $employee_id";
// Close Statement
$stmt->close();
}
Damn, your code really extremely crazy. Here you example about how to work with this:
<?php
$var = $_GET['s'];
$exp = explode(" ",$var);
$total = count($exp) - 1;
for($i = 0; $i <= $total; $i++) {
echo "Search for: " . $exp[$i] ."\n";
$sql = mysql_query("SELECT * FROM `book` WHERE `name` LIKE '%" . mysql_real_escape_string($exp[$i]) ."%'") or die(mysql_error());
if (mysql_fetch_num($sql) != 0) {
// Somthing found
}
}
?>
You have an error on line 25,
e cho "$trimmed_array[$j]";;
should be
echo "$trimmed_array[$j]";
Also, it seems that you are using $GET_[] variables, which are passed via the url string, which does not allow spaces. On line 15, you are splitting the array with explode(" ", $var);
I would also urge you, if you have not, look into sanitizing your database queries.

Categories