prepared statement causing while loop error - php

I have the following simple mysqli php application, which should work fine. $pk is accepted perfectly and is a valid ARTICLE_NO, and the query works perfectly when executed directly by mysql. I have put output statements after every event and all except tetsing while executes. The while loop is never entered, and I am unsure why.
edit: I have narrowed the problem down to the fact that 0 rows are returned, but I have no idea why as the same query in phpmyadmin gives the right result.
edit2: if I get rid of the while loop and just have
if (!$getRecords->fetch()) {
printf("<p>ErrorNumber: %d\n", $getRecords->errno);
}
It shows that the errno is 0. So no records are fetched, and there is no error, yet it is a valid query.
<?php
ini_set('display_errors', '1');
error_reporting(E_ALL);
$pk = $_GET["pk"];
$con = mysqli_connect("localhost", "", "", "");
if (!$con) {
echo "Can't connect to MySQL Server. Errorcode: %s\n". mysqli_connect_error();
exit;
}
$con->set_charset("utf8");
echo "test outside loop";
if(1 < 2) {
echo "test inside loop";
$query1 = 'SELECT ARTICLE_NO FROM AUCTIONS WHERE ARTICLE_NO = ?';
if ($getRecords = $con->prepare($query1)) {
echo "inside second loop";
$getRecords->bind_param("i", $pk);
echo "test after bind param";
$getRecords->execute();
echo "test after bind execute";
$getRecords->bind_result($ARTICLE_NO);
echo "test after bind result";
while ($getRecords->fetch()) {
echo "test inside while";
echo "<h1>".$ARTICLE_NO."</h1>";
}
}
}
edit:
I tried with this code:
<?php
$mysqli = new mysqli("localhost", "", "", "");
$pk = $_GET["pk"];
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
/* prepare statement */
if ($stmt = $mysqli->prepare("SELECT ARTICLE_NAME, WATCH FROM AUCTIONS WHERE ARTICLE_NO = ? LIMIT 5")) {
$stmt->bind_param("i", $pk);
$stmt->execute();
/* bind variables to prepared statement */
$stmt->bind_result($col1, $col2);
/* fetch values */
while ($stmt->fetch()) {
printf("%s %s\n", $col1, $col2);
}
/* close statement */
$stmt->close();
}
/* close connection */
$mysqli->close();
?>
This works without $pk, if I take away the parameters it works fine. It is not a problem with getting pk via GET, because if I assign $pk = 1; instead it still fails. 1 is a valid ARTICLE_NO, and SELECT ARTICLE_NAME, WATCH FROM AUCTIONS WHERE ARTICLE_NO = 1 LIMIT 5 works fine in phmyadmin.
edit: the problem was that mysqli could not handle bigint, I am now using k as a string and it works fine.

Check the value of:
$getRecords->num_rows
which should help reveal whether the earlier SELECT is actually returning any data
You may need to also add:
$getRecords->store_result()
first to ensure that you've the whole query has completed before asking for the number of rows in the result set.
Also - make sure you cast $pk to an integer! It's possible that the value being passed in is getting mangled.

I'm not sure if you've modified that code, but you don't seem to be selecting the database you want to connect to there.
Use mysqli_select_db(...) for that if that is the problem.
EDIT: It also looks like you're using uppercase for the column, table name etc.
Get case sensitivity right, it could be that you're presuming case insensitivity because it works from the command line. As far as I know the mysqlI driver in PHP is case sensitive about at least column names.

Related

How to query my table if there is an apostrophe in search term?

How can I search for a name in my table if there is an apostrophe in the name?
If I insert name with an apostrophe like Ender's Game in my search box, it gives an error.
I already tried solutions provided on stackoverflow, but I am not able to solve this.
Here is my code:
$string1 = $_GET['name'];
$quer = "SELECT * FROM info WHERE name = '$string1'";
$q = mysqli_query($conn, $quer);
If there is an apostrophe in $_GET['name'], an error is shown.
How can I solve this?
Code in that form is vulnerable to SQL injection. Use mysqli::prepare instead:
$string1 = $_GET['name'];
$quer = "SELECT * FROM info WHERE name = ?";
$stmt = $conn->prepare($quer);
$stmt->bind_param('s', $string1);
$stmt->execute();
$stmt->bind_result($result);
$stmt->fetch();
$stmt->close();
var_export($result);
If you're adapting legacy, insecure code, it may be faster to use mysqli_real_escape_string. This should be reserved as a last resort, but it's there if you need it, and it's better than a regex.
The best practice that you can expect to hear over and over again from knowledgeable StackOverflow volunteers is to use prepared statements to ensure query security and reliability.
For your case, I recommend the following snippet which not only safely executes your SELECT query, but also provides informative diagnostic/debugging checkpoints throughout the process and allows you to process the resultset - represented by an multi-dimensional associative array.
$_GET['name'] = "vinay's name";
$string1 = $_GET['name'];
if (!$conn = new mysqli("host", "user", "pass", "db")) {
echo "Database Connection Error: " , $conn->connect_error; // do not show this to public
} elseif (!$stmt = $conn->prepare("SELECT * FROM info WHERE name = ?")) {
echo "Prepare Syntax Error: " , $conn->error; // do not show this to public
} elseif (!$stmt->bind_param("s", $string1) || !$stmt->execute()) {
echo "Statement Error: " , $stmt->error; // do not show this to public
}else{
$result = $stmt->get_result();
while($row = $result->fetch_array(MYSQLI_ASSOC)){
var_export($row); // do what you like here
}
}
It is important to note that using $stmt->bind_result($result) (like in Zenexer's answer) will not work (generates $result = NULL) if the info table contains more than one column (I assume it will work with one column, but I didn't test); and it will generate a Warning because of an imbalance between the number of selected columns from SELECT * and the number of nominated variables.
Warning: mysqli_stmt::bind_result(): Number of bind variables doesn't match number of fields in prepared statement
If you want to enjoy the benefits of explicitly binding a result variable, you should specify your desired columns in the SELECT clause like this:
if (!$conn = new mysqli("host", "user", "pass", "db")) {
echo "Database Connection Error: " , $conn->connect_error; // do not show this to public
} elseif (!$stmt = $conn->prepare("SELECT id FROM info WHERE name = ?")) {
echo "Prepare Syntax Error: " , $conn->error; // do not show this to public
} else {
if (!$stmt->bind_param("s", $string1) || !$stmt->execute() || !$stmt->bind_result($id)) {
echo "Statement Error: " , $stmt->error; // do not show this to public
} else {
while ($stmt->fetch()) {
echo "<div>$id</div>";
}
}
$stmt->close();
}

How to select a column for a MySQL table and compare it with a PHP variable

I am trying to compare a MySQL table column which I have imported to my script and compare it with a PHP value which I have defined.
I am trying to make an if loop that checks if any of the values in the column are equal to the variable.
// Connect to database containing order information
$servername = "server";
$username = "user";
$password = "pass";
// Create connection
$conn = new mysqli($servername,$username,$password);
// Check connection
if ($conn->connect_error)
{
die("Connection failed: " . $conn->connect_error);
}
// define variables and set to empty values
$name = $ordernumber = "";
// Load up data from the form
$ordernumber = ($_POST['order_number']);
// Get SQL info
$sql = "SELECT order_number FROM p_orders;";
if ($conn->query($sql) === TRUE)
{
echo "Checked Orders.....";
}
else
{
echo "Failed to check orders, please contact Support for assistance" . $conn->error;
}
// Checking Script
if ($ordernumber === $orders)
{
echo "Order Number Found.... Let's Select a Seat";
}
else
{
echo "Your Order was not found, either you did not order a reservation ticket, have not waited 3 days or you entered the number wrong. If issues persist then please contact Support."
};
The end part of the script should be like this...
$stmt = $mysqli->stmt_init();
if ($stmt->prepare('SELECT order_number FROM p_orders WHERE orderID = ?')) {
$stmt->bind_param('s',$_POST['order_number']); // i if order number is int
$stmt->execute();
$stmt->bind_result($order_number);
$stmt->fetch();
if (!empty($order_number))
echo "Order Number Found.... Let's Select a Seat";
}else {
echo "Your Order was not found...";
}
$stmt->close();
}
$mysqli->close();
...note that the query now looks for only the records that match and note the use of prepared statement to make safe the post variable from SQL Injection.
The reason to collect only the matching items from SQL is otherwise, if you have a million records, the database would return all of them and then PHP will need to loop through them (this can cause maximum execution, memory and other errors). Instead databases where built to look things up like this - note an index on this field would be good and also use of a "youtube style" id is recommended, which is why I've assumed the use of a string for it's instead of a number as the variable minght imply - and it's not the "id" which is good for a number of reasons... I've added a link to explain "youtube style" id which I'll not go into detail here but there is a lot of win in using that :)
UPDATED based on...
http://php.net/manual/en/mysqli-stmt.prepare.php
MySQL prepared statement vs normal query. Gains & Losses
https://www.youtube.com/watch?v=gocwRvLhDf8 (Will YouTube Ever Run Out Of Video IDs?)
Preferably use a WHERE clause searching for the order id and mysqli prepared statement, like below.
$mysqli = new mysqli("localhost", "my_user", "my_password", "my_db");
/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$name = "";
// Load up data from the form
$ordernumber = $_POST['order_number'];
/* create a prepared statement */
if ($stmt = $mysqli->prepare("SELECT COUNT(*) FROM p_orders WHERE orderID=?")) {
/* bind parameters for markers */
$stmt->bind_param("i", $ordernumber ); // "i" if order number is integer, "s" if string
/* execute query */
$stmt->execute();
/* bind result variables */
$stmt->bind_result($counter);
/* fetch value */
$stmt->fetch();
if ($counter>0) { // if order id is in array or id's
echo "Order Number Found.... Let's Select a Seat";
} else {
echo "Your Order was not found, either you did not order a reservation ticket, have not waited 3 days or you entered the number wrong. If issues persist then please contact Support."
}
/* close statement */
$stmt->close();
}
/* close connection */
$mysqli->close();

MySQL Row Isn't Found But It's There

I'm using PHP to try and select a single row from a table in my MySQL database. I've run the query manually inside phpMyAdmin4 and it returned the expected results. However, when I run the EXACT same query in PHP, it's returning nothing.
$query = "SELECT * FROM characters WHERE username=".$username." and charactername=".$characterName."";
if($result = $mysqli->query($query))
{
while($row = $result->fetch_row())
{
echo $row[0];
}
$result->close();
}
else
echo "No results for username ".$username." for character ".$characterName.".";
And when I test this in browser I get the "No results..." echoed back. Am I doing something wrong?
This isn't a duplicate question because I'm not asking when to use certain quotes and backticks. I'm asking for help on why my query isn't working. Quotes just happened to be incorrect, but even when corrected the problem isn't solved. Below is the edited code as well as the rest of it. I have removed my server information for obvious reasons.
<?PHP
$username = $_GET['username'];
$characterName = $_GET['characterName'];
$mysqli = new mysqli("REDACTED","REDACTED","REDACTED");
if(mysqli_connect_errno())
{
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$query = "SELECT * FROM `characters` WHERE `username`='".$username."' and `charactername`='".$characterName."'";
if($result = $mysqli->query($query))
{
while($row = $result->fetch_row())
{
echo $row[0];
}
$result->close();
}
else
echo "No results for username ".$username." for character ".$characterName.".";
$mysqli->close();
?>
It's failing: $mysqli = new mysqli("REDACTED","REDACTED","REDACTED"); because you didn't choose a database.
Connecting to a database using the MySQLi API requires 4 parameters:
http://php.net/manual/en/function.mysqli-connect.php
If your password isn't required, you still need an (empty) parameter for it.
I.e.: $mysqli = new mysqli("host","user", "", "db");
Plus, as noted.
Your present code is open to SQL injection. Use mysqli_* with prepared statements, or PDO with prepared statements.
Footnotes:
As stated in the original post. Strings require to be quoted in values.
You need to add quotes to the strings in your query:
$query = "SELECT *
FROM characters
WHERE username='".$username."' and charactername='".$characterName."'";

PHP, MYSQLi query results not working with with WHERE using $_GET

I am trying to get the results of a SQL query using WHERE, whenever I use the $_GET variable it doesn't work, now I have echoed the $query variable and it shows the value of $_GET['idced'] but for some reason it doesn't do the query thus the loop doesn't show anything.
But when I manually type in the value that I want to compare, it works perfectly fine... any help would be greatly appreciated.. I also know that their might be some security issues with using GET but its a local app so it's not a concern.. heere is the code I have:
<?php
$mysqli = new mysqli("localhost", "cx", "", "cxtrack");
/* check connection */
if ($mysqli->connect_errno) {
printf("Connect failed: %s\n", $mysqli->connect_error);
exit();
}
$idced_history = mysqli_real_escape_string($mysqli, $_GET['idced']);
//This is the query that is not working:
$query = "SELECT * FROM applications WHERE idced = $idced_history;";
if ($result = $mysqli->query($query)) {
//This loop works fine when I replace $idced_history with a value of idced
while ($row = $result->fetch_assoc()) {
$curenttime=$row["applicationposition"];
$time_ago =strtotime($curenttime);
echo "<div style='background:red; position:relative; top:2.6em; margin-bottom:1%;'>";
echo "<a href='#'>".$row["applicationposition"]."</a><br/>";
echo "Applied On: ".$row["applicationdate"]." ( ". timeAgo($time_ago) ." ) <br>";
echo "Via: ".$row["applicationtype"]."</div>";
}
$result->free();
}
$mysqli->close();
?>
sometime it not work that way.. try change to:
$query = "SELECT * FROM applications WHERE idced = ".$idced_history;
It didn't work because, idced you get from url is a string and you should spare strings from the sql query with single quotes. Otherwise, mysql act like to your variable as a table name.
try
"SELECT * FROM applications WHERE idced = '$idced_history'";

Learning SELECT FROM WHERE prepared statements

Can someone re-write the below code as a prepared statement?
result = mysqli_query($con,"SELECT * FROM note_system WHERE note = '$cnote'")
or die("Error: ".mysqli_error($con));
while($row = mysqli_fetch_array($result))
{
$nid = $row['id'];
}
I am trying to learn prepared statements and am having trouble understanding how it works from the many examples I have found while searching. I am hoping that if I see some code I am familiar with re-written as a prepared statement that it might click for me. Please no PDO, that is too confusing for me at my current level of knowledge. Thanks.
Hello ButterDog let me walk you through PDO step by step.
Step 1)
create a file called connect.php (or what ever you want). This file will be required in each php file that requires database interactions.
Lets start also please note my comments :
?php
//We set up our database configuration
$username="xxxxx"; // Mysql username
$password="xxxxx"; // Mysql password
// Connect to server via PHP Data Object
$dbh = new PDO("mysql:host=xxxxx;dbname=xxxxx", $username, $password); // Construct the PDO variable using $dbh
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // Set attributes for error reporting very IMPORTANT!
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, FALSE); // Set this to false so you can allow the actual PDO driver to do all the work, further adding abstraction to your data interactions.
?>
Step 2) Require the connect.php please take a look :
require ('....../........./...../connect.php'); // Require the connect script that made your PDO variable $dbh
Step 3)
to start database interactions just do the following also please read the code comments. For the moment we will not worry about arrays! Get the full gyst of PDO then worry about making it easier to work with! With repetition the "long way" comes more understanding of the code. Do not cut corners to begin with, cut them once you understand what you are doing!
$query = $dbh->prepare("SELECT * FROM note_system WHERE note = :cnote"); // This will call the variable $dbh in the required file setting up your database connection and also preparing the query!
$query->bindParam(':cnote', $cnote); // This is the bread and butter of PDO named binding, this is one of the biggest selling points of PDO! Please remember that now this step will take what ever variable ($cnote) and relate that to (:cnote)
$query->execute(); // This will then take what ever $query is execute aka run a query against the database
$row = $query->fetch(PDO::FETCH_ASSOC); // Use a simple fetch and store the variables in a array
echo $row['yourvalue']; // This will take the variable above (which is a array) and call on 'yourvalue' and then echo it.
Thats all there is to PDO. Hope that helped!
Also take a look at this. That helped me so so much!
I also use this as a reference (sometimes) - The web site looks like crap but there is quality information on PDO on there. I also use this and I swear this is the last link! So after this any questions just ask, but hopefully this can turn into a little reference guide on PDO. (hopefully lol)
Use pdo:
http://php.net/manual/en/book.pdo.php
from various docs:
/* Connect to an ODBC database using driver invocation */
$dsn = 'mysql:dbname=testdb;host=127.0.0.1';
$user = 'dbuser';
$password = 'dbpass';
try {
$dbh = new PDO($dsn, $user, $password);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
$sql = 'SELECT name, colour, calories
FROM fruit
WHERE calories < :calories AND colour = :colour';
$sth = $dbh->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
$sth->execute(array(':calories' => 150, ':colour' => 'red'));
$red = $sth->fetchAll();
This is one way to do it with PDO:
$sel = $db->prepare("SELECT * FROM note_system WHERE note=:note");
$sel->execute(array(':note' => $_POST['note']));
$notes = $sel->fetchAll(PDO::FETCH_ASSOC);
See the placeholder :note in the query in line 1, which is bound to $_POST['note'] (or any other variable for that matter) in line 2.
If I want to run that query again, with a different value as :note, I'll just call lines 2 and 3.
Displaying the results:
foreach ($notes as $note) {
echo $note['id'] . ": " . $note['text'] . "<br />";
}
This should help you on the right path...
$link = mysqli_connect("localhost", "my_user", "my_password", "world");
/* check connection */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$query = "SELECT id FROM note_system WHERE note = ?";
$stmt = mysqli_stmt_init($link);
if(!mysqli_stmt_prepare($stmt, $query)) {
print "Failed to prepare statement\n";
}
else {
$note = "mynote";
mysqli_stmt_bind_param($stmt, "s", $note);
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);
while ($row = mysqli_fetch_array($result))
{
$nid = $row['id'];
}
}
mysqli_stmt_close($stmt);
mysqli_close($link);

Categories