php unsuccessful while loop within prepared statements - php

code below is a part of my sitemap.xml file. My aim is to write the last modified date of my approved articles. There are 2 possibilities for this data.
If article has no approved comment, then lastmod is the approval
date of the article.
If article has at least 1 approved comment, then lastmod is the
approval date of the last approved comment.
Errors in my output are:
There are some articles in my db that has no comments but also these commentless articles get the approval date of last comment of some other articles. As a result since I have some comments which are approved today, all those commentless articles' lastmode is date of today. but these articles are quite old.
$newsql in my 2nd while loop prints "newstmt prepare error" on
screen, so if ($newstmt = $connection->prepare($newsql)) part doesn't work
Can you please correct me?
Thank you, best regards
code
<?php
//if spesific article is approved then its last modification date = approval date of article
//if spesific article has approved comment(s), then modification date = approval date of its last comment
$sql = "SELECT col_author, col_title, col_approvaldate FROM articles WHERE col_status = ? ORDER by col_approvaldate DESC";
if ($stmt = $connection->prepare($sql))
{
/* bind parameters */
$stmt -> bind_param("s", $bindparam1);
/* assign value */
$bindparam1 = 'approved';
/* execute statement */
$stmt->execute();
/* bind result variables */
$stmt->bind_result($author, $title, $articledate);
/* fetch values */
while ($stmt->fetch())
{
//if exist, get approved newest comment approval date
$newsql = "SELECT col_approvaldate FROM comments WHERE col_status = ? AND col_for_author = ? AND col_for_title = ? ORDER by col_approvaldate DESC LIMIT 1";
if ($newstmt = $connection->prepare($newsql))
{
/* bind parameters */
$newstmt -> bind_param("sss", $ybindparam1, $ybindparam2, $ybindparam3);
/* give values */
$ybindparam1 = 'approved';
$ybindparam2 = $author;
$ybindparam3 = $title;
/* execute statement */
$newstmt->execute();
/* bind result variables */
$newstmt->bind_result($commentdate);
/* fetch values */
$biggerdate = '';
while ($newstmt->fetch())
{
// is there any approved comment for this article?
if (!is_null($commentdate))
{$biggerdate = $commentdate;}
}
/* close statement */
$newstmt->close();
}
else {echo 'newstmt prepare error';}
//print the result
echo '<url>'."\r\n";
echo "\t".'<loc>'.root_folder.urlencode('articles').'/'.urlencode(space_to_dash($author)).'/'.urlencode(space_to_dash(no_punctuation($title))).'</loc>'."\r\n";
//if there is no approved comment for this article
if ($biggerdate == '')
{
$biggerdate = $articledate;
}
$datetime = new DateTime($biggerdate);
$biggerdate = $datetime->format('Y-m-d\TH:i:sP');
echo "\t".'<lastmod>'.$biggerdate.'</lastmod>'."\r\n";
echo '</url>'."\r\n";
}
/* close statement */
$stmt->close();
}
?>

How it have to be
You have to get your data using single query.
Comments have to be linked using article id
PDO instead of mysqli ought to be used
So, here you go:
$sql = "SELECT author, title, a.approvaldate, max(c.approvdate) biggerdate
FROM articles a
LEFT JOIN comments c ON c.article_id = a.id AND c.status='approved'
WHERE a.status = 'approved'
GROUP BY a.id
ORDER BY a.approvaldate DESC";
$stmt = $con->prepare($sql);
$stmt->execute();
$data = $stmt->fetchall();
foreach ($data as $row) {
extract($row);
echo "<url>\r\n";
echo "\t<loc>".root_folder.'articles';
echo '/'.urlencode(space_to_dash($author));
echo '/'.urlencode(space_to_dash(no_punctuation($title)))."</loc>\r\n";
//if there is no approved comment for this article
if (!$biggerdate)
{
$biggerdate = $approvaldate;
}
$datetime = new DateTime($biggerdate);
$biggerdate = $datetime->format('Y-m-d\TH:i:sP');
echo "\t<lastmod>$biggerdate</lastmod>\r\n";
echo "</url>\r\n";
}
it is of course not tested and apparently contains many errors but just to show you an ides.
First of all you have to make query work.
then make read linked PDO tag wiki and establish a connection.
Then fix all the errors and typos, if any

Related

Mysqli query using $_get where a value is missing [duplicate]

This question already has answers here:
Search Form with One or More (Multiple) Parameters
(2 answers)
Closed 6 years ago.
I have a drop-down box where a user can select a location. Then, there is a text box where they can input a maximum rental price (there will be a few more options but to keep things simple just these in the example). Then this will go to a results.php page and using the $_GET array extract the values and query the database
This works fine if both fields are complete, but if they only wanted to search by location and leave the rent field blank it doesn't work and displays results.php?loc=york&rent= in the URL, which then as I have used the AND function displays no results?
I'm very new to PHP and would very much appreciate anyone who can point me in the right direction or what the correct term to search in google for?
<?php
$location = $_GET['loc'];
$rent=$_GET['rent'];
$result = $mysqli->query("SELECT * FROM dbc_posts WHERE '$location'=city &&'$rent'>rent_price ORDER BY ID ASC");
?>
try this
<?php
// you can check for sql injection
$location = $_GET['loc'];
$rent=$_GET['rent'];
// check if $_GET['rent'] is provided and has a value
if( isset( $_GET['rent'] ) && $_GET['rent'] ) {
$result = $mysqli->query("SELECT * FROM dbc_posts WHERE city='$location' AND rent_price < '$rent' ORDER BY ID ASC" );
// do remaining stuff
} else {
// rent is not provided
$result = $mysqli->query("SELECT * FROM dbc_posts WHERE city='$location' ORDER BY ID ASC");
// do other stuff
}
?>
You can either create 2 queries, or just one with some variables.
$rent = $_GET['rent'];
$rent_options = "";
if(isset($rent)) //add condition
{
$rent_options .= "&& \'rent\'>rent_price";
}
$mysqli->query("SELECT * FROM dbc_posts WHERE '$location'=city".$rent_options." ORDER BY ID ASC");
This way, assuming they chose a rent option, it will be added to the query. If not, it will simply be blank space and be ignored.
If the $rent is empty the you have to check it first before querying to database.
if(!empty($rent))
{
$result = $mysqli->query("SELECT * FROM dbc_posts WHERE city='$location' and rent_price<'$rent' ORDER BY ID ASC");
} else {
$result = $mysqli->query("SELECT * FROM dbc_posts WHERE city='$location' ORDER BY ID ASC");
}

If else statement with mysql table? - PHP

I need to make an if else statement that will prevent a user from bidding on an item if they are the highest bidder. I think it would go a little something like this.
if ($accountid = the accountid in the bidhistory table)
{
echo "You are the highest bidder!";
}
else
{
$sql="INSERT INTO bidhistory (accountid, biditemid)
VALUES ($accountid, $itemid)";
mysql_query("
UPDATE bidhistory
SET bidprice = bidprice + 1
WHERE biditemid = " .
#mysql_escape_string($itemid));
$result=mysql_query($sql) or die("Error in adding bid for item: ".mysql_error());
}
?>
I'm not sure how to reference the accountid from the bidhistory table. Also, if there is a better way to do this, please point me in the wright direction. Thanks!
Note:
You can fetch the row of the highest bid with the specific item first.
Then check if the highest bidder (accountid) is the same with the current user.
You can check the notes I had for some lines quoted in /* ... */
Your query for checking:
$result = mysql_query("SELECT accountid FROM bidhistory WHERE biditem = '$itemid' ORDER BY bidhistoryid DESC LIMIT 1"); /* GET THE LAST ROW FOR WHO BIDS LAST; AND REPLACE NECESSARY COLUMN NAME (unique/primary) - bidhistoryid */
while($row = mysql_fetch_array($result)){
$checkaccountid = $row['accountid']; /* STORE THE USER THAT BIDS LAST FOR THIS ITEM */
}
if($checkaccountid == $accountid){ /* THEN COMPARE IT WITH THE CURRENT USER */
/* CODE YOU WANT TO DO IF HE/SHE IS THE LAST BIDDER ALREADY */
}
else {
/* IF NOT, HE/SHE CAN STILL BID */
}
But I recommend that you use mysqli_* rather than the deprecated mysql_* API.
$con = new mysqli("YourHost", "Username", "Password", "Database"); /* REPLACE NECESSARY DATA */
/* CHECK CONNECTION */
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
if($stmt = $con->prepare("SELECT accountid FROM bidhistory WHERE biditem = ? ORDER BY bidhistoryid DESC LIMIT 1")){
$stmt->bind_param("i",$itemid); /* BIND THIS VARIABLE TO YOUR QUERY ABOVE */
$stmt->execute(); /* EXECUTE THE QUERY */
$stmt->bind_result($checkaccountid); /* STORE THE RESULT TO THIS VARIABLE */
$stmt->fetch(); /* FETCH THE RESULT */
if($checkaccountid == $accountid){
/* CODE YOU WANT TO DO IF HE/SHE IS THE LAST BIDDER ALREADY */
}
else {
/* IF NOT, HE/SHE CAN STILL BID */
}
$stmt->close();
} /* END OF PREPARED STATEMENT */

Check if a row exists in another table using mysqli

I am trying to select a row in one table and if it does exists in the second table,do something and if it doesn't,copy the values from table one into the second.
The problem is that,once it finds match (a row that is present in the first and second table),it shows errors for all other rows that did not match.
This is the error
Notice: Trying to get property of non-object in C:\wamp\www\loans.php on line 26
This is my code
<?php
//error_reporting(0);
$mysqli = new mysqli("localhost", "root", "123456", "test");
/* check connection */
if ($mysqli->connect_errno) {
printf("Connect failed: %s\n", $mysqli->connect_error);
exit();
}
$query = "select dest_msisdn,text_message,service_id,sender_name from incoming_sms";
if ($result = $mysqli->query($query)) {
/* fetch associative array */
while ($row = $result->fetch_assoc()) {
$dest_msisdn = $row['dest_msisdn'];
$text_message = $row['text_message'];
$service_id = $row['service_id'];
$sender_name = $row['sender_name'];
/**
Transactions
*/
$m = $mysqli->query("SELECT tel from transactions where tel = $dest_msisdn")->fetch_object()->message;
if(empty($m)){
$ti = "insert into transactions(message,tel) values($text_message,$dest_msisdn)";
$mysqli->query($ti);
}
}
/* free result set */
$result->free();
}
/* close connection */
$mysqli->close();
?>
I want to insert rows that i find in table one and are not in table two.
I suggest you check the rows yielded before accessing any properties that the result yields:
$m = $mysqli->query("SELECT tel, message from transactions where tel = $dest_msisdn");
// hi! im missing ^^
// you are accessing the property "message" but its not a selected column in your query
if($m->num_rows <= 0) {
$ti = "insert into transactions(message,tel) values($text_message,$dest_msisdn)";
$mysqli->query($ti);
}
When you chain like that you are assuming there will always be a row. When there isn't a row you cant get the property from it. That's why you get the error. So do something like this:
$r = $mysqli->query("SELECT tel from transactions where tel = $dest_msisdn");
if ($r->num_rows == 0) {
$ti = "insert into transactions(message,tel) values($text_message,$dest_msisdn)";
$mysqli->query($ti);
}
This doesn't answer your question directly, but it will fix your problem and probably solve some others.
The way you are going about inserting (where you first SELECT and then loop through the results in PHP, then SELECT from another table, then INSERT) seems unnecessarily complex. You can get rid of your PHP loop and just execute the INSERT in a single SQL statement without all the PHP overhead. Let your DB do the work for you.
All of this:
$query = "select dest_msisdn,text_message,service_id,sender_name from incoming_sms";
if ($result = $mysqli->query($query)) {
/* fetch associative array */
while ($row = $result->fetch_assoc()) {
$dest_msisdn = $row['dest_msisdn'];
$text_message = $row['text_message'];
$service_id = $row['service_id'];
$sender_name = $row['sender_name'];
/**
Transactions
*/
$m = $mysqli->query("SELECT tel from transactions where tel = $dest_msisdn")->fetch_object()->message;
if(empty($m)){
$ti = "insert into transactions(message,tel) values($text_message,$dest_msisdn)";
$mysqli->query($ti);
}
}
/* free result set */
$result->free();
Could be changed to just this:
$mysqli->query("INSERT INTO transactions(message,tel) SELECT text_message, tel FROM transactions INNER JOIN incoming_sms on transactions.tel = incoming_sms.dest_msisdn")

If nothing is found for field, create new field

PHP newbie here
I have a mysql table called "topics", and i'm pulling information from the table for a page based on a result from a form (in the URL through GET)
If the URL doesn't exist, i'd like to be able for the table to create a new entry with the topic name from the URL filled in
$topic_name would be what i'd be putting in the new topicname field
My code so far:
$topic_name = strtolower(mysql_real_escape_string($_GET['t']));
//look for info
$topic_info = mysql_query("SELECT * FROM topics WHERE topicname = '$topic_name' LIMIT 1");
if (mysql_numrows($topic_info)<=0) {
//insert record
$SQL='insert into topics (topicname) values ("'.$topic_name.'")';
mysql_query($SQL);
$t_desc='NEW TOPIC : '.$topic_name;
}
else {
//do as normal (without unnessecary loop)
$g=mysql_fetch_array($topic_info);
$t_desc = $g['desc'];
}
EDIT: Sorry, I don't think i explained well, the result is from a GET from a form, so url.com/topic?=BLAH
blah would be the name of the field i'd want to create if it doesn't exist.
The table has an Auto incrementing 'ID' (primary key)
If i understand you correct :
$topic_name = (isset($_GET['t'])) ? strtolower(mysql_real_escape_string($_GET['t'])) : '';
//look for info
$topic_info = mysql_query("SELECT * FROM topics WHERE topicname = '$topic_name' LIMIT 1");
if (mysql_num_rows($topic_info)<=0) {
//insert record
//UPDATE
//$SQL='insert into topics (topicname) values ("'.$topic_name.'")';
$SQL='insert into topics (topicname, `desc`) values '.
'("'.$topic_name.'", "NEW TOPIC DESC")';
mysql_query($SQL);
$t_desc='NEW TOPIC : '.$topic_name;
} else {
//do as normal (without unnessecary loop)
$g=mysql_fetch_array($topic_info);
$t_desc = $g['desc'];
}
Try as below
$topic_info = mysql_query("SELECT * FROM topics WHERE topicname = '$topic_name' LIMIT 1");
$count = mysql_num_rows($topic_info);
if($count <= 0){
// do insert query
}
else {
// loop through you result and display record
while($g = mysql_fetch_array($topic_info)){
$t_desc = $g['desc'];
}
}
Note: Better to use PDO or Mysqli lib for new development and prevent mysql injection attack

PHP PDO Row Counting

i want to check the rows if there are any events that are binded to a host with host_id parameter, everything is well if there is not any events binded to a host, its printing out none, but if host is binded to one of the events, its not listing the events, but if i remove the codes that i pointed below with commenting problem starts here and problem ends here, it lists the events. I'm using the fetchAll function above too for another thing, there is not any such that error above there, but with the below part, it's not listing the events, how can i fix that?
Thanks
try
{
$eq = "SELECT * FROM `events` WHERE `host_id` = :id AND `confirmed` = '1' ";
$eq_check = $db->prepare($eq);
$eq_check->bindParam(':id', $id, PDO::PARAM_INT);
$eq_check->execute();
//problem starts here
$count3 = $eq_check->fetchAll();
$rowCount = count($count3);
if ($rowCount == 0)
{
echo "None";
}
//problem ends here
while($fetch = $eq_check->fetch (PDO::FETCH_ASSOC) )
{
$_loader = true;
$event_id = $fetch['event_id'];
$event_name = $fetch['event_name'];
$link = "https://www.mywebsite.com/e/$event_id";
echo "<a target=\"_blank\" href=\"$link\"><li>$event_name</li></a>";
}
}
catch(PDOException $e)
{
$log->logError($e." - ".basename(__FILE__));
}
Thank you
You can't fetch twice without executing twice as well. If you want to not just re-use your $count3 item, you can trigger closeCursor() followed by execute() again to fetch the set again.
To reuse your $count3 variable, change your while loop into: foreach($count3 as $fetch) {
The reason that it is not listing the events when you have your code is that the result set is already fetched using your fetchAll statement (The fetchAll doesn't leave anything to be fetched later with the fetch).
In this case, you might be better off running a select count(*) to get the number of rows, and then actually running your full query to loop through the results:
An example of this in PDO is here:
<?php
$sql = "SELECT COUNT(*) FROM fruit WHERE calories > 100";
if ($res = $conn->query($sql)) {
/* Check the number of rows that match the SELECT statement */
if ($res->fetchColumn() > 0) {
/* Issue the real SELECT statement and work with the results */
$sql = "SELECT name FROM fruit WHERE calories > 100";
foreach ($conn->query($sql) as $row) {
print "Name: " . $row['NAME'] . "\n";
}
}
/* No rows matched -- do something else */
else {
print "No rows matched the query.";
}
}
$res = null;
$conn = null;
?>
Note that you cannot directly use rowCount to get a count of rows selected - it is meant to show the number of rows deleted and the like instead.

Categories