Check if word is already in DB (PHP) - php

I'm trying to create a function which checks if word in a string is in the DB.
So, for example, I have a list with basic words in my DB. I type a sentence and would like to get all the words from that sentence which are not yet in the DB.
Any tips on how to work this out?

First convert search string to an array using this function
$str = "Hello user how are you.";
$find_it = explode(" ",$str);
Now use mysql query to find if this exist in DB or NOT...
$filterExisting = "'" . implode("', '", $find_it ) . "'";
$sql = "SELECT * FROM table WHERE field NOT IN (". $filterExisting .")";
$result = $db->query($sql);

Related

How do I properly handle a string with an apostrophe when using it within a like clause with PDO?

I am attempting to do a string search with a like clause using PDO. The name has an apostrophe. All my attempts thus far have resulted in no results found even though the names exist.
This code works, where I have hardcoded the array values:
// looking for last names that start with A' and any first name
like_string = array("A'%", "B%");
$sql = "SELECT p.last_name, p.first_name
FROM person p
WHERE p.last_name LIKE ? AND p.first_name LIKE ? ";
$fields = array($like_string[0], $like_string[1]);
$stmt = $this->pdb->prepare($sql);
$stmt->execute($fields);
$result = $stmt->fetchALL(PDO::FETCH_ASSOC);
However this code, where the string array is built within the php code, does not, and I do not understand why.
// e.g $search val = "A', B";
$search_array = explode(',',$search_val);
$like_string[0] = trim($search_array[0]) . "%";
$like_string[1] = trim($search_array[1]) . "%";
The results from the code above produces array values of:
$like_string[0] = "A'%"
$like_string[1] = "B%"
yet no rows are returned. I have even tried adding addslashes as seen below - still no rows fetched:
// e.g $search val = "A', B";
$search_array = explode(',',$search_val);
$like_string[0] = addslashes(trim($search_array[0]) . "%");
$like_string[1] = addslashes(trim($search_array[1]) . "%");
Any help would be greatly appreciated.
As an update to a previous comment, the code below produces
$search_val = "A', B";
$search_array = explode(',',$search_val);
$like_string[0] = trim($search_array[0]) . "%";
$like_string[1] = trim($search_array[1]) . "%";
var_dump($like_string);
the following output from var_dump
array (size=2)
0 => string 'A'%' (length=3)
1 => string 'B%' (length=2)
And I believe the issue is that the resultant strings above are not surrounded in double quotes. So how do I force that to occur?
I discovered the issue. The search string entered by the user was being sanitized by calling
escape_string(filter_var($item_to_prep, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_HIGH));
This caused a conflict with the PDO functions.

Database search like google [duplicate]

This question already has answers here:
Google-like Search Engine in PHP/mySQL [closed]
(9 answers)
Closed 1 year ago.
I currently have a search option on my PHP+MYSQL website.
The MYSQL query is currently something like "SELECT pageurl WHERE name LIKE '%$query%'.
The reason I posted here is because I noticed that if the name of one of my products is "Blue Bike" and someone looks for "Bike Blue", no results are returned.
I am looking for a solution to this because I know that if I type on google same word, something appears.
I was thinking to create a PHP function to mix up all the words from the query if the query is having 4 or fewer words, generating around 24 queries.
Is there an easier solution to this?
Thanks for your time
As to not let this go without a working answer:
<?php
$search = 'this is my search';
$searchSplit = explode(' ', $search);
$searchQueryItems = array();
foreach ($searchSplit as $searchTerm) {
/*
* NOTE: Check out the DB connections escaping part
* below for the one you should use.
*/
$searchQueryItems[] = "name LIKE '%" . mysqli_real_escape_string($searchTerm) . "%'";
}
$query = 'SELECT pageurl FROM names' . (!empty($searchQueryItems) ? ' WHERE ' . implode(' AND ', $searchQueryItems) : '');
?>
DB connections escaping
mysqli_:
Keep using mysqli_real_escape_string or use $mysqli->real_escape_string($searchTerm).
mysql_:
if you use mysql_ you should use mysql_real_escape_string($searchTerm) (and think about changing as it's deprecated).
PDO:
If you use PDO, you should use trim($pdo->quote($searchTerm), "'").
use full text search instead of like
full text search based on indexed text and is very faster and beter than using like.
see this article for more information about full text search
What you are looking for is fulltext search.
Try Sphinx, it is very fast and integrates well with MySQL.
Sphinx website
I wrote a function that approaches Google's operation taking into account the double quotes for the elements to search as a whole block. It does NOT take into account the - or * instructions.
table: MySQL table to consider
cols: array of column to parse
searchParams: search to process. For example: red mustang "Florida 90210"
function naturalQueryConstructor($table, $cols, $searchParams) {
// Basic processing and controls
$searchParams = strip_tags($searchParams);
if( (!$table) or (!is_array($cols)) or (!$searchParams) ) {
return NULL;
}
// Start query
$query = "SELECT * FROM $table WHERE ";
// Explode search criteria taking into account the double quotes
$searchParams = str_getcsv($searchParams, ' ');
// Query writing
foreach($searchParams as $param) {
if(strpos($param, ' ') or (strlen($param)<4)) {
// Elements with space were between double quotes and must be processed with LIKE.
// Also for the elements with less than 4 characters. (red and "Florida 90210")
$query .= "(";
// Add each column
foreach($cols as $col) {
if($col) {
$query .= $col." LIKE '%".$param."%' OR ";
}
}
// Remove last ' OR ' sequence
$query = substr($query, 0, strlen($query)-4);
// Following criteria will added with an AND
$query .= ") AND ";
} else {
// Other criteria processed with MATCH AGAINST (mustang)
$query .= "(MATCH (";
foreach($cols as $col) {
if($col) {
$query .= $col.",";
}
}
// Remove the last ,
$query = substr($query, 0, strlen($query)-1);
// Following criteria will added with an AND
$query .= ") AGAINST ('".$param."' IN NATURAL LANGUAGE MODE)) AND ";
}
}
// Remove last ' AND ' sequence
$query = substr($query, 0, strlen($query)-5);
return $query;
}
Thanks to the stackoverflow community where I found parts of this function!
To have a google like search you'd need many database and index nodes, crazy algorithms.. now you come up with a SELECT LIKE ... lol :D
MySQL is slow in searching, you'd need fulltext and index set properly (MyISAM or Aria Engine). Combinations or different entities to search for are almost not implementable properly AND fast.
I'd suggest to setup an Elasticsearch server which is based on Apache's Lucene.
This searchs very fast and is easy to maintain. And you would not have to care about SQL injection and can still use the mysql server fast.
Elasticsearch (or other Lucene based search engines like SolR) can easily be installed on any server because they are written in Java.
Good documentation:
http://www.elasticsearch.org/guide/en/elasticsearch/client/php-api/current/
I would do an explode first:
$queryArray = explode(" ", $query);
and then generate the SQL query something like:
for ($i=0; $i< count($queryArray); $i++) {
$filter += " LIKE '%" + $queryArray[$i] + "%' AND" ;
}
$filter = rtrim ($filter, " AND");
$sql = "SELECT pageurl FROM ... WHERE name " + $filter
(note: haven't tested/run this code)

concatenate string in php foreach

I should be able to figure this out, but I keep going in circles. I have a form with checkboxes. When the checkboxes are selected they tagged to be deleted.
I process those selected checkboxes with a foreach:
foreach (array_keys($_POST['checkboxselect']) as $k) {
$str .= $k.',';
}
This is my lame attempt to put the list of videos together. The sql delete I'm using is:
DELETE FROM `videos` WHERE `video_name` IN ($str)
So I'm missing lots of things here. The $str needs to have:
Only one checkbox is returned so return string with quotes (i.e. "myvideo.mp4")
Multiple checkboxes are selected so build a string with quotes and commas (i.e. "myvideo.mp4","myvideo2.mp4","myvideo3.mp4")
Thanks for the help.
Try using PHP's implode:
// Init links
$mysqliLink = mysqli_connect('host', 'user', 'password') or die('Could not connect: ' . mysqli_error());
$mysqlLink = mysql_connect('host', 'user', 'password') or die('Could not connect: ' . mysql_error());
//-----
// Prep values for query
//-----
// Only pick one of the following depending upon the mysql library you are using
// If using mysql, passing the 2nd argument is not necessary, but for
// clarity, adding it
$deleteNames = array_map('mysql_real_escape_string', array_keys($_POST['checkboxselect']), array_fill(0, count($_POST['checkboxselect']), $mysqlLink));
// If using mysqli
// This will ensure that $mysqliLink will be passed in as first arg for
// every iteration satisfying the function signature
$deleteNames = array_map('mysqli_real_escape_string', array_fill(0, count($_POST['checkboxselect']), $mysqliLink), array_keys($_POST['checkboxselect']));
//-----
// Because you are passing strings, we need to ensure each is wrapped in quotes
$deleteNames = "'" . implode("','", $deleteNames) . "'";
// Construct query using implode
$sql = sprintf('DELETE FROM `videos` WHERE `video_name` IN (%s)', $deleteNames);
-- Update --
Using Joomla APIs:
$db = &JFactory::getDBO();
// Localize and sanitize each individual value
foreach (array_keys($_POST['checkboxselect']) as $element) {
$deleteNames[] = $db->quote($element);
}
// Because you are passing strings, we need to ensure each is wrapped in quotes
// No longer true because $db->quote taking care of quoting out each name for us
$deleteNames = implode(',', $deleteNames);
// Construct query using implode
$sql = sprintf('DELETE FROM `videos` WHERE `video_name` IN (%s)', $deleteNames);
Use implode() like this:
$str = '"' . implode('","', array_keys($_POST['checkboxselect'])) . '"';
implode() will take an array and join each value in the array with the "glue" string. In this case the "glue" is "," and the array is composed of the keys in $_POST['checkboxselect']. Finally, the resulting string is wrapped in ".
This will result in your desired example string "myvideo.mp4","myvideo2.mp4","myvideo3.mp4".

how to delete all rows using IN OPERATOR in mysql php

i am having problem in understanding the behaviour of this programme below is simple code to delete the email address using IN operator
$emails = $_POST['ids'];
$sql = "DELETE FROM newsletter where email ";
$condition = sprintf('IN ("%s")',implode(' "," ',$_POST['ids']));
$sql = $sql.$condition;
include '../includes/db.php';
$r = mysql_query($sql);
echo $sql;
it only deletes one email id and returns true . how can i make it run in a way it deletes all the emails .
below is the query constructed using the above code.
DELETE FROM newsletter where email IN ("adfadsf#gmail.com ","
asdfasfasf#gmail.com "," kjhkhsd#assdfsdf.sdfsf "," shit#gshit.com ","
someother#gmail.com")
is it wrong way of deleteing ?
Instead of:
$condition = sprintf('IN ("%s")',implode(' "," ',$_POST['ids']));
do:
$condition = sprintf('IN ("%s")',implode('", "',$_POST['ids']));
IN operator matches contents of the field with the values exactly. Spaces at the beginnings and ends of values might have cause your problems.
The query is valid however you are adding spaces before/after the email.
" asdfasfasf#gmail.com " does not match "asdfasfasf#gmail.com"
This code would be vulnerable to SQL injection attacks, i could make post something like
"); delete from newsletter; delete from newsletter where email in ("
the " are part of my post string, this would wipe your newsletter table.
However that aside the key issue with your code is potentially the spaces (do your strings include spaces in the database?) and the use of double quotes. I'm not 100% certain but I'm sure " can be used as a field indicator rather than a string so you probably want single quotes.
$emails = $_POST['ids'];
$sql = "DELETE FROM newsletter where email ";
$condition = sprintf("IN ('%s')",implode("','",$_POST['ids']));
$sql = $sql.$condition;
include '../includes/db.php';
$r = mysql_query($sql);
echo $sql;
Output then should be
DELETE FROM newsletter where email IN ('adfadsf#gmail.com','asdfasfasf#gmail.com','kjhkhsd#assdfsdf.sdfsf','shit#gshit.com','someother#gmail.com')
If you need to insert strings in a SQL query you have to single-quote them and protect against SQL injection. Also, the comma separator in the IN clause should not be quoted.
$safe_emails = array();
foreach($_POST['ids'] as $i){
$safe_emails[] = "'" . mysql_real_escape_string($i) . "'";
}
$sql = 'DELETE FROM newsletter WHERE email IN (' . implode(', ', $safe_emails) . ')';

Php Multi-Dimensional Array / MySql problem

I am trying to write a php script that take a text file break down its contents and and insert it into a MySql database, the code is as follows:
$file = "my_file.txt";
$db = "db_name";
$link = mysql_connect("localhost","root");
if(!$link) die("Connection Failed");
mysql_select_db($db) or die("Could not open $db: ".mysql_error()."<br />");
$fp = fopen($file, 'r') or die("Could not open file");
$my_filesize = filesize($file);
while(!feof($fp)) {
$prod_doc.=fread($fp, $my_filesize); // store the file in a variable
}
$prod_array = explode("~",$prod_doc); // create a array with the explode function
for($i=0; $i<count($prod_array); $i++){
$prod_items[$i] = explode(',', $prod_array[$i]); // create a malti-dimensional array
}
$query = "INSERT INTO my_table(feild1, feild two, feild three)
VALUES ('$prod_items[$i][0]','$prod_items[$i][1]','$prod_items[$i][2]')
";
$result = mysql_query($query);
if(!$result) die(mysql_error());
$result = mysql_affected_rows($result);
echo $result;
mysql_close($link); `
My problem is this: Array[0], Array[1], Array[3] is what is entered into the database instead of my data. Thanks in advance, cheers.
To access array variable element values used inside a double-quote string need braces delimiters:
"'{$prod_items[$i][0]}','{$prod_items[$i][1]}','{$prod_items[$i][2]}') ";
Another way to code this is by concatenation (in which case you don't need the extra delimiters):
"'" . $prod_items[$i][0] . "','" . $prod_items[$i][1] . "','" . $prod_items[$i][2] . "') ";
Don't forget, if the input data is unpredictable, you need to filter out characters that can break your sequel or compromise security principles. SEE How can I prevent SQL injection in PHP?
Also, junmats's comment is correct, you are only running the query outside the for loop which doesn't make sense.
You have to iterate over your $prod_items array as well, then concate the values
$insert = array();
for($i=0; $i<count($prod_array); $i++){
$prod_items[$i] = explode(',', $prod_array[$i]); // create a malti-dimensional array
$insert[] = '( ' .$prod_items[$i][0]. ', '.$prod_items[$i][1]. ', '. $prod_items[$i][3] .')';
}
$insert_string = implode(', ', $insert);
$query = "INSERT INTO my_table(feild1, feild two, feild three)
VALUES" . $insert_string;
And you should use foreach insted of for.
Seems like you've skipped some code.
After explode you'll have array of strings, not 2d array.
Also it's better to update the code a bit.
$query = "INSERT INTO my_table(feild1, feild_two, feild_three) VALUES ('".$prod_items[$i][0]."','".$prod_items[$i][1]."','".$prod_items[$i][2]."') ";
You should use the standard concatenation(.) technique for this.
PHP can only evaluate simple variables inside a string:
"$var" --> var is evaluated
"$var->var" --> is not evaluated
"$var[0]" --> is not evaluated
$query = "INSERT INTO my_table(feild1, feild two, feild three)
VALUES ('".$prod_items[$i][0]."','".$prod_items[$i][1]."','".$prod_items[$i][2]".')
";

Categories