I'm trying to create a search feature on my website. It isn't showing any results and I keep getting Call to a member function prepare() on a non-object in line x...
function doSearch() {
$output = '';
if(isset($_POST['search'])) {
$searchq = $_POST['search'];
$searchq = preg_replace ("#[^0-9a-z]#i","",$searchq);
$sql = "SELECT * FROM entries WHERE name LIKE :searchq or description LIKE :searchq or content LIKE :searchq";
$stmt = $conn->prepare($sql);
$stmt->bindParam(":searchq",$searchq,PDO::PARAM_STR);
$stmt->execute();
$count = $stmt->rowCount();
if($count == 0) {
$output = '<tr><tr>No results found.</tr></td>';
} else {
while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$eName = $row['name'];
$eDesc = $row['description'];
$eCont = $row['content'];
$id = $row['id'];
$elvl = $row['level'];
$ehp = $row['hp'];
$output .= '<tr><td>'.$eName.'</td><td>'.$eDesc.'</td><td>'.$elvl.'</td><td>'.$ehp.'</td></tr>';
}
}
return $output;
}
}
I have my PDO connection included in my functions.php file.
prepare() is a method of a PDO connection object, and your $conn variable is not one. It needs to be instantiated as a connection object, like this:
$conn = new PDO('mysql:host=localhost;dbname=database', 'user', 'password');
Or if that's already done somewhere in the "global" scope, you just need to declare in your function:
global $conn;
It's fine to do this. The declaration is misleading. It's only "global" in the scope of the executing script, and does not transcend the script execution. All such objects are destroyed at the end of script execution. It's nothing to do with the session.
should be like:
$sql = "SELECT * FROM entries
WHERE name LIKE :searchq or
description LIKE :searchq or
content LIKE :searchq";
global $conn;
$stmt = $conn->prepare($sql);
Make sure you have included the db configuration file.
Related
I need to write a PHP function to echo out MySQL rows as I give it the SQL query I want to be executed as the function argument. I have tried out the following code but it is giving me an undefined index error
function runQuery($query) {
$conn = mysqli_connect('localhost', 'root', '', 'mydb');
$result = mysqli_query($conn,$query);
while($row=mysqli_fetch_assoc($result)) {
$resultset[] = $row;
}
if(!empty($resultset))
return $resultset;
the code I am using to call the function is;
runQuery(SELECT * FROM mytable WHERE id='5')
echo $resultset['name'];
this, however, gives me this error, undefined index 'resultset' on line 25. any kind assistance would be appreciated
You dont have a $resultset in the scope of where you call the function. The function creates one, but that is only visible inside the function.
You will also have to put QUOTES around the query, you are passing a string there so it needs to be quoted.
Your errors should have generated quite a few error messages, if you were not getting them I have added 4 lines of code you should add while testing code for example if you are testing on a LIVE server with error reporting turned off.
You should also change the function to ensure you always return something
So amend the call to
ini_set('display_errors', 1);
ini_set('log_errors',1);
error_reporting(E_ALL);
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
function runQuery($conn, $query) {
$resultset = [];
$result = mysqli_query($conn,$query);
while($row=mysqli_fetch_assoc($result)) {
$resultset[] = $row;
}
return $resultset;
}
$resultset = runQuery($conn, "SELECT * FROM mytable WHERE id='5'");
// as result will now be a multidimentional array
// you will need to loop over that to get each returned row
foreach ( $resultset as $row ) {
echo $row['name'];
}
AFTER your edit there is another error
$conn is not created inside the function, so will be invisible in the function code unless passed as a parameter to the function (there is another way but lets not get into the bad habit of using global variables)
First, your code is probably vulnerable to SQL Injection. Please take care of that, by using prepared statements for instance.
https://www.w3schools.com/sql/sql_injection.asp
https://websitebeaver.com/prepared-statements-in-php-mysqli-to-prevent-sql-injection
Other than that, you do not assign the return value of your function to a variable. You cannot use the $resultset defined in the function scope outside the function, as it is a different scope. Try the following:
$resultset = runQuery("SELECT * FROM mytable WHERE id='5'")
echo $resultset['name'];
I built a similar function recently - here is my code
function returnSQL($conn, $nameSql) {
$result = mysqli_query($conn, $nameSql);
if (!$result) {
return 0;
}
while ($res = mysqli_fetch_assoc($result)) {
$data[] = $res;
}
return $data;
}
The connection is setup outside the function and passed in as an argument along with the sql like this...
$conn = mysqli_connect($servername, $username, $password, $DBName);
if (!$conn) {
echo 'Failed to connect to database :- ' . $DBName . '<br>';
die();
}
$sql = "SELECT * FROM table";
$data = returnSQL($conn, $sql);
I'm no expert, but this works for me :)
What I notice from your code is that you are trying to access $resultset outside of the function it is declared in and I think it is not available as a global variable - perhaps it should be something like:
$returnValue = runQuery(SQL statement);
// $returnValue is assigned the array returned from runQuery()
echo $returnValue['name'];
Why is this not working:
function listOrderComments ($factnr){
global $connection;
//$factnr = 123; //or $factnr = "123"; (Both work)
$query = "SELECT * FROM orderstatus WHERE factuurnummer = '$factnr'";
$result = mysqli_query($connection, $query);
When I echo $factnr I get "123" back.
When I uncommented //$factnr = 123; my function is working.
Looked everywhere for a solution. check the type $factnr is (string).
Well if you're using a variable in your query you're opening yourself up to an injection attack for one.
If you're going to be using that variable I would recommend you use bind_param for your query
Read the PHP manual link below and you will be able to figure out the issue
http://php.net/manual/en/mysqli-stmt.bind-param.php
If you're passing in a variable to your function it should already be set so I don't understand why you're setting it to 123 anyway. So execute the sql statement and bind the parameter following the first example on the PHP docs page.
public function listOrderComments ($factnr)
{
global $connection;
$query = "SELECT * FROM orderstatus WHERE factuurnummer = ?";
$sql->prepare($query);
$sql->bind_param("s", $factnr);
$sql->execute();
$result = $sql->get_result();
$data = mysqli_fetch_all($result, MYSQLI_ASSOC);
foreach ($data as $row) {
print_r($row);
}
}
Then do what you want with the result
You can go with:
$query = "SELECT * FROM orderstatus WHERE factuurnummer = ". $factnr;
Concatenating your code is not good practise. Your best solution is to use PDO statements. It means that your code is easier to look at and this prevents SQL injection from occuring if malice code slipped through your validation.
Here is an example of the code you would use.
<?php
// START ESTABLISHING CONNECTION...
$dsn = 'mysql:host=host_name_here;dbname=db_name_here';
//DB username
$uname = 'username_here';
//DB password
$pass = 'password_here';
try
{
$db = new PDO($dsn, $uname, $pass);
$db->setAttribute(PDO::ERRMODE_SILENT, PDO::ATTR_EMULATE_PREPARES);
error_reporting(0);
} catch (PDOException $ex)
{
echo "Database error:" . $ex->getMessage();
}
// END ESTABLISHING CONNECTION - CONNECTION IS MADE.
$factnr = "123" // or where-ever you get your input from.
$query = "SELECT * FROM orderstatus WHERE factuurnummer = :factnr";
$statement = $db->prepare($query);
// The values you wish to put in.
$statementInputs = array("factnr" => $factnr);
$statement->execute($statementInputs);
//Returns results as an associative array.
$result = $statement->fetchAll(PDO::FETCH_ASSOC);
$statement->closeCursor();
//Shows array of results.
print_r($result);
?>
Use it correctly over "doted" concat. Following will just work fine:
$factnr = 123;
$query = "SELECT * FROM orderstatus WHERE factuurnummer = " . $factnr;
UPDATE:
here is $factnr is passing as argument that supposed to be integer. Safe code way is DO NOT use havvy functions even going over more complicated PDO, but just verify, is this variable integer or not before any operation with it, and return some error code by function if not integer. Here is no danger of code injection into SQL query then.
function listOrderComments ($factnr){
global $connection;
if (!is_int($factnr)) return -1
//$factnr = 123; //or $factnr = "123"; (Both work)
$query = "SELECT * FROM orderstatus WHERE factuurnummer = " . $factnr;
$result = mysqli_query($connection, $query);
So I have 2 files one is mainvariables.php & load_more.php. The load_more.php is a php file on its own since i make an ajax call to it. The mainvariables.php file has 1 function.
It's weird because in my header.php file I include the mainvariables.php and get the returned values but when I try it with the load_more.php file it does not work.
mainvariables.php
<?php
function mainVariables(){
global $pdo;
//getting school id for switch statment
$schoolId = (isset($_GET['id']) ? $_GET['id']:NULL);
if ($schoolId) {
$sql = 'SELECT * FROM schools WHERE id = :id';
$query = $pdo->prepare($sql);
$query->execute(array(':id' => $schoolId));
}else {
echo "Not Working";
}
//all values of current school
return $query->fetchAll(PDO::FETCH_ASSOC);
}
?>
load_more.php
<?php
// including the config file
require('config.php');
//pdo connct for config.php file
$pdo = connect();
//Include main variables function
include('php/mainvariables.php');
//return of main variables function
$specificSchool = mainVariables();
//School Variables
$shcoolOfficialId = $specificSchool[0]["id"];
switch ($shcoolOfficialId) {
case 1:
echo "yes";
break;
case 2:
echo "no";
break;
default:
echo "There are no more stories to load.";
break;
}
?>
Just for example my header.php file is like this:
<?php
// including the config file
require('config.php');
//pdo connct for config.php file
$pdo = connect();
//Include main variables function
include('php/mainvariables.php');
//return of main variables function
$specificSchool = mainvariables();
$shcoolOfficialId = $specificSchool[0]["id"];
?>
the header.php does work but the load_more.php does not. I get error: Call to a member function fetchAll() on null on line 15 of mainvariables.php. It's the line returning the query. Also it says Undefined variable: query for the same line as well.
Thank YOU
The problem is this statement:
return $query->fetchAll(PDO::FETCH_ASSOC);
If the preceding if statement evaluates to false, $query will never be defined. Return a different value if $schoolId does not exist, and check the result before using it in the rest of the script.
You define $query in the scope of the if statement, so that variable has not been created outside of the if statement so when you run this,
return $query->fetchAll(PDO::FETCH_ASSOC);
It will fail. Why don't you try this,
function mainVariables(){
global $pdo;
$query = null;
//getting school id for switch statment
$schoolId = (isset($_GET['id']) ? $_GET['id']:NULL);
if ($schoolId) {
$sql = 'SELECT * FROM schools WHERE id = :id';
$query = $pdo->prepare($sql);
$query->execute(array(':id' => $schoolId));
}else {
echo "Not Working";
}
//all values of current school
return $query->fetchAll(PDO::FETCH_ASSOC);
}
Edit 1
I put the fetching of the results in the if statement, so only it will only fetch in that part, that way you get the error and you don't need to define the $query outside of the if statement.
function mainVariables(){
global $pdo;
//getting school id for switch statment
$schoolId = (isset($_GET['id']) ? $_GET['id']:NULL);
if ($schoolId) {
$sql = 'SELECT * FROM schools WHERE id = :id';
$query = $pdo->prepare($sql);
$query->execute(array(':id' => $schoolId));
//all values of current school
return $query->fetchAll(PDO::FETCH_ASSOC);
}else {
echo "Not Working";
}
}
I get this error when trying to run this, what do it mean?
if(isset($_POST['submit']))
{
$date = $_POST['date'];
$partySize = $_POST['partysize'];
$catering = $_POST['catering'];
print_r($date);
print_r($partySize);
print_r($catering);
include "/diska/www/include/coa123-13-connect.php";
$host='co-project.lboro.ac.uk';
$dbName='coa123wdb';
$dsn = "mysql://$username1:$password1#$host/$dbName"; //Data Source Name
require_once('MDB2.php'); //Just include this line into your program - you do not have to have the source in your directory
$db =& MDB2::connect($dsn); //Try to make a connection
if (PEAR::isError($db)) {
die($db->getMessage());
}
//step 1 - query
$sql = "SELECT * FROM venue
WHERE capacity >= $partySize";
//step 2 - executing the query
$result =& $db->query($sql);
if (PEAR::isError($sql)) {
die($result->getMessage());
}
$valueIDArray = array();
while($row = $result -> fetchrow()){
$valueIDArray[] = $row[0];
}
$values = implode(',', $valueIDArray);
$query = "SELECT * FROM venue_booking
WHERE venue_id IN ($values)";
//step 2 - executing the query
$result1 =& $db->query($query);
if (PEAR::isError($query)) {
die($result1->getMessage());
}
while($row = $result1 -> fetchrow()){
$idValue[] = $row[0];
$dateValues[] = $row[1];
}
availableDate($dateValues,$date,$idValue, $db); //Line error points to
function availableDate($bookedDates, $date, $idValue, $db){
I have commeted on the line the error points to, this file works when its in its own PHP file but when inside the if(isset($_POST['submit'])) statement it does not work. What am I doing wrong?
Move the function definition outside the if statement. There's almost never a good reason to do that -- the only excuse might be if you wanted different definitions of the function depending on a condition, but that doesn't seem to be what you're doing. If you define a function inside an if, you have to define it before you call it; functions defined at top-level can be called from anywhere.
call availableDate after it's defined, if you already have to define it inside of if statement.
Ex.
function availableDate($bookedDates, $date, $idValue, $db){
...
}
//and then call it...
availableDate($dateValues,$date,$idValue, $db); //Line error points to
EDIT:
Example of non-working function defined inside of conditional statement
if(1){
func('a');
function func($a){
echo $a;
}
}
This wont work, but this will:
if(1){
function func($a){
echo $a;
}
func('a');
}
I'm trying to place these in a seperate file that'll be included on every page
$sql = 'select id, name, age, address, pincode from json where name = :name';
$arr = array(":name" => $name);
// There are some 30 diff sql's and arrays
Another page
$name = 'peter';
$conn = connect();
function myType(){
global $conn;
global $sql;
global $arr;
$stmt = $conn->prepare($sql);
$stmt->execute($arr);
while( $row = $stmt->fetch(PDO::FETCH_ASSOC) ) {
foreach ($row as $value) {
echo $value.' <br>';
}
}
}
myType();
I'm trying to keep the sqls and arrays in a separate file and use them when needed. Keeps things clean and easy to maintain. But the variables are declared later, which gives me: Notice: Undefined variable: name in C:\web\apache\htdocs\dev\json.php on line 24
Can you see a way to do this without uglying things?
Well you should use two files
sql.php
fetch.php
Then in fetch.php you will use require_once 'sql.php'
here's the code for fetch.php:
$name = 'peter';
$conn = connect();
require_once 'sql.php';
function myType(){
global $conn;
global $sql;
global $arr;
$stmt = $conn->prepare($sql);
$stmt->execute($arr);
while( $row = $stmt->fetch(PDO::FETCH_ASSOC) ) {
foreach ($row as $value) {
echo $value.' <br>';
}
}
}
myType();
And this is sql.php
$sql = 'select id, name, age, address, pincode from json where name = :name';
$arr = array(":name" => $name);
This should be helpful and you can use sql.php whenever you like.
Storing the queries and there bound parameters in a separate include is a bit strange. How will you change the bound parameter after the include?
My suggestion is to create a model that will handle the database operations. The benefit of this is you can encapsulate the database work and keep it separate from your app logic and also easily reuse it throughout.
Basic example:
class CustomersModel
{
protected $db;
public function __construct($db)
{
$this->db = $db;
}
public function getByName($name)
{
$result = array();
$sql = 'select id, name, age, address, pincode from json where name = :name';
if($stmt = $conn->prepare($sql))
{
$stmt->execute(array(":name" => $name));
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
}
return $result;
}
}
Usage:
require_once('/path/to/CustomerModel.php');
$conn = connect();
$model = new CustomerModel($conn);
$customers = $model->getByName('peter');
foreach($customers as $c)
{
echo htmlspecialchars($c['name']) . '<br />;
}