My PHP Search Function isn't Outputting Data - php

So I am trying to create a way of searching my website. I've created a search bar on my index page. You can find this page here: http://seersvillage.com/v1.2/
My search form looks like this:
<form method="post" action="search.php">
<input type="text" name="search" class="search" value="Skeleton" onFocus="this.value=''">
</form>
and I have a functions.php file attatched and this page is also connected to my mysql database. I have content available to be read / searched for all ready.
Here is my search function on functions.php:
function doSearch() {
$output = '';
if(isset($_POST['search'])) {
$searchq = $_POST['search'];
$searchq = preg_replace ("#[^0-9a-z]#i","",$searchq);
$query = mysql_query("SELECT * FROM entries WHERE name LIKE '%$searchq%' or description LIKE '%$searchq%' or content LIKE '%$searchq%'") or die("Could not search");
$count = mysql_num_rows($query);
if($count == 0) {
$output = 'there was no search results!';
} else {
while($row = mysql_fetch_array($query)) {
$eName = $row['name'];
$eDesc = $row['description'];
$eCont = $row['content'];
$id = $row['id'];
$output .= '<div>'.$eName.' '.$eDesc.'</div>';
}
}
}
}
And the only thing on my search.php (excluding your usual html layout) is as follows:
<?php
include('includes/functions.php');
if(!isset($_POST['search'])) {
header("Location:index.php");
}
?>
and further down in the tags.
<?php print("$output");?>
Now I am pretty new to PHP and MySQL. However I am getting no error on my error.log file, making troubleshooting a little hard for a first timer. Any suggestions? I'm sure it's a very simple mistake, probably just misspelt something, but I just can't see it.

it seems that your php.ini file is set to not display errors. Add these lines of code at the beginning of your code and retry:
<?php
error_reporting(E_ALL);
ini_set("display_errors", 1);
?>

Your doSearch function does not return anything.
return $output;
But $output is only declared within the function. So you'll need to use
print(doSearch());
Either that or declare $output as a global variable, but we don't want to do that :)

function doSearch() {
$output = '';
if(isset($_POST['search'])) {
$searchq = $_POST['search'];
$searchq = preg_replace ("#[^0-9a-z]#i","",$searchq);
$query = mysql_query("SELECT * FROM entries WHERE name LIKE '%$searchq%' or description LIKE '%$searchq%' or content LIKE '%$searchq%'") or die("Could not search");
$count = mysql_num_rows($query);
if($count == 0) {
$output = 'there was no search results!';
} else {
while($row = mysql_fetch_array($query)) {
$eName = $row['name'];
$eDesc = $row['description'];
$eCont = $row['content'];
$id = $row['id'];
$output .= '<div>'.$eName.' '.$eDesc.'</div>';
}
}
//make sure your function returns $output
return $output;
}
Make sure your function returns the output and then echo out the function:
<?php echo doSearch(); ?>
This is because of how PHP variables are scoped.
...then of course we need to add in all the standard provisos ... don't use the mysql_ library it's almost as dead as a Norwegian Blue. If you use mysqli or PDO you can bind the parameters/values to a prepared statement and not only will that improve efficiency but it'll ensure your input is properly sanitised (far better than that odd ad-hoc preg_replace you're using).
You don't want to kill your script (die) when the query fails - that's just a bit weird, handle the error properly.
There are far better ways to do searches in SQL such as FULLTEXT searches.. or if you can, perhaps implement Apache Solr rather than trying to roll your own.

Related

How to highlight user input in mysql search results using php?

I have added my code below, i am new to php and mysql and trying to search mysql using php based on user inputs and working really fine. But not sure how to highlight the user input value while displaying from mysql.
$output = NULL;
if(isset($_POST['submit'])){
$mysqli = new mysqli("localhost","root","","test");
$search = $mysqli->real_escape_string($_POST['search']);
$resultSet = $mysqli->query("SELECT * FROM books WHERE BookContent LIKE '%$search%'");
if($resultSet->num_rows>0){
while($rows = $resultSet->fetch_assoc()){
$BookContent = $rows['BookContent'];
//$output = preg_replace("/($search)/i",'<span class="highlight">$1</span>', $output);
echo $output = "" ."Your search results--> $BookContent"."<br>";
}
}else{
echo $output = "No result" ;
}
}
?>
just add this in your page.
CSS:
.highlight{background-color:yellow}
jQuery:
$("body").highlight("<?php echo $search; ?>");

How do i create pagination for my search results

I'm trying to create pagination for my search results. I'm able to create a working pagination if I drop the search functionality (i.e by not including if (isset($_POST['submit-search'])) and LIKE %search%) but once I include these, as seen in the code beneath, I only get a blank page when I click the next page, like as if the sql terms isn't kept in memory.
<?php
if (isset($_POST['submit-search'])) {
$results_per_page = 2;
$search = mysqli_real_escape_string($conn, $_POST['search']);
$sql = "SELECT * FROM article WHERE a_title LIKE '%$search%' OR a_text LIKE '%$search%'";
$result = mysqli_query($conn, $sql);
$queryResult = mysqli_num_rows($result);
$number_of_pages = ceil($queryResult/$results_per_page);
// determine which page number visitor is currently on
if (!isset($_GET['page'])) {
$page = 1;
} else {
$page = $_GET['page'];
}
$this_page_first_result = ($page-1)*$results_per_page;
$sql = "SELECT * FROM article WHERE a_title LIKE '%$search%' OR a_text LIKE '%$search%'LIMIT ".$this_page_first_result.",".$results_per_page." ";
$result = mysqli_query($conn, $sql);
// echoing the search results
while ($row = mysqli_fetch_assoc($result)) {
echo "<h3>".$row['title']."</h3>
<p>".$row['text']."</p>";
}
// echoing the pagination
for ($page=1;$page<=$number_of_pages;$page++) {
echo "<li><a href='search_results.php?page=".$page."'>".$page."</a></li>";
}
}
?>
html
<form action="search_results.php" method="POST">
<input type="text" name="search"placeholder="Search">
<button type="submit" name="submit-search">go</button>
</form>
The logic is wrong.
// this code is only executed on the initial search.
if (isset($_POST['submit-search'])) {
When the user go's to the next page:
echo "<li><a href='search_results.php?page=".$page."'>".$page."</a></li>";
Only a page number is given and the search parameter is lost as nothing is posted, so the first if statement will not run again.
You could do something like:
echo "<li><a href='search_results.php?page=".$page."&search=$search'>".$page."</a></li>";
And:
if(isset($_POST['submit-search']) || isset($_GET['search'])){
$search = ...;
}

jquery autocomplete with php file that queries a mysql database

i'm trying to use a jquery autocomplete text-input with a mysql database for autocomplete suggestions. From a tutorial i got the following php function that is used to query a database.
<?php
include "db_connect.php";
$search = protect($_GET['term']);
$result = mysql_query("SELECT planeID FROM `planes` WHERE `planeID` LIKE '%$search%' ")
or die('Something went wrong');
$json = '[';
$first = true;
while ($row = mysql_fetch_assoc($result))
{
if (!$first) { $json .= ','; } else { $first = false; }
$json .= '{"value":"'.$row['planeID'].'"}';
}
$json .= ']';
echo $json;
within the chrome networkpanel, i can see, that after each input into my textfield a request to "suggest_planeID.php?term=d-" i sent but i don't reveive any suggestion.
the database looks like this:
i have ha DatatBase called "test" with a table caled "planes" inside. This table has two columns 'planeID' and 'planeType".
is there any chance to debug the php file to find the error or does anyone here already see the error?

Having problems with cannot redeclare

I just finished writing this script and getting it to work but I need to use it a total of 8 times on 1 page. It works fine the first time but the second time I get: Fatal Error cannot redeclare get_names(). I've been told the way around this is to use include_once but I can't seem to figure out how exactly I'm supposed to do that. I've tried cutting both of the get_names parts out of the code and putting them into separate php files then using the include_once command. I got it to work but once again I got the same error after trying to use the script twice. I also tried putting the whole script into a php file and then using the include_once("scriptname.php") command and the same thing happened. So my questiion is how exactly do I cut this script up so I don't get this error anymore?
<?php
$db = mysql_connect('localhost', 'username', 'pass') or die("Database error");
mysql_select_db('dbname', $db);
$query = "SELECT pool FROM winners";
$result = mysql_query($query) or die(mysql_error());
while($row = mysql_fetch_array($result))
if ($row['pool'] % 2) {
echo "<h4>Result 1</h4>";
$names = get_names(1);
foreach($names as $name) {
echo $name . "<br/>";
}
} else {
echo "<h4>Result 2</h4>";
$names = get_names(0);
foreach($names as $name) {
echo $name . "<br/>";
}
}
function get_names($pool_result)
{
$name_array = array();
$query = "SELECT * FROM comments WHERE commentid % 2 = $pool_result";
$result = mysql_query($query);
while ($row = mysql_fetch_array($result)) {
array_push($name_array, $row['name']);
}
return $name_array;
} ?>
put getNames function in afile.php and include that once at the start. take getNames function out of your current file.
so things goes like this
in first php file (say) you have this code - filea.php
function get_names($pool_result)
{
$name_array = array();
$query = "SELECT * FROM comments WHERE commentid % 2 = $pool_result";
$result = mysql_query($query);
while ($row = mysql_fetch_array($result)) {
array_push($name_array, $row['name']);
}
return $name_array;
}
you second file will have fileb.php
$db = mysql_connect('localhost', 'username', 'pass') or die("Database error");
..... rest of source code excluded. Make sure you get rid of getNames in this file
Now just include as per normal
include 'filea.php'; // include it once only
include 'fileb.php'; // as many times as your wish
or just wrap your code in a function and call that instead
If you are using this script 8 times, then put the entire thing inside a function and call that function 8 times instead of copy pasting.

editing mysql table with html form

My aim is to have a simple, form based CMS so the client can log in and edit the MySQL table data via an html form. The login is working, but the edit page isn't returning the values from the MySQL table, nor am I getting any errors.
I'm still amateur, and I first started the following code for a class project, but now plan to implement it for a live site. From what I understand I shouldn't have to declare the next/previous/etc. variables at the top, which I tried unsuccessfully to do so anyway. Does anything stand out to any of you?:
<?php
echo "<h2>Edit Special Offer</h2><hr>";
if (isset($_COOKIE["username"]))
{
echo "Welcome " . $_COOKIE["username"] . "!<br />";
include "login.php";
}
else
echo "You need to log in to access this page.<br />";
if(isset($previous))
{
$query = "SELECT id, specialtitle, specialinfo
FROM special WHERE id < $id ORDER BY id DESC";
$result = mysql_query($query);
check_mysql();
$row = mysql_fetch_row($result);
check_mysql();
if ($row[0] > 0)
{
$id = $row[0];
$specialtitle = $row[1];
$specialinfo = $row[2];
}
}
elseif (isset($next))
{
$query = "SELECT id, specialtitle, specialinfo
FROM special WHERE id > $id ORDER BY id ASC";
$result = mysql_query($query);
check_mysql();
$row = mysql_fetch_row($result);
check_mysql();
if ($row[0] > 0)
{
$id = $row[0];
$specialtitle = $row[1];
$specialinfo = $row[2];
}
}
elseif (isset($add))
{
$query = "INSERT INTO special (specialtitle, specialinfo)
VALUES ('$specialtitle', '$specialinfo')";
$result = mysql_query($query);
check_mysql();
$id = mysql_insert_id();
$message = "Special Offer Added";
}
elseif (isset($update))
{
$query = "UPDATE special
SET specialtitle='$specialtitle', specialinfo='$specialinfo'
WHERE id = $id";
$result = mysql_query($query);
check_mysql();
$id = mysql_insert_id();
$message = "Monthly Special Updated";
}
elseif (isset($delete))
{
$query = "DELETE FROM special WHERE id = $id";
$result = mysql_query($query);
check_mysql();
$specialtitle = "";
$specialinfo = "";
$message = "Special Offer Deleted";
}
$specialtitle = trim($specialtitle);
$specialinfo = trim($specialinfo);
?>
<form method="post" action="editspecial.php">
<p><b>Special Offer</b>
<br><input type="text" name="specialtitle" <?php echo "VALUE=\"$specialtitle\"" ?>> </p>
<p><b>Special Info/Description</b>
<br><textarea name="specialinfo" rows="8" cols="70" >
<?php echo $specialinfo ?>
</textarea> </p>
<br>
<input type="submit" name="previous" value="previous">
<input type="submit" name="next" value="next">
<br><br>
<input type="submit" name="add" value="Add">
<input type="submit" name="update" value="Update">
<input type="submit" name="delete" value="Delete">
<input type="hidden" name="id" <?php echo "VALUE=\"$id\"" ?>>
</form>
<?php
if (isset($message))
{
echo "<br>$message";
}
?>
Login.php:
<?php
function check_mysql()
{
if(mysql_errno()>0)
{
die ("<br>" . mysql_errno().": ".mysql_error()."<br>");
}
}
$dbh=mysql_connect ("xxxxxxxxxxxxxxxxx","xxxxxxxx","xxxxxxxx");
if (!$dbh)
{
die ("Failed to open the Database");
}
mysql_select_db("xxxxxx");
check_mysql();
if(!isset($id))
{
$id=0;
}
?>
Please please please do a little bit more learning before attempting to build this thing.
You can do it the way you are doing it, but with just a small amount of extra knowledge about OO programming, and maybe about the Pear db classes you will have 3x cleaner code.
If you really choose not to, at the very least, pull each of your save, update, delete, etc procedures out into functions instead of just inlining them in your code. put them in a separate file, and include it in that page.
It may not be useful to you, but I am going to dump a generic table access class here in the page for you. It requires a simple db class API, but if you use this or something like it your life will be 5x easier.
If you don't understand this code when you look at it, that's ok, but please just come back and ask questions about the stuff you don't understand. That is what stackoverflow is for.
This is an older class that should just do basic stuff. Sorry it's not better I just wanted to dig something out of the archives for you that was simple.
<?php
// Subclass this class and implement the abstract functions to give access to your table
class ActiveRecordOrder
{
function ActiveRecordOrder()
{
}
//Abstract function should return the table column names excluding PK
function getDataFields()
{}
//Abstract function should return the primary key column (usually an int)
function getKeyField()
{}
//abstract function just return the table name from the DB table
function getTableName()
{}
/*
This function takes an array of fieldName indexed values, and loads only the
ones specified by the object as valid dataFields.
*/
function loadRecordWithDataFields($dataRecord)
{
$dataFields = $this->getDataFields();
$dataFields[] = $this->getKeyField();
foreach($dataFields as $fieldName)
{
$this->$fieldName = $dataRecord[$fieldName];
}
}
function getRecordsByKey($keyID, &$dbHandle)
{
$tableName = $this->getTableName();
$keyField = $this->getKeyField();
$dataFields = $this->getDataFields();
$dataFields[] = $this->getKeyField();
$results = $dbHandle->select($tableName, $dataFields, array($keyField => $keyID));
return $results;
}
function search($whereArray, &$dbHandle)
{
$tableName = $this->getTableName();
$dataFields = $this->getDataFields();
$dataFields[] = $this->getKeyField();
return $dbHandle->select($tableName, $dataFields, $whereArray);
}
/**
* Since it is *hard* to serialize classes and make sure a class def shows up
* on the other end. this function can just return the class data.
*/
function getDataFieldsInArray()
{
$dataFields = $this->getDataFields();
foreach($dataFields as $dataField)
{
$returnArray[$dataField] = $this->$dataField;
}
return $returnArray;
}
/**
* Added update support to allow to update the status
*
* #deprecated - use new function saveObject as of 8-10-2006 zak
*/
function updateObject(&$dbHandle)
{
$tableName = $this->getTableName();
$keyField = $this->getKeyField();
$dataArray = $this->getDataFieldsInArray();
$updatedRows = $dbHandle->updateRow(
$tableName,
$dataArray,
array( $keyField => $this->$keyField )
);
return $updatedRows;
}
/**
* Allows the object to be saved to the database, even if it didn't exist in the DB before.
*
* #param mixed $dbhandle
*/
function saveObject(&$dbhandle)
{
$tableName = $this->getTableName();
$keyField = $this->getKeyField();
$dataArray = $this->getDataFieldsInArray();
$updatedRows = $dbHandle->updateOrInsert(
$tableName,
$dataArray,
array( $keyField => $this->$keyField )
);
return $updatedRows;
}
}
"Welcome " . $_COOKIE["username"] . "!<br />"; [and many other places]
HTML-injection leading to cross-site security holes. You need to use htmlspecialchars every time you output a text value to HTML.
"INSERT INTO special (specialtitle, specialinfo) VALUES ('$specialtitle' [and many other places]
SQL-injection leading to database vandalism. You need to use mysql_real_escape_string every time you output a text value to an SQL string literal.
if (isset($_COOKIE["username"]))
Cookies are not secure, anyone can set a username cookie on the client-side. Don't use it for access control, only as a key to a stored or session user identifier.
You also appear to be using register_globals to access $_REQUEST values as direct variables. This is another extreme no-no.
Between all these security snafus you are a sitting duck for Russian hackers who will take over your site to push viruses and spam.
Be careful with your code there. Your not filtering your cookie value and you shouldn't be storing a username directly in there as it can be easily changed by the visitor. You should look into filter_input for filtering cookie data and eany form data that is being submitted - especially your $_POST['id']
this will save you a lot of heartache further down the line from attacks.
Your if else statements are checking if variables are set but you dont set next, previous, add etc
You are using submit buttons with those values so you would need to check for
if(isset($_POST['previous']))
instead of yours which is
if(isset($previous))
I can't see where you set your database details either unless you have an included file somewhere that you haven't posted. (don't post the real ones of course but i can't see anything)
I don´t know what's happening in login.php, but you're using $id before it is set. That´s just in the first part.
Edit: To clarify, you are using $id in every query statement and setting it afterwards, my guess would be that $id is null and that is why nothing gets returned.
Edit 2: What else is happening in login.php? If you never read your $_POST variables, nothing will ever happen.
Edit 3: Like I already partly said in a comment, your if(isset($previous)) section, elseif (isset($update)) section and elseif (isset($delete)) sections will never do anything as $id is always 0.
After authenticating your user you need to get and filter the posted variables, $_POST['id'], $_POST['previous'], etc.

Categories