Hackosis is an Open Blog. You Can Participate.

  • 06
  • Nov

 
 
PHP-MySQL Logo

There might be many reasons why you may be storing data in a database. As Google has showed us, searching data is an invaluable tool that can help minimize the time that it takes to find the information you need.

I would like to show you how you can build your own PHP search engine to find the information you seek in a MySQL database.

First you will need a LAMP to work from. For Windows users a quick and dirty way is to download and install XAMPP. For Linux users try searching Google for a tutorial.

OK, now we will skip to the part where you have a working LAMP install and a database that needs searching from a web interface. I will assume that you have basic knowledge of and where to put your PHP files and also some basic SQL query syntax.

NOTE: I am not including “<?php” at the beginning of documents, nor “?>” at the end I will assume that you will know that these are the operators to signify php code within a file. You may also download the zip file that contains all of the code examples listed below at the end of this document.

Step 1: We are going to create a config.php file with our database information. Please fill in the correct information for your MySQL database and save the file:

  1. $dbhost=‘127.0.0.1′;
  2. $dbusername=‘db_username’;
  3. $dbuserpass=‘db_password’;
  4. $dbname = ‘db_name’;


Step 2: Construct the search.php file.

It is always a good practice to make verbose comments in your code. If someone else comes along they might have some questions and may need to contact you.

  1. /**************************************************************************************
  2. * Main Search Page – search.php
  3. * Author: Your Name <email@something.com>
  4. * This file searches the database
  5. **************************************************************************************/

Next, we are going to call the config.php file that we created in Step 1. We could just use ‘include’ instead of ‘require’, but this file is critical to our application, so we want the script to fail if it cannot find the ‘config.php’ file. You would also want to store this in a different directory if our PHP application had many files, but since there are only two, we will put it in the same place as search.php.

  1. //Get variables from config.php to connect to mysql server
  2. require ‘config.php’;

After that, we are going to initiate a connection to our database. This pulls the variables from the config.php that we specified. If it cannot connect, it will print ‘Cannot select database’.

  1. // connect to the mysql database server.
  2. mysql_connect ($dbhost, $dbusername, $dbuserpass);
  3. //select the database
  4. mysql_select_db($dbname) or die(‘Cannot select database’);

Now lets insert some code to pull a variable from the search form that we will create later in the file. This basically says, if the search variable is set through the form, retrieve it and store it. There is no sense in storing it if it is not set. Also, the curly brackets are the enclosure for the if statement.

  1. //search variable = data in search box or url
  2. if(isset($_GET[’search’]))
  3. {
  4. $search = $_GET[’search’];
  5. }

We don’t want extra whitespace in the search variable as it will make a pure wild card and return all results; so we trim it like this:

  1. //trim whitespace from variable
  2. $search = trim($search);
  3. $search = preg_replace(‘/\s+/’, ‘ ‘, $search);

Here comes the fun part. What we are doing here is seperating the words of the search variable, delimited by spaces and storing them in an array inside the keywords variable. I told you it was fun.

  1. //seperate multiple keywords into array space delimited
  2. $keywords = explode(" ", $search);

Now, just to double check ourselves we are going to make sure that no arrays are empty, as said before, if this is the case, it will return every row because of the syntax of our SQL query. If there is any empty arrays, we are ridding of them.

  1. //Clean empty arrays so they don’t get every row as result
  2. $keywords = array_diff($keywords, array(""));

OK, we are ready to set the MySQL query. This is saying if the search variable is ‘null’ or is ‘%’ (MySQL wildcard) do nothing, else the MySQL query is whatever we set it to. Depending on the number of keywords, it will loop until it has competed the query for all words entered. You might have a preference for how your query is ordered, so replace the “ORDER BY column1″ with the column that you would like to sort by. You will have to replace table_name and column[1-4] with the table that you are searching in your database. If you have more columns that you are searching you will have to enter more OR statements. Some tweaking may be required here.

  1. //Set the MySQL query
  2. if ($search == NULL or $search == '%'){
  3. } else {
  4. for ($i=0; $i<count($keywords); $i++) {
  5. $query = "SELECT * FROM table_name " .
  6. "WHERE column1 LIKE '%".$keywords[$i]."%'".
  7. " OR column2 LIKE '%".$keywords[$i]."%'" .
  8. " OR column3 LIKE '%".$keywords[$i]."%'" .
  9. " OR column4 LIKE '%".$keywords[$i]."%'" .
  10. " ORDER BY column1";
  11. }

Now we will run the query and store it in a variable named result. If the query fails it will print the MySQL error message. The curly bracket at the end will close our if statement from the previous code snippet.

  1. //Store the results in a variable or die if query fails
  2. $result = mysql_query($query) or die(mysql_error());
  3. }

In the following code we are going to count the number of rows retrieved from the MySQL query.

  1. if ($search == NULL or $search == '%'){
  2. } else {
  3. //Count the rows retrived
  4. $count = mysql_num_rows($result);
  5. }

Now is when we start printing the HTML code. I have included the HTML inside of echo statements to show you how it works. Notice how you MUST provide "\" before any double quotes. Notice how the method of our form is "GET"? That must match how we retrieved the variable earlier. The body onload statement is a little javascript that will automatically place the cursor in the search box to avoid repetitive mouse gestures. Also, we will print the keywords that the user searched for below the search box. Customize the form to your liking.

  1. echo "<html>";
  2. echo "<head>";
  3. echo "<title>Your Title Here</title>";
  4. echo "<link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\" />";
  5. echo "</head>";
  6. echo "<body onLoad=\"self.focus();document.searchform.search.focus()\">";
  7. echo "<center>";
  8. echo "<br /><form name=\"searchform\" method=\"GET\" action=\"search.php\">";
  9. echo "<input type=\"text\" name=\"search\" size=\"20\" TABINDEX=\"1\" />";
  10. echo " <input type=\"submit\" value=\"Search\" />";
  11. echo "</form>";
  12. //If search variable is null do nothing, else print it.
  13. if ($search == NULL) {
  14. } else {
  15. echo "You searched for <b><FONT COLOR=\"blue\">";
  16. foreach($keywords as $value) {
  17.    print "$value ";
  18. }
  19. echo "</font></b>";
  20. }
  21. echo "<p> </p><br />";
  22. echo "</center>";

Next, we can print some error messages if need be telling the user if there is nothing in the search box or a wildcard, and if the search returned no rows from the database.

  1. //If users doesn't enter anything into search box tell them to.
  2. if ($search == NULL){
  3. echo "<center><b><FONT COLOR=\"red\">Please enter a search parameter to continue.</font></b><br /></center>";
  4. } elseif ($search == '%'){
  5. echo "<center><b><FONT COLOR=\"red\">Please enter a search parameter to continue.</font></b><br /></center>";
  6. //If no results are returned print it
  7. } elseif ($count <= 0){
  8. echo "<center><b><FONT COLOR=\"red\">Your query returned no results from the database.</font></b><br /></center>";
  9. //ELSE print the data in a table
  10. } else {

What we are going to print next, after the else above, is a table header. This is optional, especially if you choose not to display the results in a table.

  1. //Table header
  2. echo "<center><table id=\"search\" bgcolor=\"#AAAAAA\">";
  3. echo "<tr>";
  4. echo "<td><b>COLUMN 1:</b></td>";
  5. echo "<td><b>COLUMN 2:</b></td>";
  6. echo "<td><b>COLUMN 3:</b></td>";
  7. echo "<td><b>COLUMN 4:</b></td>";
  8. echo "<td><b>COLUMN 5:</b></td>";
  9. echo "<td><b>COLUMN 6:</b></td>";
  10. echo "<tr>";
  11. echo "</table></center>";

Now we can start printing the data that was returned by the SQL query in a table. We are including some code to alternate colors in the table for readability. The code following is saying while there are rows in the result, store them in a variable named row and print the data. Also, the end if is from the error messages two code snippets above. The names column[1-6] should match the names of the columns in your MySQL database that you are wishing to display in the HTML table. If you are wishing to not display your results in a HTML table, feel free to change the HTML to something more fitting.

  1. //Colors for alternation of row color on results table
  2. $color1 = "#d5d5d5";
  3. $color2 = "#e5e5e5";
  4. //While there are rows, print it.
  5. while($row = mysql_fetch_array($result))
  6. {
  7. //Row color alternates for each row
  8. $row_color = ($row_count % 2) ? $color1 : $color2;
  9. //table background color = row_color variable
  10. echo "<center><table bgcolor=".$row_color.">";
  11. echo "<tr>";
  12. echo "<td>".$row['column1']."</td>";
  13. echo "<td>".$row['column2']."</td>";
  14. echo "<td>".$row['column3']."</td>";
  15. echo "<td>".$row['colomn4']."</td>";
  16. echo "<td>".$row['column5']."</td>";
  17. echo "<td >".$row['column6']."</td>";
  18. echo "</tr>";
  19. echo "</table></center>";
  20. $row_count++;
  21. //end while
  22. }
  23. //end if
  24. }

The last thing we are going to do is clear the memory of the result and close the body and html tags.

  1. echo "</body>";
  2. echo "</html>";
  3. if ($search == NULL or $search == '%') {
  4. } else {
  5. //clear memory
  6. }

There are better ways to handle some of the operations in the PHP code in this example. The main point here was to split it up so it is more easily understandable. I hope this was a good exercise for you. Please be aware that the input IS NOT PROPERLY SANITIZED, so if you set the user in your config.php file as a user that can write to the database, there is a probability that SQL injection could occur.

Download the config.php and search.php files here.

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Related Posts


Tags: , , , ,

Like this post? Subscibe to the RSS feed.


93 Comments

  1. hadi Says:

    How would you put the search engine in a template for the search results so it won’t go into a blank page but your own template

  2. Shane Says:

    I would recommend looking up on some CSS coding.

    http://www.w3.org/MarkUp/Guide/Style

  3. Paul Filmer Says:

    nice code – been looking for something that can use – and . in the search.

    I’m having real difficulty in setting a result as a link….

    I have a field called [url] and I’m trying to code the result as a direct link – I’ve tried all combinations of and can’t get the code to work – any suggestions?

    echo “”.$row['url'].”";

  4. Shane Says:

    Give this a whirl. I am assuming that your field actually contains a URL:

    echo “<a href=”.$row['url'].”>Link</a>”;

  5. Shawn Says:

    Greetings. Thank you so much for putting together this tutorial. I used it on my website and it’s flawless! (:

    Question: I want to add a drop-down menu next to the search box to add the functionality of limiting results to specific database columns. In other words, my database table has 3 columns (or “fields”), and so my drop-down menu would also have 3 options, each corresponding with a unique column/field name.

    Any help would be most appreciated.

  6. Shane Says:

    You would have to query the database for the column names, store it in an array, then pass the drop down menu value back into your main query for the search terms entered into the search box.

  7. Olie Says:

    Nice Code! Just what I was looking for.

    Do you know how I can spread the columns further apart?

    here is what mine looks like.

    just type in a name like mike

    http://www.nutritiondirect.org/point_system/search.php

  8. Shane Says:

    You should look into some CSS classes:

    http://www.tizag.com/cssT/class.php

    You can set the width easily this way.

  9. Frank Says:

    great tutorial,

    but i have a question:

    it is possible to get two results that are the same with this script. Do you know how to “compare” the results and delete one of the two result that are the same?

    thanks for your time,
    Frank

  10. Paul Filmer Says:

    thanks Shane – the link code works good!

  11. Dan Says:

    Excellent script! For unique results try this:

    $searchResult = array();
    $result = mysql_query($query);
    while($row = mysql_fetch_array($result)) {
    if(!in_array($row, $searchResult){
    array_push($searchResult, $row); }
    }

    :)

  12. Steve Says:

    This tutorial is really the best one I have encountered on the net and has furnished me with a good understanding of php – mysql search engine. I must confess that I am having a little trouble getting back the array results from the DB. The search I am submitting is returning results in the form of column headers with a very small centered coloured band where the results should be??… I am not entirly sure why this is… maybe it is my table? although a regular select pulls results… Please can you help ;-)

  13. Shane Says:

    Thanks Steve, I am glad you got good use from it!

    What do you mean by ‘regular’ SELECT? Are you doing something obscure?

    If you are still in a bind, upload the script (without usernames and passwords of course) and email me the URL.

    Upload site:
    http://rapidshare.com/

    Contact Me

  14. Steve Says:

    Shane I must confess that I “was” doing something obscure I was running a query within a query within the search like old mainframe applies to DB2 piggybacking rex on the back of jcl against very large databases. I really had some difficulty but your “Are you doing something obscure?” reply just got me thinking and I have to say that I now have the code working in my obscure way LOL;-D I am very happy ;-D. Your tutorial code is of a very high and clearly thought out quality which I am still very grateful for. Your skill and the tutorial which again I am very happy to have come accross after looking for several days. ;-) again thank you Shane

  15. Allen Says:

    Great work Shane.

    How would I limit the number of results displayed as well as a generating “next page” until there are no more results?

  16. Shane Says:

    Hey Allen, thanks for stopping by.

    Mabye this PHP paging tutorial would be helpful.

  17. Owen Says:

    Hi, great tut however I have one small question which is puzzling me.

    To my tiny mind this is only ever going to pull the results of the last keyword in the array ($keyword[$i]) as the loop seems to be renewing the variable $query and then when finished looping runs the mysql_query…

    Surely you need to store the created queries in an array and then loop thru the array storing records that way?

    Feel free to shoot me down in flames (please!)

    Oo

  18. Shane Says:

    Owen,

    You would think this would be the case, but the script works fine with multiple keywords.

    Honestly, I don’t have the answer to why. Anyone else have some insight?

  19. Kostas Says:

    Shane
    Thanks for the excellent tutorial – brilliantly set out and easy to understand.
    I too would like to add ‘pagination’ and you pointed Alan to an excellent site too.
    I’ve just spent 3 hours trying to insert it into you search page with no luck!
    Are you planning to write a ‘part 2′ in the near future including pagination?!
    Thanks.
    Kostas

  20. Shane Says:

    Kostas,

    I will post a pagination tutorial as soon as I get a chance. It is kind of tricky.

  21. Lucian Says:

    After I have read your script I have 2 questions in mind:
    1. what about chars like “%”,”/” or “‘” in search text
    2. if column1 matches 4 of my $keywords, it will show 4 times

  22. Lucian Says:

    Sorry about the second question, I’d read the code again :)

  23. Shane Says:

    Lucian,

    @ Question 1:

    You need to be more specific. Are you trying to filter characters like that? If so, you might look into a sanitizing tutorial.

  24. aaron cicali Says:

    I’m confused. Looking at the first section of code where the query is constructed, it appears that the for loop would result in the query only containing the last of an array of keywords (multiple columns only searched by the last keyword). Am I missing something?

    I have a search script I’m cleaning up, and I’m trying to find out if there’s a more efficient way to query besides:

    SELECT * FROM table WHERE
    column1 LIKE keyword1 OR column2 LIKE keyword1 AND
    column1 LIKE keyword2 OR column2 LIKE keyword2
    AND
    column1 LIKE keyword3 OR column2 LIKE keyword3

    The query requires all keywords to match for a positive result to be returned.

    Great tutorial. Thanks for sharing.

  25. Steve Says:

    Hi Shane – I was wondering if there was a way in PHP of restricting the number of times a user could pull from the DB i.e. 3 searches and then get a message sort of idea. The java onclick idea.. I have been playing with sessions but as of yet no joy. Any help would be great… thanks in advance, Steve

  26. Shane Says:

    I would think it would entail a session where a variable gets incremented each time the script is run under that session ID. If the variable is less than three, do nothing, else print message.

    To be honest, I have not played with session a whole lot, so I am in a similar boat with you Steve.

  27. Allen Says:

    Also, this maybe a dumb question, but I can’t figure out how to display results without a keyword search. For example, I simply want to list all the entries in a table where a field RESTAURANT matches keyword CHINESE FOOD.

    I think there is a simple solution to this. Any help?

  28. Allen Says:

    Here is the pagination scrip that is working for me. I used the link Shane gave us and adapted it to Shanes code:

    It doesnt seem to want to post the links. Here’s the code:

    http://precisionautosport.com/code.txt

  29. Shane Says:

    Allen,

    Thanks for enlightening us with your pagination code. Mind if I include it in the post?

    As far as your query question, I am a bit unclear at what you are trying to accomplish..

  30. Mikko Says:

    Hi!

    I made a little tweak to the code:

    $query = “SELECT * FROM table_name WHERE “;

    for ($i=1; $i<=count($keywords); $i++)
    {

    $query = $query .”column1 LIKE ‘%”. $keywords[$i-1]. “%’ “;

    if ($i<count($keywords))
    { $query = $query .”OR “;}
    }

    $query = $query .”ORDER BY column1″;

    Now you don’t have to worry about how many words user enters into the search field.

    The changes I made:

    1)
    I cut the $query down into smaller pieces.

    2)
    i=1; $i<=count($keywords);

    i now starts from one instead of zero but as I added the ‘=’ to the condition the loop keeps on iterating until it reaches the count($keywords)but the number of iterations stays still the same as in the original version.

    3)
    $query = $query .”column1 LIKE ‘%” .$keywords[$i-1].”%’ “;

    To get the correct entry from the key I deducted 1 from $keywords[$i]

    4)
    if ($i<count($keywords))
    { $query = $query .”OR “;}

    This will prevent extra “OR ” from appearing into the end of the query (like: …column1 LIKE word3 OR column1 LIKE word4 OR ORDER BY column1) since it is printed once less than count($keywords) is.

    Hope this explanation made some sense :)

  31. Mikko Says:

    [edit]

    Oh and add the semicollon at the end of query: $query = $query .”ORDER BY column1;″;

    If you copy and paste the text straight from the site be sure to change those “tilted” single quotes to the “straight” ones (’ instead of ´)

  32. karthi Says:

    i want a particular text serarch coding for validation in user registration page while i insert but i want tos search the particul name in my database

  33. Lucas Says:

    Hi,

    really great tutorial !! Helped me out a lot with my MYSQL DB. Well, i got 2 questions regarding your script. I have 4 columns in my DB, ..let’s call them A,B,C and D. Well and i would like to have a search form where a user can choose at the beginning in which column he will be searching. Kinda “Scroll Out Space”, where he can choose between one of the 4 columns. After he has chosen one he can enter a search word next to a free textfield and the Search script will “only” search in that particular chosen column. And my last question is…how can i manage it that my results will be shown in a table which you can see??? One of my columns has longer results in it, so the whole “results” page doesn’t look even after search was finished. Just a table so that every column will have it’s own space and the whole results page will look ok and not in chaos. Thanks in advance. Regards, Lukas.

  34. Steve Says:

    Hi Shane – I was wondering if there was a way in which multiple tables could be searched?

    Many thanks in advance ;-)

  35. Mikko Says:

    Hi Steve!

    What you’re looking after is using JOIN. More info on that can be found from http://www.informit.com/articles/article.aspx?p=30875&seqNum=5

  36. Robert Newton Says:

    Thank you for making this tutorial. Between your search code (and explanation) and the example for pagination as posted by (Allen of precisionautosport) I have a fairly professional looking (and working) search for my sister’s website. If you’d like a link back to this site (seo), I’d be more than happy to oblige. Again, Shane and Hackosis, thank you. =)

  37. Aaron Cicali Says:

    Hi Shane,

    I think there’s a bug in your example, please correct me if I’m wrong.

    When you use a FOR loop to assign the variable $query, the query would only contain what was assigned to it during the last iteration of the for loop. This renders all but the final iteration useless.

    This might work better:

    //Set the MySQL query
    if($search == NULL or $search == ‘%’)
    {
    //do nothing
    }
    else
    {
    $query = “SELECT * FROM table_name WHERE “;

    for ($i=0; $i < count($keywords); $i++)
    {
    $query .= ” column1 LIKE ‘%”.$keywords[$i].”%’”.
    ” OR column2 LIKE ‘%”.$keywords[$i].”%’”.
    ” OR column3 LIKE ‘%”.$keywords[$i].”%’”.
    ” OR column4 LIKE ‘%”.$keywords[$i].”%’”;

    if($i < (count($keywords) – 1))
    $query .= ” AND”;
    }

    $query .= ” ORDER BY column1″;
    }

  38. Shane Says:

    Thanks for the suggestion Aaron. I will test this and post back the results. I am always up for improvements!

  39. BT Says:

    Cool site search.

    One question

    how can we add options to search a specific column ei

    Keyword: europe
    choose option(dropdown): London (selected)

    and it searches only london columns and displays those results in london.

    Many Many Thanks

  40. Steve Says:

    Hi Again guys, I firstly would like to thank Shane and Mikko for the help they have given me. I have one final question. How can I pull the data from the array in the form of either formatted XML,HTML or suchlike page. The reason I ask these questions here is simple…. I have needed help with php given the time limits that I am working to and have found that there is no BS or Ego here, the content is from genuine clear thinking people. BTW,If somebody would find the php session eq to the java onclick code I created useful, please let shane know and I will be happy to provide.

  41. thanksToYou Says:

    nice code, but how can i make the column much further?
    please help me!

    thanks!

  42. Mikko Says:

    Hi guys!

    BT:

    You’ll have to first assign values to your dropdown menu :

    London
    Helsinki

    Then when processign the values from GET:
    $city =$_GET['city']

    And adjust your query:

    $query = “SELECT * FROM table_name WHERE column1 LIKE ‘%”.$city”;

    Steve:
    The results should show up as a formatted HTML-page if you followed through the whole example (or downloaded the files attached to the end of tutorial.

    thanksToYou:
    What do you mean by making columns further?

  43. Mikko Says:

    Damn. The site apparently doesn’t want to print out pure html code :p I’ll try replacing signs with { and } respectevly in BT’s example. See if this works…

    {form action=”searchform.php” method=”GET”}
    {select name=”city”}
    {option value=”london”}London{/option}
    {option value=”Helsinki”}Helsinki{/option}
    {/select}
    {/form}

  44. Alen Says:

    Great job!

    I found out that the query is key sensitive.
    What should i do for the script to get all the results regardless the KeyCase

    thanks

  45. Shane Says:

    Alen,

    By default the query should NOT be case sensitive. It may have something to do with collation.

    See here:

    MySQL Case sensitivity

  46. Alen Says:

    Thanks for your prompt reply

    i just did copy paste your script and changed the columns and db name etc.

    if i search for Hill or hill i get different results..

    the Db is utf8_unicode_ci type

    thanks

  47. Alen Says:

    [append]

    It was my fault the table city was utf8_bin
    I change it to utf8_general_ci and it works like charm

    thanks again!

  48. Alen Says:

    hi,

    I’m trying to do a select query without success.

    My problem is:
    I have a table “users” with fields: city,country
    and a table “Country” with fields: id,name

    in the table “users” the field country is the filled with “id” (1,2,3..) of the country.

    What i want to archive is to form the select statement that it would get from the table “country” the name field so i could use it in the search.

    Usually I’m doing it like the following but i don’t know how to implement it in the search form:
    SELECT country.name, users.city, FROM country, users WHERE country.id = users.country

    any help?
    thanks

  49. Allen Says:

    Hi again,

    Can we take the code one step further? Let’s say I have a database with listings. How would I be able to store pictures in the database along with its info such as address, name, etc. Would I store the actual image in mySQL? or just store the path to the image file on my server then call it using img src=”"

  50. Alen Says:

    Allen

    The best is to store the path of the image in the sql. but if you plan to have A LOT of images i guess the mysql choice will be faster than the filesystem.

  51. Alen Says:

    Reply to post: By Alen on Mar 20, 2008

    I did my homework :) Im posting the solution in case someone has the same Q

    $query = “select * FROM users LEFT JOIN country on users.country=country.id ” .

  52. Shane Says:

    Great work Alen. ;)

  53. Alen Says:

    Shane can i ask you a Q?

    now im getting two ID fields (one form users and the one from country)

    How can i escape define which fields from the joined table to be joined? :)

  54. Shane Says:

    Is something like you are looking for?

    SELECT * FROM t1 LEFT JOIN (t2, t3, t4)
    ON (t2.a=t1.a AND t3.b=t1.b AND t4.c=t1.c)

  55. Al Says:

    Hello,
    Great article! I am extremely new to the web developing community, and trying to teach myself how to do all of this =) This article has helped me quite a bit with developing a search engine for my site.

    Question though.
    When performing the search, I am able to retrieve information from my database just fine. The problem is, my echo’ed keyword is not exact to my database.

    Example
    I type in “Help” for the search word. My echo’ed result is “Help” BUT, in my database, the “Help” is actually “HELP”.

    How do I go about making the echo’ed search result exactly case sensative to the database information?

    Thanks for the help =)

  56. Albert Says:

    nice code they have done exactly what i was in need of. thanks

  57. Robert Says:

    Shane,

    How can I “AND” the keywords so that if more than one keyword is entered, all keywords are required to be in the results?

  58. Shane Says:

    //Set the MySQL query
    if ($search == NULL or $search == ‘%’){
    } else {
    for ($i=0; $i $query = “SELECT * FROM table_name ” .
    “WHERE column1 LIKE ‘%”.$keywords[$i].”%’”.
    ” AND column2 LIKE ‘%”.$keywords[$i].”%’” .
    ” AND column3 LIKE ‘%”.$keywords[$i].”%’” .
    ” AND column4 LIKE ‘%”.$keywords[$i].”%’” .
    ” ORDER BY column1″;
    }

  59. Robert Says:

    Shane,

    I meant I wanted all keywords to be matched in the results. If the keywords entered are “blue” and “rug”, I want all the results to have blue and rug in them (so blue rug, blue rugs, long blue rug(s), wide blue rug(s), etc.

    Something else I’ve noticed (now that I’m playing with this again) is the last keyword is the limiting factor in the results. If for instance you enter “blue” and “rug” again, and blue by itself has 40 results and rug 12, your results will total 12, because rug is the last keyword. If you enter “rug” and “blue,” you will get 40 results, because blue is the last keyword.

    I think someone else has alluded to this in the comments. I test some of the posted suggestions, and will get back to you if you’d like.

    Still, if you have any ideas how I can get the keyword results combined, I’d greatly appreciate it.

  60. Robert Says:

    Shane,

    Ok, modified my queries to work with the script by Aaron Cicali, and the results are more consistent. Although, reversing the order of my keywords results in a consistent 2 results difference (when 2 keywords are entered).

    Still not getting the keywords being “AND” together.

  61. Robert Says:

    Ok, Shane, got it working so it’ll AND keywords. The idea is to AND & OR in the right order.

    Ex (for 3 columns):
    SELECT * FROM search_tbl WHERE column1 LIKE ‘%blue%’ AND column2 LIKE ‘%brown%’ OR column1 LIKE ‘%blue%’ AND column3 LIKE ‘%brown%’ OR column2 LIKE ‘%blue%’ AND column1 LIKE ‘%brown%’ OR column2 LIKE ‘%blue%’ AND column3 LIKE ‘%brown%” OR column3 LIKE ‘%blue%’ AND column1 LIKE ‘%brown%’ OR column3 LIKE ‘%blue%’ AND column2 LIKE ‘%brown%’ ORDER BY id

    Here’s the loop (I’m terrible at loops) that I made to do this:

    $query = “SELECT * FROM search_tbl WHERE”;
    $counter=0;
    for ($col_inc=1; $col_inc<11; $col_inc++){
    for ($and_col=1; $and_col<11; $and_col++){
    $query .= ” column”.$col_inc.” LIKE ‘%”.$keywords[$i+0].”%’”.
    ” AND column”.$and_col.” LIKE ‘%”.$keywords[$i+1].”%’”;
    $counter++;
    //echo $counter;
    if ($counter < 100){
    $query .= ” OR”;
    }
    }
    }
    //echo $query;
    $query .= ” ORDER BY item_name”.
    ” LIMIT ” . ((($page-1)*$Limit) . “,$Limit”);

  62. Robert Says:

    I forgot to mention the numbers I picked for the loop are for my DB which contains 10 columns (hence the 1 – 11 and counter < 100).

  63. Robert Says:

    Boss looked at what I did today, and said use an array. I went with using 1 column type text, modified my loop, and search works with multiple keywords, and is not fixed in keyword size (to columns or rows of columns). Oh, I also put in an active field (to turn on and off).

    $query = “SELECT * FROM search_tbl WHERE active = 1 AND”;
    for ($i=0; $i<(count($keywords)); $i++){
    $query .= ” column1 LIKE ‘%”.$keywords[$i].”%’”;
    if ($i+1<(count($keywords))){
    $query .= ” AND”;
    }
    }
    $query .= ” ORDER BY item_name”.
    ” LIMIT ” . (($page-1)*$Limit) . “,$Limit”;
    $SearchResult = mysql_query($query) or die(mysql_error());

  64. Robert Says:

    Forgot to mention, keywords are space separated.

  65. Yaheno Says:

    Worked Great! Thx :)

  66. Kaash Says:

    Hi

    This is best search script. But getting a issue please help me in:
    http://b-2-b-life.com/ma/search.php

    This link is not working and I want to make some coumization..like
    1. Want to put two or three drop down box ( select filds for “country” and service
    2. One text box like you have given
    3. Want to show the result in horizently like
    Neme : Phone : City : Website
    Please help me in this

    thank you for your time.
    Regards

  67. Mike Says:

    Hi there,

    Great tutorial, has really helped me get a good looking search engine on my site.

    I need some help though please with introducing a dropdown box to narrow down the results displayed. It has already been mentioned in post number 6, but me being a bit of a noob cannot figure out what to do.

    I have searched around the net for help but getting more and more lost, can anyone please offer some further advise please? Thanks

  68. Shane Says:

    Example:

    http://kimbriggs.com/computers/computer-software/php-dynamic-drop-down.file

  69. steve Says:

    I am using a simple search where a name is passed from a form elsewhere on the site to this page. If the name is in the database contains the name it displays the result, however if the name isn’t in the data base then the page loads fine, but there is just white space where the output should be. I would like it state a message there to the effect – sorry that name is not in our database… blah blah. Any help would be appreciated.

    <?php
    include “conn.php”;

    $name = $_GET[name];

    $page=$_GET[page];
    $limit=1;

    if(empty($_GET[page])){
    $page = 1;
    }

    $limitvalue = $page * $limit – ($limit);

    $sql = “Select * from names where name like ‘$name’”;
    $rec = mysql_query($sql) or die(mysql_error());

    $topcontent = ”

    Name
    Gender
    Nationality”;

    $bg=”#ffffff”;

    $ctr=0;
    while($datas=mysql_fetch_array($rec)){
    if($bg==”#ffffff”){
    $bg=”#ffffff”;
    }else{
    $bg=”#ffffff”;
    }
    $means=substr($datas[meaning],0,300);
    $link = str_replace(” “,”_”,$datas[name]);{
    $topcontent .= “$datas[name]
    $datas[gender]
    $datas[origin]

    $means
    “;
    }

    }

    /*********************************************************************************/

    $topcontent .= “”;

    $heading = “”;
    $title = ” “;

    include “template.php”;

    ?>

  70. Shane Says:

    So if it is null you could do something like:

    if ($datas[name] == ”)
    {
    echo ‘Sorry, the name is not in the database’;
    } else {
    echo $datas[name];
    }

  71. Rog Says:

    Boy do I need help. This may not be the right place to get it, but maybe you can point me in the right direction. What I’m trying to accomplish is allow an EndUser/Person who is in our database to log in using their phone number and a predetermined PIN#. I then want a page to come up with the data specific to that EndUser/Person ONLY. Then allow that EndUser/Person to update that data in the MySQL.
    So far, I’ve been able to:
    1) INSERT the data.
    2) Create the LogIn page – which actually works.
    3) Have the results magically appear in fields of a form in an HTML page — RESULTS.

    Sounds right, but there are two problems. The data that appears in the fields of the RESULTS HTML page shows the data from the FIRST ROW — EVERYTIME! Regardless of who the EndUser/Person is or what ROW their data is stored in. And secondly, I have not yet been successful at UPDATING any of the MySQL data.

    Trying to figure this stuff out is a great way to keep Alzheimer’s dementia away, but it’s so frustrating. I’d appreciate any help I can get.
    Thanks
    Rog

  72. Shane Says:

    You need a where in your sql select query to show specific results. This would be based on a variable in your PHP script.

    SELECT COLUMNS,OF,DATA
    FROM TABLE
    WHERE userid = “$userid”;

  73. Derek Says:

    Hey guys.

    I’m sitting here for about not less than a week now, cracking my braings and my back, to get a script for a sprcific, SIMPLE search engine.

    What I need to accomplish is this.

    Its a intranet website, with items and or products’ data stored. So the only thing it has to do, is when I type in a partial serial number of an item, it has to show me all items with that serial number. Thas it, nothing less, nothing more.

    So, I got your script, which I believe will do. I also got something else, which is quite similar, but it has bugs.

    What I do like is that it highlights the phrase or word that one has searched for.

    So, I’m going to post is.

    My question is this.

    How can I implement the part that highlights the search word, into your script?

    Thanx, and regards!
    South Africa.

    ###############################################

    <?php
    //This is a working script
    //Make sure to go through it and edit database table filelds that you are seraching
    //This script assumes you are searching 3 fields
    $hostname_logon = “localhost” ;
    $database_logon = “databaseName” ;
    $username_logon = “databaseUser” ;
    $password_logon = “databasePass” ;
    //open database connection
    $connections = mysql_connect($hostname_logon, $username_logon, $password_logon) or die ( “Unabale to connect to the database” );
    //select database
    mysql_select_db($database_logon) or die ( “Unable to select database!” );

    //specify how many results to display per page
    $limit = 10;

    // Get the search variable from URL
    $var = @$_GET['q'] ;
    //trim whitespace from the stored variable
    $trimmed = trim($var);
    //separate key-phrases into keywords
    $trimmed_array = explode(” “,$trimmed);

    // check for an empty string and display a message.
    if ($trimmed == “”) {
    $resultmsg = “Search ErrorPlease enter a search…” ;
    }

    // check for a search parameter
    if (!isset($var)){
    $resultmsg = “Search ErrorWe don’t seem to have a search parameter! ” ;
    }
    // Build SQL Query for each keyword entered
    foreach ($trimmed_array as $trimm){

    // EDIT HERE and specify your table and field names for the SQL query
    $query = “SELECT * FROM tablename WHERE field1 LIKE \”%$trimm%\” OR field2 LIKE \”%$trimm%\” OR field3 LIKE \”%$trimm%\” ORDER BY field1 DESC” ;
    // Execute the query to get number of rows that contain search kewords
    $numresults=mysql_query ($query);
    $row_num_links_main =mysql_num_rows ($numresults);

    // next determine if ’s’ has been passed to script, if not use 0.
    // ’s’ is a variable that gets set as we navigate the search result pages.
    if (empty($s)) {
    $s=0;
    }

    // now let’s get results.
    $query .= ” LIMIT $s,$limit” ;
    $numresults = mysql_query ($query) or die ( “Couldn’t execute query” );
    $row= mysql_fetch_array ($numresults);

    //store record id of every item that contains the keyword in the array we need to do this to avoid display of duplicate search result.
    do{
    //EDIT HERE and specify your field name that is primary key
    $adid_array[] = $row[ 'fieldid' ];
    }while( $row= mysql_fetch_array($numresults));
    } //end foreach

    if($row_num_links_main == 0 && $row_set_num == 0){
    $resultmsg = “Search results for:” . $trimmed .”Sorry, your search returned zero results” ;
    }
    //delete duplicate record id’s from the array. To do this we will use array_unique function
    $tmparr = array_unique($adid_array);
    $i=0;
    foreach ($tmparr as $v) {
    $newarr[$i] = $v;
    $i++;
    }

    // now you can display the results returned. But first we will display the search form on the top of the page
    ?>

    <input name=”q” type=”text” value=” ” size=”15″>

    <?php
    // display what the person searched for.
    if( isset ($resultmsg)){
    echo $resultmsg;
    exit();
    }else{
    echo “Search results for: ” . $var;
    }

    foreach($newarr as $value){

    // EDIT HERE and specify your table and field names for the SQL query
    $query_value = “SELECT * FROM tablename WHERE fieldid = ‘$value’”;
    $num_value=mysql_query ($query_value);
    $row_linkcat= mysql_fetch_array ($num_value);
    $row_num_links= mysql_num_rows ($num_value);

    //now let’s make the keywods bold. To do that we will use preg_replace function.
    //EDIT parts of the lines below that have fields names like $row_linkcat[ 'field1' ]
    //This script assumes you are searching only 3 fields. If you are searching more fileds make sure that add appropriate line.
    $titlehigh = preg_replace ( “‘($var)’si” , “\\1” , $row_linkcat[ 'field1' ] );
    $linkhigh = preg_replace ( “‘($var)’si” , “\\1” , $row_linkcat[ 'field2' ] );
    $linkdesc = preg_replace ( “‘($var)’si” , “\\1” , $row_linkcat[ 'field3' ] );

    foreach($trimmed_array as $trimm){
    if($trimm != ‘b’ ){
    //IF you added more fields to search make sure to add them below as well.
    $titlehigh = preg_replace( “‘($trimm)’si” , “\\1” , $titlehigh);
    $linkhigh = preg_replace( “‘($trimm)’si” , “\\1” , $linkhigh);
    $linkdesc = preg_replace( “‘($trimm)’si” , “\\1” , $linkdesc);
    }
    //end highlight

    ?>

    $limit){
    // next we need to do the links to other search result pages
    if ($s>=1) { // do not display previous link if ’s’ is ‘0′
    $prevs=($s-$limit);
    echo “Previous ” .$limit. ““;
    }
    // check to see if last page
    $slimit =$s+$limit;
    if (!($slimit >= $row_num_links_main) && $row_num_links_main!=1) {
    // not last page so display next link
    $n=$s+$limit;
    echo “Next ” .$limit. ““;
    }
    }
    } //end foreach $newarr
    ?>

  74. Shane Says:

    Derek, I am glad that my script was of use to you.

    you might see this website for a quick explanation of highlighting search terms:

    http://www.alistapart.com/articles/searchhighlight/

  75. rpflo Says:

    I this provides results by relevance and is WAY easier to work with:

    First enable fulltext indexing of your table columns by running this SQL:

    ALTER TABLE news ADD FULLTEXT(headline, story);

    Then run this query like every other select query in PHP:

    SELECT headline, story FROM news
    WHERE MATCH (headline,story) AGAINST (’Hurricane’);

    That’s it.

  76. Tyson Says:

    Awesome script, worked great..
    However, i’m having issues with the table alignment. The table header is much longer than the rows below it and the data doesn’t align with the column/fields. Any ideas of how I can get this to line up?

    //Table header
    echo “”;
    echo “”;
    echo “Company:“;
    echo “Number:“;
    echo “Status:“;
    echo “Date:“;
    echo “FirstName:“;
    echo “LastName:“;
    echo “”;
    echo “”;

    //Colors for alternation of row color on results table
    $color1 = “#d5d5d5″;
    $color2 = “#e5e5e5″;
    //While there are rows, print it.
    while($row = mysql_fetch_array($result))
    {

    //Row color alternates for each row
    $row_color = ($row_count % 2) ? $color1 : $color2;

    //table background color = row_color variable
    echo “”;
    echo “”;
    echo “”.$row['company'].”";
    echo “”.$row['number'].”";
    echo “”.$row['status'].”";
    echo “”.$row['date'].”";
    echo “”.$row['FirstName'].”";
    echo “”.$row['LastName'].”";
    echo “”;
    echo “”;
    $row_count++;
    //end while
    }
    //end if
    }

  77. Shane Says:

    Tyson. Welcome to the Hackosis.com blog.

    You need to specify some styling in your code:

    http://www.w3schools.com/CSS/pr_dim_width.asp

  78. Anthony Says:

    An interesting piece of code although I can only get it to search on one keyword at the moment – the last one.

    A couple of mods I have made:
    Download and put the Port Stammer class into the same folder and you can search for convert or converts and it will return either ( this is php 5 only but there is a version for php 4 ):
    // Use the Port Stemmer algorithem to remove the s etc. from the end of the search words
    include ‘PorterStemmer.php’;

    //Set the MySQL query
    if ($search == NULL or $search == ‘%’){
    } else {
    for ($i=0; $i<count($keywords); $i++) {

    $query = “SELECT * FROM $dbtable ” .
    “WHERE Title LIKE ‘%”.PorterStemmer::Stem($keywords[$i]).”%’”.
    ” OR Notes LIKE ‘%”.PorterStemmer::Stem($keywords[$i]).”%’” .
    ” ORDER BY Title”;

    I have also put the table name into the config file and only allow upper or lower case letters and spaces in the search word.

  79. Anthony Says:

    The forum issed of my last part of the comment :

    // Remove everything except letters from search
    $search = ereg_replace(”[^A-Za-z ]“, “”, $search);

  80. Tyson Says:

    Thanks Shane, I think I got the columns lined up good now :)

    Not a big deal, but do you have any idea why the header row is just a little bit longer than data rows below it even when all the same column width settings are being used?

  81. Shane Says:

    Not right off hand, but I usually use separate CSS classes for the header and the table body.

  82. search script needed - TalkPHP Says:

    [...] :: MySQL 5.0 Reference Manual :: 11.8 Full-Text Search Functions HOWTO: Simple Search Engine with PHP and MySQL | Hackosis __________________ inquisitive 1. Eager to acquire knowledge. 2. Too curious; overly interested; [...]

  83. sdrevised Says:

    Love this script. Fantastic. I was just wondering if you had an eta on the pagination. You were mentioning that you were going to add that to this script and I think that would make it darn near perfect :-)

  84. Shane Says:

    The ETA on the pagination in ASAP. ;P

    Sorry, I have been VERY busy lately. Thanks for the feedback!

  85. This is bad Says:

    Good lord, you’re generating a lot of ‘LIKE’ clauses? Talk about slowdown.

    What you need to do is setup a FULLTEXT column type in MySQL, and then look into MATCHES AGAINST…

  86. Shane Says:

    Thanks for the tips. I am always up for some optimization. ;)

  87. Robert Says:

    Shane,

    Thanks again for this page. Everything still works great. So well in fact that I’ve added the search at my work site. I’ve continued to mod it here and there, and it grows more useful every day. My last mod was to add a separate table for saving data queries (along with time and ip of data query).

    Now, after all this time, though, someone brought up the brilliant idea of adding a NOT to the search. Keywords NOT keyword(s) or keywords – keywords. Any ideas?

  88. kh Says:

    Hello Shane,

    I am new to PHP and MySql. I am looking for paginated results for a simple get method form that includes an image map:

    <!—->

    <!—->

    <!—->

    <!—->

    Country

    Albania
    Andorra
    Austria
    Belarus
    Belgium
    Bosnia and Herzegovina

    Bulgaria
    Croatia
    Cyprus
    Czech Republic
    Denmark
    Estonia

    Faroe Islands
    Finland
    France
    Georgia
    Germany
    Gibraltar

    Greece
    Greenland
    Hungary
    Iceland
    Ireland
    Israel

    Italy
    Latvia
    Liechtenstein
    Lithuania
    Luxembourg
    Macedonia

    Malta
    Moldova
    Monaco
    Netherlands
    Norway
    Poland

    Portugal
    Romania
    Russia
    San Marino
    Serbia and Montenegro
    Slovakia

    Slovenia
    Spain
    Sweden
    Switzerland
    Turkey
    Ukraine

    United Kingdom

    Region

    equals
    contains
    begins with
    ends with

    Group name

    equals
    contains
    begins with
    ends with

    Target group

    equals

    contains
    begins with
    ends with

    Type of group

    equals
    contains

    begins with
    ends with

    Last modified

    before
    after

    month

    1
    2
    3
    4

    5
    6
    7
    8
    9
    10

    11
    12
     

    year

    2004

    2005

    2006

    2007

    2008

    Sort By

    <!– unsorted –>
    Group name
    Country
    Region
    Targetgroup

    Grouptype

    ascending
    descending

     

    Return

    5
    10
    20
    30
    50
    all

    records per page

    I am doing this for a non-profit and I am absolutely stuck.

    I have created the database and it works (MySql).

    The problem I am having is creating the “results.php” paginated page.

    If you need the website URL and I will get back to you.

    If you can please point me in the right direction, I will be most grateful.

    Kind regards,

    kenneth

  89. Shane Says:

    kh, see Allen’s example here:

    http://precisionautosport.com/code.txt

  90. kh Says:

    Hello Shane,

    Thanks for this.

  91. Shane Says:

    More on pagination:

    http://bible.ministrytalk.com/pagination/demo.php

  92. john Says:

    nice code… i am using it in a website but i have a problem with searching. I ll explain to you with an example

    well…

    i have in mysql’s table: columm1 columm2 columm3 columm4

    columm1 has—> 1.Nick Brown
    2. Nick Black
    3. George Brown
    4.John Best

    columm2 —-> we dont care…….

    when i am using this code and i am searching Nick Brown the result is…

    Nick Brown
    Nick Black
    George Brown

    this means that it searches Nick or Brown

    I want to search Nick and Brown… I want to take only the insert

    Nick Brown

    can u help me plz? It s an important for me

    tnx

  93. PHP Simple Search Engine with PHP and MySQL - Geekstep - Free Cpanel Hosting Says:

    [...] [...]

Leave a Comment