I'm trying to figure out why a mysqli parepared statement is not working. I can say the page have something like 2 sections, the first one needs $_GET to be empty and the last one needs $_GET['id'] and other to be set (isset). Both "sections" have the same query but in the last section there's a different query first.
Everyting is working fine until the repeated query in the last "section", where nothing is printed.
I have something like this:
if (login_check($mysqli) == true) {
if(empty($_GET)) { //first section
if ($stmt = $mysqli->prepare("SELECT friends.*, members.*, account_type.* FROM friends INNER JOIN members ON members.id = friends.friendID
INNER JOIN account_type ON account_type.name = members.acc_type
WHERE friends.userID = ? AND members.acc_type = ?")) {
$stmt->bind_param('is', $_SESSION['user_id'], $_SESSION['acc_type']);
$stmt->execute();
} else echo $mysqli->error;
$result = $stmt->get_result();
// php/mysqli stuff working as expected ($row[] printing db data)
// no need to close
}
if(isset($_GET['id'], $_SESSION['user_id'])) { // last section
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
/* prepare statement */
if ($stmt = $mysqli->prepare("SELECT COUNT(*) rowCount FROM friends WHERE friendID = ? AND userID = ?")) {
$stmt->bind_param('ii', $_GET['id'], $_SESSION['user_id']);
$stmt->execute();
/* bind variables to prepared statement */
$stmt->bind_result($rowCount);
/* fetch values */
if($stmt->fetch()) {
if ($rowCount > 0) { // This check is working fine, I tested.
$stmt->close(); // close here so no "non-object" error
$stmt = $mysqli->prepare("SELECT friends.*, members.*, account_type.* FROM friends INNER JOIN members ON members.id = friends.friendID
INNER JOIN account_type ON account_type.name = members.acc_type
WHERE friends.friendID = ? AND members.acc_type = ?");
$stmt->bind_param('is', $_GET['id'], $_SESSION['acc_type']);
$stmt->execute();
$result = $stmt->get_result();
$row = $result->fetch_array();
// Here I have some $row['columns'] and nothing is printed.
} else{
echo $_SESSION['username'], ', you are not allowed to be here.';
}
}
/* close statement */
$stmt->close();
}
/* close connection */
$mysqli->close();
}
} else {
echo 'Please, log in.';
}
The first query is working fine, the other is a copy/paste.
I don't see where the problem is :(
Thanks!
Edit: sorry the second query should be "WHERE friends.friendID".
for ($i = 1; $i < 13; $i++) {
$month = $row['month' . $i];
if($row[$month] == 1) {
$paid[] = 'Paid';
} else {
$paid[] = 'Not Paid';
}
$bonus = $row['bonus'];
}
The problem is members.monthx and friends.monthx have the same name, but they are not meant to have the same values so I don't know from what table is getting $row['month' . $i]. The value should be taken from friends.monthx. How do I specify that?
Related
When the search matches all displays perfectly. But when there is no match the no result message does not display. Please any insight on this one. Thanks upfront
$result = "SELECT T1.ID, T2.Image1, T1.unoone, T1.unotwo, T1.unothree,
T1.unofour
FROM T1 LEFT JOIN T2 ON (T1.ID=T2.Image1)
WHERE T1.ID=T2.Image1 AND T1.unoone LIKE '%".$uno_one."%'
AND T1.unotwo LIKE '%".$uno_two."%'
AND T1.unothree LIKE '%".$uno_three."%'
AND T1.unofour LIKE '%".$uno_four."%' ";
$stmt = mysqli_stmt_init($con);
$query = mysqli_stmt_prepare($stmt, $result);
if(!$query) {
die("no result");
} else {
/* execute statement */
mysqli_stmt_execute($stmt);
/* bind result variables */
mysqli_stmt_bind_result($stmt, $id, $img[0], $uno_one, $uno_two,
$uno_three, $uno_four);
/* fetch values */
while (mysqli_stmt_fetch($stmt)) {
echo $img[0];
echo $uno_one;
echo $uno_two;
echo $uno_three;
echo $uno_four;
}
/* close statement */
mysqli_stmt_close($stmt);
}
As Madan Sapkota said : "if(!$query) { only check if any error exists".
You need to use a function for counting results, like mysqli_stmt_num_rows():
if(mysqli_stmt_num_rows ( $stmt ) == 0 ){ echo "there is no result";}
// The while loop after won't be run when no result are found, no need to put an else here.
while (mysqli_stmt_fetch($stmt)) {
...
}
I've made the following script that shows blogposts. $_MULT[0] shows 'blog', $_MULT[1] shows the ID of the blogpost.
I'm wondering:
1) Is this script safe for SQL injection?
2) What if I removed ctype_digit() ? Would it still be safe then?
<?php
error_reporting(E_ALL);
$db = new PDO('mysql:host=localhost;dbname=blablabla','blablabla','passwd');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
echo '<h2>Blog</h2>';
$iTijd = time();
$_MULT = explode("/", $_GET['p']);
if($_MULT[0] == 'blog' AND isset($_MULT[1]))
{
if(ctype_digit($_MULT[1]))
{
// query
$sql = "SELECT Titel, Post, Datum FROM Blog WHERE Id = :Id AND Status = :Status AND Datum < :Tijd LIMIT 1";
// prepare query
$stmt = $db->prepare($sql);
// bind values
$stmt->bindParam(':Id', $a=$_MULT[1], PDO::PARAM_INT);
$stmt->bindParam(':Status', $a='1', PDO::PARAM_INT);
$stmt->bindParam(':Tijd', $a=$iTijd, PDO::PARAM_INT);
// execute query
$stmt->execute();
// select data from db
$aRow = $stmt->fetch(PDO::FETCH_ASSOC);
// show blogpost
echo '<h4>'. $aRow['Titel'] .'</h4><br />';
$datum = $aRow['Datum'];
$datum = date("d-m-Y", $datum);
echo '<i>'. $datum.'</i> - '. $aRow['Post'];
}
else
{
echo "<h2>404 - Pagina niet gevonden</h2>";
}
}
else
{
// query
$sql = "SELECT Id, Titel FROM Blog WHERE Status = :Status AND Datum < :Tijd ORDER BY Id DESC LIMIT 10";
// prepare query
$stmt = $db->prepare($sql);
// bind values
$stmt->bindParam(':Status', $a='1', PDO::PARAM_INT);
$stmt->bindParam(':Tijd', $a=$iTijd, PDO::PARAM_INT);
// execute query
$stmt->execute();
echo '<br /><ul>';
// select data from db
while($aRow = $stmt->fetch(PDO::FETCH_ASSOC))
{
echo '<h4><li>'. $aRow['Titel'] .'</li>
</h4>';
}
echo '</ul>';
if($stmt->rowCount() == 0)
{
echo '<p>Er zijn nog geen blogposts toegevoegd.</p>';
}
}
?>
Is that safe? And what should I do with this? Just leave it?
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
Strange code, but if You want use it change if statement to:
if($_MULT[0] == 'blog' && ! empty($_MULT[1])) { ... }
if(ctype_digit( (string) $_MULT[1])) { ... }
Here is my code.. It doesn't give me an error whale binding, but it will not display anything even though there is more than one row that meets the select statements criteria
$sql = 'SELECT reply_content FROM ticket_replies WHERE reply_id = ? ORDER BY reply_order ASC';
$stmt2 = $mysqli->prepare($sql);
if($stmt2 === false) {
trigger_error('Wrong SQL: ' . $sql . ' Error: ' . $mysqli->error, E_USER_ERROR);
}
$stmt2->bind_param('i', $loggedInUser->user_id);
$stmt2->execute();
$stmt2->store_result();
$stmt2->bind_result($reply_content1);
$stmt2->fetch();
if($stmt2->num_rows > 0) {
while ($stmt2 ->fetch()) {
echo $reply_content1;
}
}
$stmt2->close();
You are fetching twice, try commenting out the first one
//$stmt2->fetch();
if($stmt2->num_rows > 0) {
while ($stmt2 ->fetch()) {
...
The way you have it now will move the cursor one more time. But you have only one record, that's why you don't see anyting.
I have this MYSQL Table :
id | action
A6bIMWP1rQ changedusername
A6bIMWP1rQ changedusername
Now how i make this php function to count if more then 5 times changedusername exsit, it will return false?
i have tryed:
function checkIfOverFive($id,$mysqli) {
global $func; //The database connection
if ($stmt = $mysqli->prepare("SELECT action FROM userchange_attemps WHERE user_id = ?")) {
$stmt->bind_param('i', $id);
// Execute the prepared query.
$stmt->execute();
$stmt->store_result();
// If there has been more than 5 failed logins
if($stmt->num_rows > 5) {
return true;
}else{
return false;
}
}
}
And how with php i determine how much left attemps upto 5 ?
Lets say now in my table theres 2 rows, and left 3 , how i return that value to the user ?
Thanks.
Use mysql COUNT
function checkIfOverFive($id,$mysqli) {
global $func; //The database connection
if ($stmt = $mysqli->prepare("SELECT COUNT(id) as count FROM userchange_attemps WHERE user_id = ? AND action = 'changedusername'")) {
$stmt->bind_param('i', $id);
// Execute the prepared query.
$stmt->execute();
$stmt->store_result();
$row = $stmt->fetch_assoc();
if($row['count'] > 5) {
//do something
} else {
//do something else
}
}
}
How about...
SELECT COUNT(action)
FROM userchange_attemps
WHERE action = 'changedusername' AND user_id= ?
How to put PDO bindParam in if statement? I tried to do a different variations, but none of them worked.
function get_all_pages($subject_id, $public = true)
{
$db = new PDO('mysql:host=localhost;dbname=name;charset=utf8', 'root', 'whatewer');
$query = "SELECT * ";
$query.= "FROM pages ";
$query.= "WHERE subject_id =:id ";
if ($public)
{
$query.= " AND visible =:visible ";
}
$query.= "ORDER BY position ASC";
$query.= "ORDER BY position ASC";
$stmt = $db->prepare($query);
if ($public)
{
$stmt->bindParam(':id', $subject_id, PDO::PARAM_INT);
$stmt->bindValue(':visile', 2, PDO::PARAM_INT);
}
else
{
$stmt->bindParam(':id', $subject_id, PDO::PARAM_INT);
}
$stmt->execute();
$affected_rows = $stmt->rowCount();
if ($affected_rows == 1)
{
$subject = $stmt->fetch(PDO::FETCH_ASSOC);
return $subject;
}
}
else
{
return null;
}
}
Ok there was misunderstanding I got my cod "Wright" it was stackoverflow that messed my code up. i was struggling to put code in code area. In reality it looks like this.
http://imagizer.imageshack.us/v2/800x600q90/593/zvf8.png
$affected_rows = $stmt->rowCount(); might give you unexpected results as according to the manual:
For most databases, PDOStatement::rowCount() does not return the
number of rows affected by a SELECT statement.
You should fetch a row directly and see what the result is:
$stmt->execute();
if ($subject = $stmt->fetch(PDO::FETCH_ASSOC))
{
return $subject;
}
else
{
return null;
}
And I would recommend opening your database connection as I mentioned in my comment:
$db = new PDO('mysql:host=localhost;dbname=name;charset=utf8', 'root',
'whatewer', array(PDO::ATTR_ERRMODE => PDO::ERRMODE_WARNING));
That will cause PDO to throw exceptions and that will give you a clear error message whenever something goes wrong on any of the db calls.