PDO returns empty array as result - php

I have a simple search form, which I use to send a POST request to my php script using AJAX. I want the script to search my database for the keyword in the title column, and return the rows where it finds it. The posted data looks like this "searchword=test1", where test1 in the content of my text input.
I have 2 rows in my database, one has a title of test1, and another of test2. If I do SELECT * FROM articles I can see the results fine. If I type SELECT * FROM articles WHERE title LIKE 'test1'; into console, I get the correct result, but my php script returns an empty array.
No idea what I'm doing wrong here, any help is appreciated.
my php:
try {
$hostname = "localhost";
$username = "root";
$password = "";
$db = new PDO("mysql:host=$hostname;dbname=topdecka_PTC",$username, $password);
if (!empty($_POST["searchword"])) {
$searchword = $_POST["searchword"];
$query = $db->prepare("SELECT * FROM articles WHERE title LIKE %:seachword%");
$query->execute(array(':searchword' => $searchword));
$result = $query->fetchAll(PDO::FETCH_ASSOC);
echo json_encode($result);
die();
}
else {
$query = $db->prepare('SELECT * FROM articles');
$query->execute();
$result = $query->fetchAll(PDO::FETCH_ASSOC);
echo json_encode($result);
die();
}
} catch (PDOException $e) {
echo "Error!: " . $e->getMessage() . "<br/>";
die();
}

Firstly, you forgot the $ sign for %:seachword% as per your assignment:
Sidenote: There's a typo that I just noticed in seachword which should read as searchword as per ':searchword' => $searchword
$searchword = $_POST["searchword"];
However, I'd do something like this instead:
LIKE :seachword
then
$query->execute(array(":searchword" => "%" . $searchword . "%"));
Example syntax:
$sqlprep = $conn->prepare("SELECT `column` FROM `table` WHERE `column` LIKE :word");
$sqlprep->bindValue(':word', '%value%');
Also make sure that your form does have a POST method and that your element is indeed named and no typos.
Add error reporting to the top of your file(s) which will help find errors.
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
// rest of your code
Sidenote: Error reporting should only be done in staging, and never production.
Add $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); right after the connection is opened, to catch potential errors, if any.

The reason it isn't working is because the value for :searchname is being escaped. As a result,
SELECT * FROM articles WHERE title LIKE %:seachword%
is being interpreted as this:
SELECT * FROM articles WHERE title LIKE %"test1"%
which is an invalid query. You need to quote the entire string or use concat() to add the % in.
Your two options are:
$query = $db->prepare("SELECT * FROM articles WHERE title LIKE :seachword");
$query->execute(array(':searchword' => "%" . $searchword . "%"));
or:
$query = $db->prepare("SELECT * FROM articles WHERE title LIKE CONCAT('%', :seachword, '%')");
$query->execute(array(':searchword' => $searchword));
Personally, I prefer the option with CONCAT as it separates responsibilities better, in my opinion.

Related

PHP - Passing pdo connection query via php function

So i'm trying to pass PDO Query by using php, like this(index.php):
include("dbconn.php");
mysqlConnect("'SELECT * FROM users WHERE name =' . $conn->quote($name))", "jeff");
while my dbconn file that contains the function is(dbconn.php):
function mysqlConnect($queryString, $name) {
// DB Credentials
$dbName = 'db';
$dbUser = 'root';
$dbPass = '';
$dbHost = 'localhost';
try {
$conn = new PDO("mysql:host=$dbHost;dbname=$dbName", $dbUser, $dbPass);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// Here goes the first parameter, then it uses the second parameter as a variable
$data = $conn->query($queryString);
// So the output should be this:
// $data = $conn->query('SELECT * FROM myTable WHERE name = ' . $conn->quote($name));
foreach($data as $row) {
print_r($row);
}
} catch(PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
}
}
So in my function call the php actually executes the $conn->quote($name)) code, making my application not work.
How should i do this? is this allowed in php?
Edit:
or in other words: i call a function and give it 2 parameters, one of the parameters(even tho it's in double quotes) is executed by php which shouldn't happen. How can i fix this
The way you wrote, it will never work. You just have to learn to distinguish a string literal from executable code.
Anyways, you don't need such a frankenstein at all. There is already a mechanism to put your variable in the query, called prepared statements. You just have to use them.
There are other issues with your code too. I've described them all in the article I wrote recently, The only proper guide on PDO, I am sure you will find it interesting - all the issues like wrong error handling, utterly wrong way to connect, lack of prepared statements - all described there. Having all of them solved, here goes the proper function you need:
function pdo($sql, $data=[])
{
global $pdo; // you can add a call to your favorite IoC here.
$stmt = $pdo->prepare($sql);
$stmt->execute($data);
return $stmt;
}
used as
include("dbconn.php");
$user = pdo("SELECT * FROM users WHERE name = ?", ["jeff"])->fetch();
var_dump($user);
this is how PDO have to be used.
By returning a statement, you'll be able to use all the power of PDO, getting data you need in one line, say a list
$news = pdo("SELECT * FROM news ORDER BY id DESC")->fetchAll();
var_dump($news); // already an array
or just a single value
$count = pdo("SELECT count(*) FROM posts WHERE author=?", [$id])->fetchColumn();
var_dump($count); // already a number
or simply by iterating results one by one
$news = pdo("SELECT * FROM news ORDER BY id DESC")->fetchAll();
foreach ($news as $row) {
var_dump($row);
}
and so on.

simple php search code not returning and results

I am trying to get a simple php search script to work. It currently captures the data from an html and stores it in $input. The problem is that I keep getting no results from the script below. there are no error messages at all though. I know the database has the exact match data in it, but I keep getting the message from my code below for when there is no data. Is something wrong with my SQL?
<?php
//declaring variable
$input = $_POST['find'];
//If they did not enter a search term we give them an error
if ($input == "") {
echo "You forgot to enter a search term";
exit;
}
//open connection
$dbh->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING );
//the sql statement
$results = $dbh->prepare("select
wp_users.ID,
wp_users.display_name,
stories.SID,
stories.story_name,
stories.category,
stories.genre
FROM stories
LEFT JOIN wp_users ON stories.ID=wp_users.ID
WHERE stories.story_name = '$input' OR stories.genre = '$input'");
$results->execute();
$row = $results->fetchAll(PDO::FETCH_ASSOC);
//giving names to the fields
$storyname = $row['story_name'];
$category = $row['category'];
$genre = $row['genre'];
//put the results on the screen
echo "<b>$storyname</b>";
echo "$categoy";
echo "$genre<br>";
//This counts the number or results – and if there wasn’t any it gives a
little message explaining that
$anymatches=$row;
if ($anymatches == 0)
{
echo "<h3>Results</h3>";
echo "<p>Sorry, your search: "" . $input . "" returned zero
results</p>";
}
?>
$results = $dbh->prepare("select
wp_users.ID,
wp_users.display_name,
news.SID,
news.story_name,
news.genre
FROM stories
LEFT JOIN wp_users ON news.ID=wp_users.ID
WHERE news.story_name = $input OR news.genre = $input");
Basically, when writing these queries you need to enclose strings in quotes. Right now, your query would contain
news.story_name=Five Cats Go Missing
You need it to be
news.story_name='Five Cats Go Missing'
Enclose it in quotes news.story_name='$input' and so on.
First and foremost, since you are using PDO, bind your variables. I believe you are vulnerable to SQL injection at the moment. Second turn on your PDO error message, and PHP error messages if you don't have them on. #Ghost suggested how to turn on your error reporting for PDO, and you can user <?php error_reporting(-1) ?> for PHP reporting.
Refer to these links for more details on error reporting:
PHP Error Reporting: http://php.net/manual/en/function.error-reporting.php
PDO Error Reporting: http://php.net/manual/en/pdo.errorinfo.php
I also you can check the return value of the $results->execute();. If there is nothing wrong with your SQL query statement, that should return true, with not it will return false, thus there is something wrong with your SQL.

MySQL like query not working?

I have a successful connection made in PDO to my MySQL database and I am currently trying to get it to query the database for itmes LIKE the search query.
<?php
include ('connection.php');
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";
global $conn;
$stmt = $conn->prepare($sql);
$stmt->bindParam(":searchq",$searchq,PDO::PARAM_STR);
$stmt->execute();
$count = $stmt->rowCount();
if($count == 0) {
$output = 'No results found, buddy.';
} 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 am struggling to get it to search. Unless the query exactly matches only the name, it doesn't show any results.
The LIKE operator does not do partial matches unless specifically instructed to. Perhaps you meant to prepend/append a % wildcard symbol to the search string:
$searchq = '%' . $searchq . '%';
I don't see anything wrong in the SQL text of the query.
The simplest explanation is that the SQL you are expecting to be sent to the database isn't what is being sent.
I suggest you give this a try:
use unique bind variable names in the statement, use each bind variable only once.
There used to be a bug in PDO with named bind variables (not sure if that's fixed of not. Under the covers, the named bind parameters were getting converted to positional notation, and when the same bind variable two or more times, the query being sent to MySQL wasn't what we expected.
For example:
$sql = "SELECT e.*
FROM entries e
WHERE e.name LIKE :searchq1
OR e.description LIKE :searchq2
OR e.content LIKE :searchq3";
$stmt = $conn->prepare($sql);
$stmt->bindParam(":searchq1",$searchq,PDO::PARAM_STR);
$stmt->bindParam(":searchq2",$searchq,PDO::PARAM_STR);
$stmt->bindParam(":searchq3",$searchq,PDO::PARAM_STR);
When we encountered the problem, we weren't using server side prepared statements, just regular client side prepares; the SQL sent to the server included literals, not placeholders. Turning on the general_log in MySQL allowed us to see the actual SQL statements that were being sent to the database.
You might be encountering the same problem. But I'd recommend this as a step in debugging the problem, at least to verify it isn't the problem.

How to use php variables inside SQL select statment

I want to get some data from sql server using php but the sql doesn't seem reading the php variable
<?php
$q = $_POST["fl"];
echo $foo;
if ($_POST["fl"] == true);
{
$conn1=odbc_connect('SQLDB','','');
if (!$conn1)
{exit("Connection Failed: " . $conn1);}
$sql1= "SELECT * FROM dbo.Audit WHERE Details = '$q'";
$rs1=odbc_exec($conn1,$sql1);
if (!$rs1)
{exit("Error in SQL");}
while (odbc_fetch_row($rs1))
The best way to do that is:
$stmt = odbc_prepare($conn1, "SELECT * FROM dbo.Audit WHERE Details = ?");
$success = odbc_execute($stmt, array(PDO::quote($_POST["fl"])));
You're testing for the presence of your $q incorrectly. You should have something more like:
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
if (isset($_POST['fl'])) {
$q = $_POST['fl'];
$sql = "SELECT ... WHERE Details = '$q'":
etc..
} else {
die("No fl value was passed");
}
}
Also note that I have not corrected your SQL injection vulnerability. Your code, even if it was working, is just begging to get your database trashed.
To avoid the apparent downvote party I'm not going to post any SQL, but yadda yadda SQL injection, yadda yadda input validation, etc.
Your problem is:
if ($_POST["fl"] == true); //<-- this semicolon, get rid of it
{
$conn1=odbc_connect('SQLDB','','');
Aside from that your code is syntactically fine, though you should be using if(isset($_POST['f1'])) in place of if ($_POST["fl"] == true).
You can use PDO object for making a select query to the database....
$q = $_POST['fl'];
$pdo=new PDO('mysql:host=localhost;dbname=databasename','username','password');
$query="select * from dbo.Audit WHERE Details = :q;";
$result=$pdo->prepare($query);
$result->bindValue(':q',$q);
$result->execute();
First things first, please sanitize the post before you put it inside an SQL query.
You have to use htmlentities or even better, PDO.
Second, you can try this if your current one doesn't work:
$sql1 = "SELECT * FROM dbo.Audit WHERE Details = '".$q."'";

mysql SELECT * WHERE value = $row['item']

What's the correct way to code the following
SELECT * FROM table WHERE value = $row['item']
$row['item'] echos correctly, but does not seem to work in the mysql query. Been having this problem for a few days. I've tried .$row['item']. and a few other variations but I must be doing something wrong.
The better more appropriate approach is to use mysqli and prepared statements ie:
$stmt = $mysqli->prepare("SELECT * FROM table WHERE value =?");
$stmt->bind_param("s",$row['item']); // I am assuming row['item'] is a string
$stmt->execute();
If you can't use mysqli or absolutely refuse to you can use this:
$query = "SELECT * FROM table WHERE value = '".mysql_real_escape_string($row['item'])."'";
The answer sort of depends on what is held within the $row['item'] variable. If it's a numeric value, then the query above should be fine. Since it's not working, I assume that the value of that variable is actually a string. In that case, you need to surround the value in quotes so that the database can correctly identify it as a string value (otherwise, it would just be gibberish "commands" that the database can't identify, causing the query to fail).
Regardless of the above, you shouldn't be directly inserting variables into a query under pretty much any circumstances. The reason is that it opens you up to SQL injection if you're not extremely careful. For example, if your $row['item'] variable was wrapped in single quotes in the query, but contained a single quote in its value, then the database would interpret the quote within the variable as the ending quote for the entire parameter, and it would screw up the query. Worse still, a hacker could take advantage of this to end your query entirely, then add a second query of his own making onto it (or they could introduce a UNION query on the end of the original, etc.). At the very least, you should be running something like mysql_real_escape_string() on the variable before using it:
$sql = "SELECT * FROM table WHERE value = " .
mysql_real_escape_string($row['item']);
The best way to get around this and secure your queries is to use prepared statements. These are queries that have placeholders in them instead of concatenated variables. You prepare the query with these placeholders, then you issue additional commands to the database to tell it what values to place in those placeholders. The database then takes care of the tricky issue of sanitizing these variables so that they don't cause any damage. You can use PDO for this:
try {
$dbh = new PDO(DB_DSN,
DB_USER,
DB_PASS,
array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION)
);
} catch (PDOException $e) {
echo "Connection failed: " . $e->getMessage();
exit();
}
// create query with a named placeholder
$sql = "SELECT * FROM table WHERE value = :value";
try {
$stmt = $dbh->prepare($sql);
// tell PDO to substitute the value in $row['item']
// for the named parameter specified above.
$stmt->bindValue(":value", $row['item']);
// execute the query and load the results into an array
$stmt->execute();
$records = $stmt->fetchAll();
} catch (PDOException $e) {
echo "Query failed: " . $e->getMessage();
exit();
}
foreach ($records as $record) {
// use db records
}
The way I usually recommend doing it is something like this:
$sql = sprintf("SELECT * FROM table WHERE value = '%s'",
mysql_real_escape_string($row['item']));
$item = mysql_real_escape_string($row['item']);
$mysqlQuery = "SELECT * FROM table WHERE value = '" . $item . "'";
you are missing single quotes
SELECT * FROM table WHERE value = '{$row['item']}'
PHP example

Categories