PHP: why is strtotime() returning "NOW()"? - php

I'm calling strtotime() on a formatted datetime string and for some reason it always returns NOW()...
If my formatted datetime string (stored in the last_seen attribute) is: 2013-06-13 07:13:04
and I write the following code:
echo $user->last_seen;
echo date('F j, Y', strtotime($user->last_seen));
The output I get is:
NOW() January 1, 1970
What on earth is going wrong here??? This is definitely not the expected result. The string is stored in a MySQL database, if that makes any difference.
Edit: by request, the code used to create the attribute in the database is:
$user->last_seen = date('Y-m-d H:i:s');
$user->save;
Edit 2: by request, the code used to pull the users table, with the user we want, is:
$user = User::find($user_id);
(not very helpful, lol).
Edit 3: if I var_dump($user->last_seen) the result is:
object(Laravel\Database\Expression)#40 (1) { ["value":protected]=> string(5) "NOW()" }
Edit 4: If I echo var_dump(strtotime($user->last_seen)) the result is:
bool(false)
Edit 5: this problem was a result of me being an idiot, but some fine debugging was done by everyone who posted. Read the answers if you are interested.

First of all You check the return value of strtotime($user->last_seen)
If strtotime($user->last_seen) returns false then $user->last_seen may be empty or not a valid Date and Time Formats
var_dump(strtotime($user->last_seen))

Your problem is most likely not in the select clause, but lays there where you store your data.
When you are inserting the time in the database, you are probably doing
insert into myTable (fieldname) values ('now()');
instead of
insert into myTable (fieldname) values (now());
So you need to lose the quotes there...
You are NOT storing the time in the database, but the string now() ...
The best thing you could actually do is change the database column type from varchar to DateTime, so even the database knows it's a DateTime. Then you avoid having to cast it back to DateTime in PHP.

Oh dear god.... I'm going to kick myself for this one. I did a project wide Ctrl+F for last_seen and I discovered that in my routing scheme I had this:
Route::filter('before', function() {
if (Auth::check()) {
$user = Auth::user();
$user->last_seen = DB::raw('NOW()');
$user->save();
}
});
Walks away with tail between legs...

Related

MySQL update query is updating all fields except date (using PHP)

I have a simple update query for when someone subscribes to my web app, updating the details of their license.
Recently I made some minor changes to this and it has stopped working (I presume these are linked, but haven't actually managed to prove this) - I've tried reversing whatever I did but seems to be to no avail.
For some reason, the update runs successfully and all fields update, except the expiry field.
I write my sql query into a log file and I've copied this into phpmyadmin command line and it works exactly as expected.
[Result is:
UPDATE License
SET type='Full'
, payer_id = 'XXXXXXX'
, gross = 'XXXX'
, payer_email = 'XXXXXXX'
, license_start = '2019-08-21 14:46:17'
, expiry = '2019-09-21'
, product = 'MON'
, stripe_id = 'XXXXXX'
WHERE user_id = XXX
which seems fine to me
I've adapted the format, apostrophes, I've even just put a date in like '2019-12-10' and it still won't update via the mysqli query. I've also tried expiry = $start, which requires truncation, but should work... still just doesn't update that field.
$expiry = date("Y-m-d", strtotime("+$couponmonths months", strtotime(date("Y-m-d H:i:s",$expiryts))));
$start = date ("Y-m-d H:i:s");
$sql = "UPDATE `$license_table` SET `type`='Full', `payer_id`='$subid', `gross`='$price', `payer_email`='$email', `license_start`='$start', `expiry` = '$expiry', `product`='$product_name', `stripe_id`='$stripeid' WHERE `user_id`=$userid";
}
...
if (mysqli_query($connection,$sql) === TRUE) {...}
Thanks those of you that tried to help. I've fixed this now by literally creating a new column called expiry_date instead of expiry, copying the data across to the new column, and updating all references.
Feel like I haven't solved what went wrong, but I have at least got it working again. It felt like the column had decided to to accept updates via PHP - not sure this is even possible???
I decided to try this course of action when I sent a query saying only to update this column and it still didn't work... madness!
Would love to hear an explanation if there is one, but just happy to have it working for now.
I think you should be setting $expiry, which presumably gets inserted into a datetime or timestamp type column in your DB, with the default SQL datetime format Y-m-d H:i:s as you did below.
Also, make sure that
strtotime("+$couponmonths months", strtotime(date("Y-m-d H:i:s", $expiryts)))
actually works the way you intend and returns the desired time.
Also, you should use {} to insert variables into strings.
Like so:
"UPDATE `{$license_table}` SET `type`='Full', `payer_id`='{$subid}', `gross`='{$price}', `payer_email`='{$email}', `license_start`='{$start}', `expiry` = '{$expiry}', [...]"
and so on.
This makes sure php is interpreting the variables correctly.
If all still fails, try to dump the query string and run it manually with the DB-manager or cli of your choice, for you to debug.

PHP/MySQL/PDO search on date from database

Trying to make a little Search feature for a user, so he can type in a date on a webpage made with HTML/PHP, and see which people in the db have registered as member on or after (a date). My user inputs the date in format 2015-10-01. This gets sent to a PHP page with a jqxGrid on it, populated with member details of members conforming to my query on the MySQL database (using PDO).
The query uses the operator >= on a string passed as (for example) "2015-10-01" in the WHERE clause, so I am using STR_TO_DATE to make the comparison work:
WHERE `lastUpdated` >= STR_TO_DATE( ? , '%Y-%m-%d');
With PDO, the ? later gets bound to the date (which was passed in as a string).
The db column for registration date is in DATETIME format, and in the db values look like: "2015-10-12 17:12:52".
My query returns an empty array every time, - and this after many hours of trying every conceivable permutation of date format, both in the MySQL statement and on the page that prepares the data for populating the grid.
Can someone show me what's wrong here?
Thanks!!
SP
Make it
WHERE `lastUpdated` > ?
and check your data and stuff.
Basically, you should never touch PDO until you get raw SQL to work.
okay, so here is the PDO version that works - passing in ? instead of the date:
function getJSONAllMembersByDate($PDOdbObject, $regDate)
{
try
{
$membersByDateSQL = "SELECT `id`, `name_first`, `name_last`, `organization`,`email`, `phone`,`source`,`comments`,`language_id`, `lastUpdated` FROM `member` WHERE lastUpdated>=?";//'$regDate'
$get=$PDOdbObject->prepare($membersByDateSQL);
$get->execute(array($regDate));
$rows = $get->fetchAll(PDO::FETCH_ASSOC);
$json=json_encode($rows);
return $json;
}
The fact that it works proves there were other errors in the file containing the jqxwidget (the version before I posted here). I certainly tried about a million different things to get this working.
I don't know if this counts as an answer, but at least it WORKS! There are so many variables in this problem - json, jqxgrid, pdo ... not forgetting that there are several ways to use PDO. I probably had several errors in different places.
(#apokryfos, the STR_TO_DATE was indeed unnecessary.)
In the end, this is what works:
In the PHP page containing the jqxGrid, the url sent to the server is:
url: 'my-json-responses.php?fct=getJSONAllMembersByDate&regDate=<?php echo $fromDate ?>'
This $fromDate comes from the $_POST when the user typed in a date (in the format 2015-10-01) on the input page. When the PHP page containing the jqxGrid loads, it does
$fromDate = $_POST['regDate'];
The url "transits" through the file my-json-reponses.php, which contains many functions. It finds the right one:
if ($_GET['fct'] == 'getJSONAllMembersByDate')
{
$result = getJSONAllMembersByDate($connectionObject, $_GET['regDate']);
echo $result;
}
The $result is called on the file that contains all my PDO database requests, including:
function getJSONAllMembersByDate($PDOdbObject, $regDate) { try
{
$membersByDateSQL = "SELECT `id`, `name_first`, `name_last`, `organization`,`email`, `phone`,`source`,`comments`,`language_id`, `lastUpdated` FROM `member` WHERE lastUpdated>='$regDate'";
$get=$PDOdbObject->query($membersByDateSQL);
$rows = $get->fetchAll(PDO::FETCH_ASSOC);
$json=json_encode($rows);
return $json;
}
catch (PDOException $e)
{
echo "There was a problem getting all members with this search query.";
echo $e->getMessage();
}}
Note that I couldn't make the version using "?" in the query work at all, hence passing in the variable $regDate directly, with single quotes around the variable just to make life interesting.
This returns a nice list of all my users as of 2015-10-01 - but is presumably still open to MySQL injection attacks ...
But after this marathon of debugging I am happy enough for now. (All improvements welcomed, naturally!)
SP

DateTime could not be converted to string PDO query

I'm trying add 1 month to a certain date and then save the new
date to the database using the following code. But I seem to get
an error saying "Object of class DateTime could not be converted to string"
//New Expiration Date
$expDate = new DateTime('2015-06-05');
$expDate->add(new DateInterval('P1M'));
$newExpDate = $expDate->format('Y-m-d');
//Extend
$stmt = $this->connection->prepare(' UPDATE users SET valid_until = :new_expire_date WHERE user_id = :user_id ');
$stmt->execute(array(':user_id' => $expDate,':new_expire_date' => $newExpDate));
The last line is the one that throws the error.
When I var_dump($newExpDate) I get
string(10) "2015-07-05"
It seems wierd to me, I dont know if anyone
has any idea...?
Thank you.
Sorry guys It was a mistake in my query. Im ashamed :(
The values passed to PDOStatement::execute() should be scalars (strings, integers, ...). The first value you pass, $newExpDate, is a DateTime object.
Use $expDate->format('Y-m-d'); instead.
$expDate is not a string it is the datetime object. You have :user_id assigned as $expDate. I think you meant to do something else here. $newExpDate is a string and that part of the statement seems to be correct. Relook at the first element of your created array and make sure that is really what you meant to do.

Insert current time to MySQL table using CDbMigration

How should I use MySQL's FROM UNIXTIME correctly in CDbMigration in Yii 1.x?
I have borrowed solution of converting current time given as timestamp, to MySQL's DateTime field from this answer and when just printing it:
echo 'FROM_UNIXTIME('.$base.')'."\n";
echo 'FROM_UNIXTIME('.$sixDaysLater.')'."\n";
everything seems fine:
FROM_UNIXTIME(1418223600)
FROM_UNIXTIME(1418742000)
But, when I'm trying to use the same technique as a part of my migration:
$this->insert('contents', array
(
'author_id'=>1,
'type'=>5,
'status'=>1,
'category'=>1,
'title'=>'title',
'body'=>'body',
'creation_date'=>'FROM_UNIXTIME('.$base.')',
'modification_date'=>'FROM_UNIXTIME('.$base.')',
'availability_date'=>'FROM_UNIXTIME('.$sixDaysLater.')',
'short'=>'short'
));
This fails -- that is, migration goes fine, but I can see in phpMyAdmin, that related fields for this record has been populated with zeros (0000-00-00 00:00:00), not with the expected value.
What am I missing? Is it, because values in insert are being encoded / escaped?
You can use CDBExpression instead:
new CDbExpression("NOW()");
I mean:
'creation_date'=>new CDbExpression("NOW()")
Or if you want to use FROM UNIXTIME you can do the same.
CDbExpression represents a DB expression that does not need escaping.

Timestamp returned as weird string

When I select a timestamp from the cassandra database via PDO (YACassandraPDO is also installed), I get the following output;
Bý£1€
Identified as a string(8) in a var_dump
This value should be December 17th 2013 00:00:00
As a guess, I tried $arr = unpack("l", $raw['date']); which results in
Array([1] => 1107361792)
But converting from epoch, this equals: 2005-2-02
Can anyone tell me what I'm supposed to do?
UPDATE
By the way, the timestamps show up just fine in the CQL commandline and DevCenter.
UPDATE 2
Here's the method I use to select the rows;
function getAny($limit=100)
{
$stmt = $this->pdo->prepare("SELECT * FROM \"".$this->tableName."\" LIMIT $limit;");
if($stmt->execute() === false)
{
$this->logError($stmt, "getAny");
return false;
}
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
Check that the timestamp is correct at the time of insertion into the database. The epoch time string you should have is 1387238400
Not really an answer, but it seems to be as good a solution as it's going to get; I simple changed the column types to bigint to store the epoch time & it's working fine now. If anyone ever finds out what was going on, I'd love to know!

Categories