Search Script for PHP website with MySQL Database - php

I have a PHP website to display products. I need to introduce a 'Search' feature whereby a keyword or phrase can be found among number of products.
I went through number of existing scripts and wrote/modified one for me which though able to connect to database, doesn't return any value. The debug mode throws a warning " mysqli_num_rows() expects parameter 1 to be mysqli_result, boolean given ". Seems I am not collecting the query value correctly. The PHP Manuals says that mysqli_query() returns FALSE on failure and for successful SELECT, SHOW, DESCRIBE or EXPLAIN queries mysqli_query() will return a mysqli_result object and for other successful queries mysqli_query() will return TRUE ".
Any suggestions?
<form name="search" method="post" action="search.php">
<input type="text" name="searchterm" />
<input type="hidden" name="searching" value="yes" />
<input type="submit" name="submit" value="Search" />
</form>
<?php
$searchterm=trim($_POST['searchterm']);
$searching = $_POST['searching'];
$search = $_POST['search'];
//This is only displayed if they have submitted the form
if ($searching =="yes")
{
echo 'Results';
//If they forget to enter a search term display an error
if (!$searchterm)
{
echo 'You forgot to enter a search term';
exit;
}
//Filter the user input
if (!get_magic_quotes_gpc())
$searchterm = addslashes($searchterm);
// Now connect to Database
# $db = mysqli_connect('localhost','username','password','database' );
if (mysqli_connect_errno()) {
echo 'Error: Could not connect to the database. Please try again later.';
exit;
}
else {
echo "Database connection successful."; //Check to see whether we have connected to database at all!
}
//Query the database
$query = "SELECT * FROM wp_posts WHERE post_title LIKE '%$searchterm%' OR post_excerpt LIKE '%$searchterm%' OR post_content LIKE '%$searchterm%'";
$result = mysqli_query($db, $query);
if (!$result)
echo "No result found";
$num_results = mysqli_num_rows($result);
echo "<p>Number of match found: ".$num_results."</p>";
foreach ($result as $searchResult) {
print_r($searchResult);
}
echo "You searched for $searchterm";
$result->free();
$db->close();
}

To do your literal search as you have it, you would need to change the code '%{searchterm}%' to '%$searchterm%', since the brackets aren't needed and you were searching for the phrase "{searchterm}." Outside of that you might want to take a look at FULLTEXT search capabilities since you're doing a literal search in your current method.
To make the output look like Google's output you would simply code a wrapper for each search result and style them with CSS and HTML.

I think it should be something like '%$searchterm%', not '%{searchterm}%' in your query. You are not searching for your variable $searchterm in your example.
Google's display uses LIMIT in the query so it only displays a certain amount of results at a time (known as pagination).
This is tested and works. You will need to change 1) db connection info in the search engine class. 2) If you want it to be on separate pages, you will have to split it up. If not, copy this whole code to one page and it will work on that one page.
<?php
class DBEngine
{
protected $con;
// Create a default database element
public function __construct($host = '',$db = '',$user = '',$pass = '')
{
try {
$this->con = new PDO("mysql:host=$host;dbname=$db",$user,$pass, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING));
}
catch (Exception $e) {
return 0;
}
}
// Simple fetch and return method
public function Fetch($_sql)
{
$query = $this->con->prepare($_sql);
$query->execute();
if($query->rowCount() > 0) {
$rows = $query->fetchAll();
}
return (isset($rows) && $rows !== 0 && !empty($rows))? $rows: 0;
}
// Simple write to db method
public function Write($_sql)
{
$query = $this->con->prepare($_sql);
$query->execute();
}
}
class SearchEngine
{
protected $searchterm;
public function execute($searchword)
{
$this->searchterm = htmlentities(trim($searchword), ENT_QUOTES);
}
public function display()
{ ?>
<h1>Results</h1>
<?php
//If they forget to enter a search term display an error
if(empty($this->searchterm)) { ?>
<h3>Search Empty</h3>
<p>You must fill out search field.</p>
<?php }
else {
$con = new DBEngine('localhost','database','username','password');
$results = $con->Fetch( "SELECT * FROM wp_posts WHERE post_title LIKE '%".$this->searchterm."%' OR post_excerpt LIKE '%".$this->searchterm."%' OR post_content LIKE '%".$this->searchterm."%'");
if($results !== 0 && !empty($results)) { ?>
<p>Number of match found: <?php echo count($results); ?> on search:<br />
<?php echo strip_tags(html_entity_decode($this->searchterm)); ?></p>
<?php
foreach($results as $rows) {
echo '<pre>';
print_r($rows);
echo '</pre>';
}
}
else { ?>
<h3>No results found.</h3>
<?php
}
}
}
}
if(isset($_POST['submit'])) {
$searcher = new SearchEngine();
$searcher->execute($_POST['searchterm']);
$searcher->display();
} ?>
<form name="search" method="post" action="">
<input type="text" name="searchterm" />
<input type="hidden" name="searching" value="yes" />
<input type="submit" name="submit" value="Search" />
</form>

Related

foreach() Invalid argument supplied

I have this code that works for my friend but when I run it, it gave this Warning: Invalid argument supplied for foreach() in C:\wamp64\www\DVD_show.php on line 10
What is the problem?
'''
<?php
try {
/*** connect to SQLite database ***/
$dbh = new PDO("sqlite:dvd.db");
//echo("ok");
if(isset($_GET['name'])){
$name=$_GET['name'];
$sql = "SELECT * FROM DVD where name='".$name."'";
}else $sql = "SELECT * FROM DVD";
foreach ($dbh->query($sql) as $row)
{
print 'dvds[index++]="#'.$row['name'] ."#".$row['director']. "#". $row['price']."#".$row['stock'].'#";<br>';
//dvds[index++]="#Life is Beautiful#dvd1#10.5#10#history#Roberto Benigni#";
}
/*** close the database connection ***/
$dbh = null;
}
catch(PDOException $e)
{
echo $e->getMessage();
}
?>
<form action="http://127.0.0.1/DVD_show.php" method="get">
<p>Please input DVD name: <input type="text" name="name" /></p>
<p><input type="submit" /></p>
</form>
'''
$dbh->query($sql) will return you Statement. You should use fetch or fetchAll to get the results. While fetch will return only one - so not iterable, you should use fetchAll, which always returns array.
The dbh-> query is wrong at this place as it only returns a statment but not something you can use with foreach
You first need to use the fetch() or fetchAll() methods
Please see changed code.
NOTE: If you have a HIGH number of results it is not recommended to use fetchAll as it loads the wohle dataset . then better use fetch() and while like shown in the example ar the link below.
<?php
try {
/*** connect to SQLite database ***/
$dbh = new PDO("sqlite:dvd.db");
//echo("ok");
if(isset($_GET['name'])){
$name=$_GET['name'];
$sql = "SELECT * FROM DVD where name='".$name."'";
}else $sql = "SELECT * FROM DVD";
//change this
$data = $dbh->query($sql) ->fetchAll();
foreach ($data as $row)
//changes end
{
print 'dvds[index++]="#'.$row['name'] ."#".$row['director']. "#". $row['price']."#".$row['stock'].'#";<br>';
//dvds[index++]="#Life is Beautiful#dvd1#10.5#10#history#Roberto Benigni#";
}
/*** close the database connection ***/
$dbh = null;
}
catch(PDOException $e)
{
echo $e->getMessage();
}
?>
<form action="http://127.0.0.1/DVD_show.php" method="get">
<p>Please input DVD name: <input type="text" name="name" /></p>
<p><input type="submit" /></p>
</form>
'''
please see:
https://phpdelusions.net/pdo_examples/select

If there is no $_POST present after a URL, how can I prevent (nothing) from getting passed into a MySQL query, and causing an error?

I have a Delete.php page that deletes records based on their ID.
When there is an ID, i.e., Delete.php?id=3610, all is well, and it functions as expected.
If I just go to "Delete.php" and that's it - no ID, it generates:
"You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1"
From the little I understand, it is doing this because I am trying to pass a nonexistent variable into my query.
I have been trying to put if (empty($_POST['id'])) { } in different places, which removes the error, but breaks something else.
Here is my code:
<?php
require_once 'functions.php';
$conn = mysqli_connect("localhost", "user", "pass",'db');
writeHead("Delete Track");
if (isset($_POST['delete'])) {
$trkid = $_POST['trkid'];
$query = "DELETE FROM track WHERE TrackID=$trkid";
mysqli_query($conn, $query) or die(mysqli_error($conn));
if (mysqli_affected_rows($conn)>0) {
header("Location: Display.php?action=deleted&id=$trkid&status=deleted");
exit();
}
echo "<p class='error'>Unable to update record</p>";
} else {
if (!isset($_GET['id'])) {
echo "<p class='error'>No Track ID provided.<br><a href='Display.php'>Return to display page.</a><p>";
}
$trkid=$_GET['id'];
$query = "SELECT * FROM track WHERE TrackID=$trkid";
$result = mysqli_query($conn,$query);
if (!$result) {
die(mysqli_error($conn));
}
if (mysqli_num_rows($result)> 0) {
$row = mysqli_fetch_assoc($result);
$Name=$row['Name'];
$Album=$row['AlbumId'];
$Composer=$row['Composer'];
$Milli=$row['Milliseconds'];
$Bytes=$row['Bytes'];
$UnitPrice=$row['UnitPrice'];
} else {
echo "<p class='error'>Unable to retrieve Track $trkid.<br><a href='Display.php'>Return to display page.</a>";
}
}
?>
<p>Track Information:</p>
<p><?php echo "<b>ID: $trkid <br>Title: $Name</b>"; ?></p>
<form method="post" action="Comp3Delete.php">
<p>
<input type="hidden" name="trkid" value="<?php echo $trkid; ?>">
<input type="submit" name="delete" class="btn" value="Confirm Delete">
</p>
</form>
<p>Return to Track Table Display</p>
<?php writeFoot(); ?>
Your post code is fine. it's the GET code that's wrong:
if (!isset($_GET['id'])) {
^^^^^^^^--check if the parameter exists
}
$trkid=$_GET['id'];
^---try to use the parameter ANYWAYS, even if it doesn't exist.
$trkid=$_GET['id']; has no condition so it runs even when no id is passed which generates the error. Your code should go like this:
if(isset($_GET['id'])){
$trkid=$_GET['id'];
$query = "SELECT * FROM track WHERE TrackID=$trkid";
$result = mysqli_query($conn,$query);
if (!$result) {
die(mysqli_error($conn));
}
if (mysqli_num_rows($result)> 0) {
$row = mysqli_fetch_assoc($result);
$Name=$row['Name'];
$Album=$row['AlbumId'];
$Composer=$row['Composer'];
$Milli=$row['Milliseconds'];
$Bytes=$row['Bytes'];
$UnitPrice=$row['UnitPrice'];
} else {
echo "<p class='error'>Unable to retrieve Track $trkid.<br><a href='Display.php'>Return to display page.</a>";
}
}

Array returns null

I'm trying at the moment to create a login with PHP and MySQL but I'm stuck. The array that's supposed to give me Data from the database only returns "Null" I used var_dumb().
This is the index.php file :
<?php
include_once './Includes/functions.php';
?>
<!DOCTYPE html
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<div>
<form method="POST">
<label>User ID :</label>
<input id="login_username" name="login_username" type="login"><br>
<label>Password :</label>
<input id="login_password" name="login_password" type="password" ><br>
<input id="login_submit" name="login_submit" type="submit">
</form>
</div>
</body>
</html>
This is the function.php file :
<?php
require_once 'dbconnect.php';
function SignIn() {
$lUser = $_POST['login_username'];
$lPassword = md5($_POST['login_password']);
$querySQL = "SELECT * FROM tblUser WHERE dtUser='$lUser' AND dtPassword='$lPassword'";
$queryResult = mysqli_query($dbc, $querySQL);
while ($row = mysqli_fetch_assoc($queryResult)) {
$dataArrayLogin[] = $row;
}
if ($lUser == $dataArrayLogin['dtUser'] && $lPassword == $dataArrayLogin['dtPassword']) {
echo $dataArrayLogin;
$popup = "Login Succeed";
echo "<script type='text/javascript'>alert('$popup');</script>";
$_SESSION['user'] = $lUser;
header("Location: ./british.php");
} else {
echo $dataArrayLogin;
$popup = "Login Failed";
echo "<script type='text/javascript'>alert('$popup');</script>";
}
}
if (isset($_POST['login_submit'])) {
SignIn();
}
?>
Could you help me out ?
This could be, because you have no results?
Anyway, I've checked your code, and it's not good, because you are try to use this:
$dataArrayLogin['dtUser']
There is no 'dtUser' key in your $dataArrayLogin.
When you fetching the row, you are put it into a while cycle, and collect the data into an array:
while ($row = mysqli_fetch_assoc($queryResult)) {
$dataArrayLogin[] = $row;
}
Remove the while cycle. Simple use:
$dataArrayLogin = mysqli_fetch_assoc($queryResult);
And if you echo an array, the result will be Array. Use var_dump instead.
in your html form, you don't have <form method="POST" action="SignIn">. so when you submit the form, its not going somewhere.
You need to start debugging your script. Below are the steps I would take:
Do a var_dump() on the $_POST to see if it contains all values you want
echo the $querySQL to see if all values are put in correctly
Check your database if it actually contains the record with which you are trying to login
Fetch mysql errors using mysqli_error();
That should bring your error to light.
Edit:
I often find it usefull to place some echos throughout my script to find out what parts of the code are being accessed and what parts are being skipped.
I would add a LIMIT 1 to your query as there should only be one user with the entered credentials. This way you'll also be able to skip the while loop.
Change query like this
$querySQL = "SELECT * FROM tblUser WHERE dtUser=' ".$lUser." ' AND dtPassword=' ".$lPassword." ' ";

php problems in search function

Im trying to add search function.
i want it to work like that: for exmple if i have 5 field, and user wrote only in 2, the search will be based only on 2 field. I mean it not neccesary to write information in all 5 field, i want search will happen only in filled fields.
And now it works only if i will write something in all fields (for now i have 2). And if i will write only in one field it doesnt show anything.
Code:
<html>
<head>
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div id="container">
<h1>Поиск</h1>
<form action="search_form.php" method="post">
<p>Направление</p>
<input type="text" name="course" />
<p>Форма обучения</p>
<input type="text" name="form" />
<input type="submit" value="Искать">
</form>
<?php
$db = mysql_connect("localhost", "root", "") or die (mysql_error ());
mysql_select_db("university", $db) or die(mysql_error());
$w = array('TRUE');
if (isset($_POST['course']))
{
$course = $_POST['course'];
$w[] = "course='$course'";
}
if (isset($_POST['form']))
{
$form = $_POST['form'];
$w[]= "form='$form'";
}
$where = implode($w, ' AND ');
$query = ('SELECT * FROM news WHERE '.$where);
$result = mysql_query($query,$db);
if($result !== false)
{
$news = mysql_fetch_array($result);
while($news = mysql_fetch_assoc($result)) {?>
<tr>
<td><?=$news['id']?></td>
<td><?=$news['program']?></td>
</tr><?
}
}
else
{
echo 'Sorry, we didn't find anything.';
}?>
</div>
</body>
</html>
You are vulnerable to SQL injection attacks. Learn about and fix that before you do ANYTHING else with this code.
Plus your logic is faulty: mysql_query() returns false on errors. A query which has no results is NOT an error, and still returns a valid query handle. It'll simply have 0 rows on it.
$result = mysql_query($query);
if ($result === false) {
die(mysql_error());
} else if (mysql_num_rows($result) == 0) {
die("No results");
} else {
... display results
}

PHP form on function with SQL request

I have this function on my php:
function getLastMatchs($nb) {
try
{
$db = new PDO(DBHOST, DBUSER, DBPASS);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $e)
{
die('connexion failed: '.$e->getMessage());
}
$i=0;
$get5tmatchs = $db->query('SELECT wid, lid, date, cwid, clid FROM `match`');
while ($nb<$i)
{
$data5matchs = $get5tmatchs->fetch();
echo '<tr>
<td>'.$data5matchs['wid'].'</td>';
echo '<td>'.$data5matchs['lid'].'</td>';
echo '<td>'.$data5matchs['cwid'].'</td>';
echo '<td>'.$data5matchs['clid'].'</td>';
echo '<td>'.$data5matchs['date'].'</td>
<br>
</tr>';
$i++;
}
}
And my form is:
echo '<form action="index.php" method="post">
<h3>My question......</h3>
<p>
<input type="text" name="nbmatchs" />
<input type="submit" value="ok" />
</p>
</form>';
echo getLastMatchs('nbmatchs');
How can i do for show nbmatch time the guys want my table ?
When i do now, nothing happen.
Thanks for your help
PS: For exemple i tape 5, i can see 5 time the tabe i have put in my function.
What you indended to accomplish (as far I understood) to allow a visitor enter a numer and then submit it after what some "matches" data it shown. The number visitor entered acts as a limiter.
1. Where do you get your POST variables? You have placed a function below the form with an input value of string 'nbmatchs'. I guess you wanted to submit the form and get the 'nbmatches' value and then apply it to the SQL query for filtering. The way you have done it doesn't work. You have action attribute on your form element set to index.php. That's where we are going to submit the form data. So we need to have a way to get the submitted POST variables. We do it like this:
$nbmatchs = $_POST['nbmatchs'];
Never trust data client has given you. As we know that it must a number let's do a check on it:
$nbmatches = is_numeric(trim($_POST['nbmatchs'])) ? $_POST['nbmatchs'] : 1;
Above we checked if the data client has given really is a number. If it is we'll assign this nubmer to variable $nbmatches. If the data client has given is not a number (eg. some string) we assign number 1 to the variable. At this point we may end the script execution a let the visitor know he must enter a number but we just assign 1 to the variable if anything seems suspicious. After that we can submit this variable to the function getLastMatchs which takes the variable and assigns it to the SQL query as a results limiter. Assuming that all the code will be in one file 'index.php' you should have the following code:
<?php
function getLastMatchs($nbmatches) {
try{
$db = new PDO(DBHOST, DBUSER, DBPASS);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e) {
die('connexion failed: '.$e->getMessage());
}
try {
$select = $db->prepare('SELECT wid, lid, date, cwid, clid FROM `match` LIMIT '.$nbmatches.';');
$select->execute();
$results = $select->fetchAll(PDO::FETCH_ASSOC);
} catch(PDOException $ex) {
echo "<span style='color:red'>".$ex->getMessage()."</span></p>";
}
echo '<table>';
foreach($results as $result){
$output = '<tr>';
$output .= '<td>'.$result['wid'].'</td>';
$output .= '<td>'.$result['lid'].'</td>';
$output .= '<td>'.$result['cwid'].'</td>';
$output .= '<td>'.$result['clid'].'</td>';
$output .= '<td>'.$result['date'].'</td>';
$output = '</tr>';
echo $output;
}
echo '</table>';
}
if(isset($_POST['nbmatchs'])){
$nbmatches = is_numeric(trim($_POST['nbmatchs'])) ? $_POST['nbmatchs'] : 1;
getLastMatchs($nbmatches);
}
?>
<form action="index.php" method="post">
<h3>My question......</h3>
<p>
<input type="text" name="nbmatchs" />
<input type="submit" value="ok" />
</p>
</form>
Let me know if this works the way you wanted.

Categories