I'm new here and i started coding in PHP and using MySQL.
I want to search multiple "keywords", for example "Intel i7 7700k" in table and I have no idea how to accomplish this.
My structure of my MySQL Table looks like this:
id | brand | family | model | cores | threads etc.
1 | Intel | i7 | 7700k | 4 | 8 etc.
The following PHP search works, but only for one word.
if(isset($_GET['search'])){
$search = $conn->escape_string($_GET['search']);
$query = $conn->query("
SELECT brand, family, model
FROM cpus
WHERE brand LIKE '%{$search}%'
OR family LIKE '%{$search}%'
OR model LIKE '%{$search}%'
");
I was trying to loop the array of words, but it doesn't work.
if(isset($_GET['search'])){
$search = $conn->escape_string($_GET['search']);
$words = explode(' ',$search);
$searchout = foreach ($words as $word){
"SELECT brand, family, model FROM cpus WHERE brand LIKE '%$word%' OR family LIKE '%$word%' OR model LIKE '%$word%'"
}
$query = $conn->query($search_out);
echo "<div class='result-count'>Found " . $query->num_rows . " results.</div>";
if($query->num_rows){
while($r = $query->fetch_object()){
echo "<div class='result'><a href='#'>" . $r->brand . $r->model . "</a></div>";
}
}
}
How can i make the search working on multiple words?
Like "Intel i7 7700k" "7700k intel i7" "i7 7700k intel" etc.
Here is my another try which also failed:
if(isset($_GET['search'])){
$search = $conn->escape_string($_GET['search']);
$words = explode(' ',$search);
$words_count = count($words);
$cpus_columns = ['brand','family','model'];
print_r($cpus_columns);
$mysql_where = "SELECT brand, family, model FROM cpus WHERE ".$cpus_columns[0]." LIKE ".$words[0];
$mysql_loop = for ($i = 1; $i <= $words_count; $i++){
" OR ".$cpus_columns[$i]." LIKE ".$words[$i]
}
$mysql_query = $mysql_where . $mysql_loop;
$query = $conn->query($mysql_query);
echo "<div class='result-count'>Found " . $query->num_rows . " results.</div>";
if($query->num_rows){
while($r = $query->fetch_object()){
echo "<div class='result'><a href='#'>" . $r->brand . $r->model . "</a></div>";
}
}
}
I start slowly hating PHP and MySQL, 4 days and can't get it working this is just sad.
this is how i make a searching for somethg
in my case only for name ,but u can add more
$arry = array();
$arry = explode(" ",$POST["search"]);
$query="SELECT * FROM tblfbaccban WHERE ";
for($c=0;$c<sizeof($arry);$c++)
{
$query=$query."Name LIKE'%$arry[$c]%'";
if($c<sizeof($arry)-1)
{
$query=$query." OR ";
}
}
$sql=mysqli_query($mysqli,$query)or die(mysql_error());
while ($row = mysqli_fetch_array($sql, MYSQLI_BOTH))
{
echo $row["Name"]."<br>";
}
Related
I want to create a search field like if I search "Spinach, Watermelon", it will explode the input by ",", and run MySQL search database. That means the SQL will run as
SELECT * FROM table
WHERE vegetable LIKE '%Spinach%' OR fruits LIKE '%Spinach%'
SELECT * FROM table
WHERE vegetable LIKE '%Watermelon%' OR fruits LIKE '%Watermelon%'
My database table data looks something like this :
id Vegetable fruits
----------------------
1 Spinach Apple
2 Cucumber Orange
3 Spinach Watermelon
The result of each id only can come out once.
<php>
$keywords = trim($_REQUEST['keyword']);
$keyword = explode(",", $keywords);
foreach($keyword as $keys=>$select)
{
$sql = "SELECT * FROM table WHERE vegetable LIKE '%keyword %' OR fruits LIKE '%keyword %'";
$result = mysqli_query($conn, $sql);
while ($rs = mysqli_fetch_array($result))
{
$vege = $rs["vegetable"];
$fruits = $rs["fruits"];
}
}
<html>
<form method=post>
<input type="text" class="form-control" placeholder="SEARCH..." value="<?=$keywords?>">
</form>
</html>
If you are open to using REGEXP with an alternation instead of LIKE, then here is a straightforward approach:
$keywords = trim($_REQUEST['keyword']);
$keywords = preg_replace("/,\s*/", "|", $keywords);
$where = "[[:<:]](" . $keywords . ")[[:>:]]";
$sql = "SELECT * FROM table ";
$sql .= "WHERE vegetable REGEXP '" . $where . "' OR fruits REGEXP '" . $where . "'";
$result = mysqli_query($conn, $sql);
while ($rs = mysqli_fetch_array($result)) {
$vege = $rs["vegetable"];
$fruits = $rs["fruits"];
}
Assuming you passed in the keywords search string "Spinach, Watermelon", the above script would generate this query:
SELECT *
FROM table
WHERE
vegetable REGEXP '[[:<:]](Spinach|Watermelon)[[:>:]]' OR
fruits REGEXP '[[:<:]](Spinach|Watermelon)[[:>:]]';
Honestly the best approach here would be to use LIKE or REGEXP with a prepared statement. If you do choose to use my approach, then you absolutely should sterilize the incoming CSV string to make sure it has only alphanumeric characters, comma, and whitespace in it.
Hitting database in for loop is not a good approach, You can build you query like this:
<?php
$keywords = trim($_REQUEST['keyword']);
$keyword = explode(",", $keywords);
$sqlWhere = '';
foreach($keyword as $keys=>$select)
{
$sqlWhere .= "LIKE '%$select%' OR";
}
$sqlWhere = rtrim($sqlWhere, "OR");
$sql = "SELECT * FROM table " . $sqlWhere;
$result = mysqli_query($conn, $sql);
while ($rs = mysqli_fetch_array($result))
{
$vege = $rs["vegetable"];
$fruits = $rs["fruits"];
}
?>
Try this, It will print your records must.
<php>
$keywords = trim($_REQUEST['keyword']);
$keyword = explode(",", $keywords);
for($i=0; $i<count($keyword); $i++)
{
$sql = "SELECT * FROM table WHERE vegetable LIKE '%" . $keyword[$i] . "%' OR fruits LIKE '%" . " . $keyword[$i] . " . "%'";
$result = mysqli_query($conn, $sql);
$rs = mysqli_fetch_array($result);
echo "<pre>"; print_r($rs); exit;
}
?>
<html>
<form method=post>
<input type="text" class="form-control" placeholder="SEARCH..." value="<?=$keywords?>">
</form>
</html>
I think your probelm is "*The result of each id only can come out once.".
So better make one Query:
$keywords = trim($_REQUEST['keyword']);
$keyword = explode(",", $keywords);
$where = [];
foreach($keyword as $keys)
{
$where[] = "vegetable LIKE '%".$keys." %' OR fruits LIKE '%".$keys." %'";
}
$sql = "SELECT * FROM table ".(empty($where) ? '' : implode(' OR ', $where));
so you have one query an one result set.
Dont forgett to escape your keywords.
I have a form
<form action="buscar.php" method="GET">
<input type="text" name="q" />
</form>
And my page where they show the results
<?php
require_once 'meekrodb.php';
$q = $_GET['q'];
$results = DB::query("SELECT * FROM product_description WHERE description like '%$q%'");
foreach ($results as $row) {
echo $row['name']."<br>";
}
?>
For example I have these phrases in description:
My car is big and green
My house is small and green
When I look for green, the 2 results come out, but if I look for a green house nothing comes out.
The problem is that I have to search for continuous text to work for example... My house is small...
How can I improve this query? Thank you
Try to explode GET variable.Or you can try to play with CONCAT
Explode
$q = $_GET['q'];
$word_array = explode(" ",$q);
$sqlnames="SELECT * FROM product_description WHERE";
$count = 0;
foreach($word_array as $value){
if($count == 0){
$sqlnames .= " description LIKE '" . $value ."'";
}
else{
$sqlnames .= " OR description LIKE '" . $value ."'";
}
$count = 1;
$sqlnames .= " OR description LIKE '" . $value ."'";
}
$sqlnames .="LIMIT 20";
CONCAT
(something like that)
$results = DB::query("SELECT * FROM product_description WHERE description LIKE '%$q%' OR description LIKE '%$q%' OR CONCAT(description, ' ', description ) LIKE '%$q%' LIMIT 20");
I have not tested this, but you can try to play.
My database structure:
News:
id | title |description | slug
Tags:
id | title | slug
Tags news:
id | id tags | id news
And the code:
$sqltagi = mysql_query("SELECT id_tags FROM tags_news WHERE id_news LIKE '%$id%' ORDER BY id_tagu DESC");
if (!$sqltagi)
{
echo 'Error: ' . mysql_error();
exit;
}
$row = mysql_fetch_array($sqltagi);
$lol=$row['id_tagu'];
$sql = mysql_query("SELECT title,slug FROM tags WHERE id LIKE '%$lol%'");
//$sqlq = mysql_fetch_array($sql);
while ($rowid = mysql_fetch_array($sql))
{
$aa1=$rowid['title'];
$aa2=$rowid['slug'];
$tags=''.$aa1.' '.$aa2.'';
}
how to?
Several things! First of all, please don't use mysql functions! They are not secure, prone to sql injections
Use mysqli or pdo, and you should research joins in sql.
But if you must use mysql functions, then you can do something like this:
<?php
$sql = mysql_query("SELECT title, slug FROM tags JOIN tags_news ON tags.id = tags_news.id_tags");
while ($rowid = mysql_fetch_array($sql)) {
$aa1 = $rowid['title'];
$aa2 = $rowid['slug'];
echo $tags = '' . $aa1 . ' ' . $aa2 . '<br />';
}
?>
Please try this...
$sqltagi = mysql_query("SELECT id_tags FROM tags_news WHERE id_news LIKE '%$id%' ORDER BY id_tagu DESC");
if (!$sqltagi)
{
echo 'Error: ' . mysql_error();
exit;
}
while($row = mysql_fetch_array($sqltagi))
{
$lol=$row['id_tags'];
$sql = mysql_query("SELECT title,slug FROM tags WHERE id LIKE '%$lol%'");
//$sqlq = mysql_fetch_array($sql);
while ($rowid = mysql_fetch_array($sql))
{
$aa1=$rowid['title'];
$aa2=$rowid['slug'];
$tags=''.$aa1.' '.$aa2.'';
}
}
In my script below, the user inputs a form and rows are returned from a MYSQL table if rows are similar to inputted by the user. I am building a search engine and everything is based on rank. But I want to be able to adjust the code below to see how many times the word 'iPad' for example comes up with the row fields, which are 'title', 'description', 'keywords' and 'link'. If so, I want that row to return higher than say a row that has a higher id, but only mentions iPad once in all of the fields combined.
My code is below:
Terms together query:
$query = " SELECT * FROM scan WHERE ";
$terms = array_map('mysql_real_escape_string', $terms);
$i = 0;
foreach ($terms as $each) {
if ($i++ !== 0){
$query .= " AND ";
}
$query .= "title LIKE '%{$each}%' OR link LIKE '%{$each}%' OR keywords LIKE '%{$each}%' OR description LIKE '%{$each}%' ";
}
$query = mysql_query($query) or die('MySQL Query Error: ' . mysql_error( $connect ));
echo '<p class="time">Qlick showed your results in ' . number_format($secs,2) . ' seconds.</p>';
$numrows = mysql_num_rows($query);
if ($numrows > 0) {
while ($row = mysql_fetch_assoc($query)) {
$id = $row['id'];
$title = $row['title'];
$description = $row['description'];
$keywords = $row['keywords'];
$link = $row['link'];
$rank = $row['rank'];
Seperate Terms Query
$query = " SELECT * FROM scan WHERE ";
$terms = array_map('mysql_real_escape_string', $terms);
$i = 0;
foreach ($terms as $each) {
if ($i++ !== 0){
$query .= " OR ";
}
$query .= "title LIKE '%{$each}%' OR link LIKE '%{$each}%' OR keywords LIKE '%{$each}%' OR description LIKE '%{$each}%' ";
}
// Don't append the ORDER BY until after the loop
$query = mysql_query($query) or die('MySQL Query Error: ' . mysql_error( $connect ));
$numrows = mysql_num_rows($query);
if ($numrows > 0) {
while ($row = mysql_fetch_assoc($query)) {
$id = $row['id'];
$title = $row['title'];
$description = $row['description'];
$keywords = $row['keywords'];
$link = $row['link'];
$rank = $row['rank'];
I'd try to do this using an auxiliary field on which to run a FULLTEXT query, in which you would save all textual data:
http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html
The alternative is to run the filtering in MySQL and the ranking in PHP. You might squeeze some performance by running a single LIKE on the concatenated field.
By the way, your code above lacks parentheses in the LIKE, so that the results won't be correct: you mustn't ask WHERE field1 LIKE 'x' OR field2 LIKE 'x' AND field1 LIKE 'y' OR..., you must state WHERE (field1 LIKE 'x' OR field2 LIKE 'x') AND (field1 LIKE 'y' OR...).
// Here we search for ALL terms (all must be present at least once)
// use ' OR ' to ask that at least one term must be present once.
$where = array();
foreach($terms as $term)
$where[] = "( CONCAT(title,'|',link,'|',keywords) LIKE '%{$term}%')";
$query .= ' WHERE ' . '('.implode(' AND ', $where).')';
Now in the OR case you could do a simple ranking on the number of matched terms (with AND the number is always the total number of terms):
$select_fields[] '(' . implode ('+', $where) . ') AS ranking';
Otherwise in SQL you would need recourse to a really ugly hack:
(LENGTH(
REPLACE(CONCAT(title,'|',link,'|',keywords),'{$term}','')
) - LENGTH(CONCAT(title,'|',link,'|',keywords)))/LENGTH('{$term}');
This above calculates the difference between the total length of the text where the search is to be done and the total length of the same text, with search string removed. The difference is of course proportional to how many times the search string is there: if the string is 8 characters long, a difference of 32 would mean that it is present four times. Dividing the length difference by the length of the term, we obtain the number of hits.
The problem is that for several terms you have to complicate the query enormously, and it might be really expensive to run:
$select_fields = array('*');
$where = array();
$rank = array();
foreach($terms as $term)
{
// assume $term is NOT QUOTED
$search = mysql_real_escape_string($term);
$concat = "CONCAT(title,'|',link,'|',keywords)";
$where[] = "(${concat} LIKE '%{$search}%')";
$rank[] = "(LENGTH(REPLACE(${concat},'{$search}',''))
- LENGTH(${concat}))/LENGTH('{$search}')";
}
$select_fields[] = "(".implode(",", $rank).") AS ranking";
$query .= "SELECT " . implode(',', $select_fields)
. ' FROM scan WHERE (' . implode(' AND ', $where) . ')';
I have a MySQL database called "bookfeather" with several tables that contain list books. Under each table, each book has a given number of votes. The PHP code below allows the user to enter in a book title ($entry), and then returns the total number of votes that book has in all tables ($sum).
How could I use PHP to make a 2-column, 25-row table that lists the 25 books in the database with the highest value for $sum (in descending order)?
Thanks in advance,
John
mysql_connect("mysqlv10", "username", "password") or die(mysql_error());
mysql_select_db("bookfeather") or die(mysql_error());
// We preform a bit of filtering
$entry = strip_tags($entry);
$entry = trim ($entry);
$entry = mysql_real_escape_string($entry);
$result = mysql_query("SHOW TABLES FROM bookfeather")
or die(mysql_error());
$table_list = array();
while(list($table)= mysql_fetch_row($result))
{
$sqlA = "SELECT COUNT(*) FROM `$table` WHERE `site` LIKE '$entry'";
$resA = mysql_query($sqlA) or die("$sqlA:".mysql_error());
list($isThere) = mysql_fetch_row($resA);
$isThere = intval($isThere);
if ($isThere)
{
$table_list[] = $table;
}
}
//$r=mysql_query("SELECT * , votes_up - votes_down AS effective_vote FROM `$table[0]` ORDER BY effective_vote DESC");
if(mysql_num_rows($resA)>0){
foreach ($table_list as $table) {
$sql = "SELECT votes_up FROM `$table` WHERE `site` LIKE '$entry'";
$sql1 = mysql_query($sql) or die("$sql:".mysql_error());
while ($row = mysql_fetch_assoc($sql1)) {
$votes[$table] = $row['votes_up'];
$sum += $row['votes_up'];
//echo $table . ': "' . $row['votes_up'] . " for $entry from $table\"<br />";
}
}
}
else{
print "<p class=\"topic2\">the book \"$entry\" has not been added to any category</p>\n";
}
//within your loop over the DB rows
//$votes[$table] = $row['votes_up'];
//afterwards
if($sum>0){
print "<table class=\"navbarb\">\n";
print "<tr>";
print "<td class='sitenameb'>".'<a type="amzn" category="books" class="links2b">'.$entry.'</a>'."</td>";
print "</tr>\n";
print "</table>\n";
//echo "<p class=\"topic3\">".''.$entry.''. "</p>\n";
echo "<p class=\"topic4\">". number_format($sum) . ' votes in total.'."</p>\n";
Try something like this. All of this hasn't been tested so please add comments for changes. I'll work with you to get the code right.
// After getting your array of tables formated like
$tableArray = array("`tableA`", "`tableB`", "`tableC`");
// create a table statement
$tableStatement = implode(", ", $tableArray);
// create a join statement
$joinStatement = "";
for ($i = 1; $i < count($tableArray); $i++) {
if ($joinStatement != "")
$joinStatement .= " AND ";
$joinStatement .= $tableArray[0] . ".site = " . $tableArray[$i] . ".site"
}
$firstTable = $tableArray[0];
$sql = "SELECT SUM(votes_up) FROM " . $tableStatement . " WHERE " . $joinStatement . " AND " . $firstTable . ".site LIKE '" . $entry . "' GROUP BY " . $firstTable . ".site ORDER BY SUM(votes_up) DESC";
Edit --------
I now realize that the query above won't work perfectly because votes_up will be ambiguous. Also because you probably want to be doing joins that grab records that are only in one table. I think the concept is the right direction even though the query may not be perfect.
You can do something like
$selectStatement = "SUM(tableA.votes_up) + SUM(tableB.votes_up) as total_votes_up"
I did something like this recently. In your database, you'll have to rename each field to a corresponding book name.php like (TaleofTwoCities.php). Now on your page that will display the vote results, you'll need to include some php files that will drive the database query on each load. I called mine "engine1.php" and "engine2.php." These will do all your sorting for you.
$query1 = mysql_fetch_row(mysql_query("SELECT url FROM pages ORDER BY counter DESC
LIMIT 0,1"));
$query2 = mysql_fetch_row(mysql_query("SELECT url FROM pages ORDER BY counter DESC
LIMIT 1,1"));
$query3 = mysql_fetch_row(mysql_query("SELECT url FROM pages ORDER BY counter DESC
LIMIT 2,1"));
and so on.. then..
$num1 = "$query1[0]";
$num2 = "$query2[0]";
$num3 = "$query3[0]";
That part sorts your listings by the number of votes from highest to lowest, with url, in your case, being the name of the books(remember you want it to end in .php - you'll see why in a second), and counter being the field that logs your votes.
Make your second engine.php file and add something like this:
$vquery1 = mysql_fetch_row(mysql_query("SELECT counter FROM pages WHERE
url='book1.php'"));
$vquery2 = mysql_fetch_row(mysql_query("SELECT counter FROM pages WHERE
url='book2.php'"));
$vnum1 = "$vquery1[0]";
$vnum2 = "$vquery2[0]";
and so on... Until you get to 25 for both this and engine 1.
Now, in your results page, after you put in the require_once(engine.php) and require_once(engine2.php) at the start of your body, start an HTML table. You only want two columns, so it'll be something like..
<table border=1 cellspacing=0 cellpadding=0>
<tr>
<?php include $num1; ?>
</tr>
<tr>
<?php include $num2; ?>
</tr>
And so on... By naming your field with "book1.php" and including the engines, $num1 will change to a different .php file depending on votes from high to low. Now all you have to do is make small php files for each book like so - no headers or anything because you're inserting it into the middle of html code already:
<td style="width:650px;"><center><img src="images/book1.jpg" alt="" border="none"
/></a></center></td>
<td style="width:150px;">Votes: <?php echo $vnum1;?></td>
And there you have it. A code that will dynamically give you results from high to low depending on the number of votes each book has.