I have a query that I am using to get results that are newer than a given timestamp. It is supposed to find all those newer messages that were sent and received by a given user. The problem is, no matter what I change the timestamp parameter to, I even changed it to 'g', I still get 4 results. The timestamp doesn't seem to alter my query. In the table, the timestamp is an int(11). I tried using intval and defining the bindvalue as a param int and still no luck. Any ideas?
$sql = 'SELECT timestamp, user, message, receiver, convo_id
FROM chatbox
WHERE user = ?
OR receiver = ?
AND timestamp = ?
ORDER BY timestamp DESC';
$stmt = $conn->prepare($sql);
$stmt->bindValue(1,'username');
$stmt->bindValue(2,'username');
$stmt->bindValue(3,'g');
$stmt->execute();
I suspect it's the precedence of AND and OR in your where clause. Try using parentheses:
WHERE ( user = ? OR receiver = ? )
AND timestamp = ?
assuming that's what you need.
Shouldn't you do this instead in your $sql variable?
AND timestamp > ?
Related
I have problems comparing dates between a date created with new dateTime () in php, and a date taken from a DATETIME field of a Mysql table.
With the following code, save a date in a DATETIME field of a MySQL table:
$now = new DateTime();
$update = $mysqli->query('INSERT INTO bonus (idplayer,lastlogin) VALUES ("'.$_GET["idplayer"].'","'.$now.'")');
Then I would like to retrieve the date from the tables and compare it with a date created using the php code:
$resetTime = new DateTime();
date_time_set($resetTime, 12, 00, 00);
$lastLogin = $mysqli->query('SELECT lastlogin FROM bonus WHERE idplayer = "'.$_GET["idgiocatore"].'"');
if ($resetTime < $lastLogin) {
echo "OK!<br>";
}
Using this code I can't comparate the dates because I get an error (I can't even do an echo of the date retrieved from the table).
Can anyone tell me where I'm wrong and how can I solve the problem?
Try this
$resetTime = (new DateTime)->format('Y-m-d 12:00:00'); //need it as a string
//$resetTime = date('Y-m-d 12:00:00'); //-- this is fine too
$stmt = $mysqli->parpare('SELECT lastlogin FROM bonus WHERE idplayer = ?');
$stmt->bind_param("s", .$_GET["idplayer"]);
$stmt->execute();
list($lastLogin) = $stmt->get_result()->fetch_array();
if ($resetTime < $lastLogin) {
echo "OK!<br>";
}
Basically your comparing the query result set, to your timestamp, instead of the value of the first column of the first row. Consider you code:
$lastLogin = $mysqli->query('SELECT lastlogin FROM bonus WHERE idplayer = "'.$_GET["idgiocatore"].'"');
if ($resetTime < $lastLogin) {
mysqli::query
Returns FALSE on failure. For successful SELECT, SHOW, DESCRIBE or EXPLAIN queries mysqli_query() will return a mysqli_result object. For other successful queries mysqli_query() will return TRUE.
https://www.php.net/manual/en/mysqli.query.php
Your also full of SQL Injection errors, an input such as this:
$_GET["idgiocatore"] = '" OR 1 ORDER BY lastlogin DESC LIMIT 1 --'
Will turn your query into this
'SELECT lastlogin FROM bonus WHERE idplayer = "" OR 1 ORDER BY lastlogin DESC LIMIT 1 -- "'
Everything after the -- is a comment so we can ignore that ending ". This avoids creating a syntax error, and is a very common tactic (nothing new).
This will select all records from the DB because Anything plus OR 1 is always true, then it will sort them by your lastlogin value DESC so the highest value is first and Limit to 1 return row, well just because I can. Basically this will satisfy your if condition if ($resetTime < $lastLogin) Which I guess is a "good thing" (well for me, the haxor).
Essentially this is because you are just pasting user input right into the SQL, so it becomes part of the command if formulated correctly (not a good thing for you).
Anyway Hope it helps you.
*PS it's been an age (like 6 years) sense I used MySqli (normally I use PDO) so forgive me any errors there, most of that came from a basic tutorial over at W3Schools
One last thing instead of setting the time, consider removing it altogether with the MySql DATE() function:
$resetTime = (new DateTime)->format('Y-m-d');
//...
$stmt = $mysqli->parpare('SELECT DATE(lastlogin) FROM bonus WHERE idplayer = ?');
I want that my PHP checks if the time in the mysql db is the same, and if not that it will be changed.
This is what I got:
<?php
$last_time_check=mysqli_query($con,"SELECT `time` FROM `servervars`");
if((time()-$last_time_check) >=1)
{
mysqli_query($con, 'UPDATE `servervars` SET `time`='.$time.' WHERE ID=1');
}
?>
$con is the connection to the DB.
Current value 'time' in servervars: 1412448339
Value 'ID' is 1
I do something wrong, but I just cannot find where it's going wrong.
The Fix
I've removed the variable $last_time_check and only checked if the time could get changed. If this happends then it will send another message to the client.
mysqli_query($con, 'UPDATE `servervars` SET `time` = UNIX_TIMESTAMP() WHERE ID = 1 AND UNIX_TIMESTAMP() - `time` >= 1');
if ($con->affected_rows)
{
// at least 1 second has elapsed, do stuff
}
MySQL has an equivalent to time(), its the function UNIX_TIMESTAMP(). Differently though, it can take a DATETIME as parameter to convert it into UNIX time, but when used without parameters its the same as UNIX_TIMESTAMP(NOW()).
UPDATE servervars SET time = UNIX_TIMESTAMP() WHERE ID = 1
Update
Ok so about the other issues. You are doing it all wrong. mysqli_query does not return the value directly. To fetch the value of time from the database, you need 3 steps:
$result = $con->query('SELECT `time` FROM `servervars` WHERE ID = 1'); // fetch result set
$row = $result->fetch_row(); // fetch a row from the result set, as an array
$last = $row[0]; // get the first element from the row you just fetched
Notice $con->query() can fail if theres a problem with the connection, the database, the table, or the query syntax itself, and $result->fetch_row() can fail if there are no results for the query. You should validate them before proceeding to the next step.
Alternatively, you can do this:
$con->query('UPDATE `servervars` SET `time` = UNIX_TIMESTAMP() WHERE ID = 1 AND UNIX_TIMESTAMP() - `time` >= 1');
if ($con->affected_rows)
{
// at least 1 second has elapsed, do stuff
}
This way we shortened your solution to a single query, that updates the field if necessary and report back that it happened or not..
Well i built my website to write dates to database column in the following format:
2014/04/01
Now i've come to realize this is not helpful when i want to sort by date or manipulate date so i decided to change all date to to timestamps.
i applied the following fix :
$sql = mysql_query("SELECT * FROM TABLE")or(die(mysql_Error()));
while($info = mysql_fetch_array($sql)){
$newdate = strtotime($info['date']);
mysql_query("UPDATE TABLE SET date = '$newdate' WHERE id = $info[id]")or(die(mysql_error()));
}
the problem is all the date columns are empty now, What am i doing wrong ?
There's what looks like a syntax error on this line:
mysql_query("UPDATE TABLE SET date = '$newdate' WHERE id = $info[id]")
or(die(mysql_error()));
Try changing it to:
mysql_query("UPDATE TABLE SET date = '$newdate' WHERE id = {$info['id']}")
or (die(mysql_error()));
The reason is that when interpolating array indices into a string, you must surround them with {} or PHP will just try to convert $info to a string and insert [id] after it, which I'm guessing you didn't intend.
I would also suggest checking the return value for strtotime. If it can't parse a date it returns false which I'm guessing you don't want inserted back into your database.
I am trying to get the details of a persons based on the user input age (Integer). Now my query always returns null Array() whenever I execute the below code. I haven't specified the $postdata array. You can see I have used $postdata['ageto'] and $postdata['agefrom'] are used in calculating $agefrom and $ageto
$now = new DateTime();
//Converting _POST age to Date
$agefrom = date("Y-m-d",strtotime($now->format("Y")-$postdata['ageto'].'-'.$now->format("m").'-'.$now->format("d")));
$ageto = date("Y-m-d",strtotime($now->format("Y")-$postdata['agefrom'].'-'.$now->format("m").'-'.$now->format("d")));
$this->db->select('uacc_id, uacc_username, name, dob, city, education');
$this->db->from('user_accounts as a');
$this->db->join('personal as b','a.uacc_id = b.pruserid','INNER');
$this->db->join('profession as c','a.uacc_id = c.puserid','INNER');
$this->db->join('location as d','a.uacc_id = d.luserid','INNER');
$this->db->where('dob >= ',$agefrom);
$this->db->where('dob <= ',$ageto);
$this->db->limit(10, $offset);
$query = $this->db->get();
return $query->result();
I have suspected that my input post is not fetching the data properly. So I have replaced it with my simple query select * from... where dob >.... and it worked well. So there is no problem with _POST variables. I am not sure what I am doing wrong. Can some one help me.
I think you have to specify to which table DOB belongs like a.dob. Sorry for the post but I could not comment. Hope this helps.
The select field should add the table name
$this->db->select('a.uacc_id, a.uacc_username, a.name....); // example
and your where add table name too.
$this->db->where('b.dod >= ', $agefrom); // example
or you can output the sql command.
You can look here
Using the code below, I'm having trouble checking whether a specified date exists in a MySQL 'date' column.
$data = array(1367971200);
$s=$dbh->prepare("
SELECT DISTINCT
`date`
FROM
`report_coa_bal_hist`
WHERE
UNIX_TIMESTAMP(`date`) = ?
");
if ($s->execute($data)) {
if ($s['date'] == null) {
return false;
}
return true;
}
It's returning false, despite the fact that I can see the date '2013-05-08' displayed in phpMyAdmin.
The table itself contains 70+ entries for that date. It always will do, if it contains any at all, but I just want to know whether it exists or not at this stage.
The date field is a MySQL 'date' type. I'm suspecting that the bug is in my structuring of the PDO calling of the query.
UPDATE
Updated $r['date'] to `$s['date']. I suspect that I still have an issue with the structure of that, but probably need to fix the query so that it gives us results before focusing on this.
Also tried running the query against the database directly and got an empty resultset, despite being able to see that the target date exists. Still baffled!
Try this
$data = array(1367971200);
$s=$dbh->prepare("
SELECT COUNT(`date`) as c_date
FROM
`report_coa_bal_hist`
WHERE
UNIX_TIMESTAMP(`date`) = ?");
if ($s->execute($data)) {
$result = $s->fetch(PDO::FETCH_ASSOC);
if ($result['c_date'] > 0) {
return false;
}
return true;
}
You can't select a whole day with UNIX timestamps because of their more accurate nature (i.e. seconds), you would need the textual version:
$data = array(date('Y-m-d', 1367971200));
$stmt = $dbh->prepare("SELECT COUNT(*)
FROM `report_coa_bal_hist`
WHERE `date` = ?
");
$stmt->execute($data);
$count = current($stmt->fetchAll(PDO::FETCH_COLUMN, 0));
return $count > 0;
Take note of any timezone differences between the server that runs your script and the database server itself.
there are many flaws with your code, not one:
format of the value you are checking
way you are checking in SQL
the way you are getting result
So, the code have to be
$data = array('2013-05-07');
$sql = "SELECT 1 FROM report_coa_bal_hist WHERE `date` = ? LIMIT 1";
$stm = $dbh->prepare($sql);
$stm->execute($data);
return $stm->fetchColumn();