php explode microtime error: Undefined offset: 1 - php

I have this code which is showing this error in the logs. Any ideas why?
PHP Notice: Undefined offset: 1
$microtime = microtime(true);
list($time,$mili) = explode(".", $microtime);
EDIT:
Sorry forgot to mention that this error doesn't happen every time, I just noticed it in the logs. Maybe it only happens when there are no milliseconds
Example output of microtime: 1418114280.8363

A bit too long for a comment, but (as an alternative) try using
$microtime = microtime(true);
$time = floor($microtime);
$mili = fmod($microtime, 1);
and see what result this gives

It works fine check it
echo $microtime = microtime(true);
print_r(explode(".", $microtime));
list($time,$mili) = explode(".", $microtime);
print_r($time);
echo '---';
print_r($mili);

Related

PHP error: Call to a member function setTimeZone() on boolean

Faced the following error in a function that returns the current time with microseconds:
Fatal error: Call to a member function setTimeZone() on boolean
The code this function is:
public static function getCurrentTime() {
$microtime = microtime(true);
$time = DateTime::createFromFormat('U.u', (int) $microtime != $microtime ? $microtime : $microtime + 0.001);
$time->setTimeZone(new DateTimeZone(date_default_timezone_get()));
return $time->format('Y-m-d H:i:s.u');
}
This error occurs with a small proportion of users (<1%). I know that setTimeZone() can return false if a problem occurs, but how can I avoid this problem in my code? Why does setTimeZone() return false?
I am using PHP Version 7.0.9.
The problem turned out to be that the microtime(true) function sometimes returns a number without a dot and the U.u format does not apply to it. As a result, two solutions were found to solve the problem:
Solution 1: Replace (int) $microtime != $microtime with stripos($microtime, '.')
Solution 2: Wrap the code in a try-catch construct, like this:
try {
getCurrentTime();
} catch (Exception $e) {
// Retry a maximum of 3 times
}
Posted on behalf of OP
The casting to (int) on your ternary statement might be the culprit.
What you are effectively doing is:
$microtime_int != $microtime_float
Which will almost always give you a false. But when it returns TRUE, when you hit the magic sweet spot of $microtime having zeroes after the decimal point, your format U.u will not work.
Since you must have microseconds, then I will suggest catching an error and retrying until you are fine.
This pseudocode should fix your issue:
try{
getCurrentTime();
}catch(e Exception){
retry max 3 times
}
Please see the proof:
Ouput:
1544603355.9997
1544603355.9998
1544603355.9998
1544603355.9999
1544603355.9999
1544603355.9999
1544603356
PHP Fatal error: Uncaught Error: Call to a member function setTimeZone() on boolean in a.php:6
Stack trace:
#0 {main}
thrown in a.php on line 6
script:
<?php
for ($i = 0; $i <= 999999; $i++){
$microtime = microtime(true);
echo $microtime . "\n";
$time = DateTime::createFromFormat('U.u', (int) $microtime != $microtime ? $microtime : $microtime + 0.001);
$time->setTimeZone(new DateTimeZone(date_default_timezone_get()));
}
Above fixes, still in very small amount of cases, give me an error. So I fixed it, in rather very creapy way, but if it works, it works:
$microtime = number_format(microtime(true),4,'.','');

Failed to parse time string: it is working good on my local but on server

I have a code which is working on my localhost but in server it throws error.
the error is: Fatal error: Uncaught exception 'Exception' with message 'DateTime::__construct(): Failed to parse time string (#1645.0000000006) at position 14 (0): Unexpected character
my code is:
function secondsToTime($seconds)
{
$arr = array();
$dtF = new DateTime('#0');
$dtT = new DateTime("#$seconds");
$arr[0] = $dtF->diff($dtT)->format('%h');
$arr[1] = $dtF->diff($dtT)->format('%i');
$arr[2] = $dtF->diff($dtT)->format('%s');
return $arr;
}
print_r(secondsToTime("1645.0000000006"));
what is the problem? thanks everyone
Apparently handling of microseconds changed around PHP 7.1 and PHP accepts decimal values as valid timestamps starting with that version, but not before. If you have to make it compatible with previous versions, you need to cast your float to an int:
$dtT = new DateTime('#' . (int)$seconds);

preg_split to unknown number of list() elements

I have a PHP script that I wrote probably 10 years ago. I don't remember what version PHP was on at the time but my script worked just fine without complaint from the interpreter. Now, I've had to move my scripts to a new web host and, under PHP 7.x, the interpreter complains loudly about a certain line of this script and I'm looking for an elegant way to get it to shut up.
The offending line is:-
list($degrees, $minutes, $seconds) = preg_split("/ /", $coord);
The $coord variable contains a GPS coordinate in one of three forms: "degrees minutes seconds", "degrees decimal-minutes", or "decimal-degrees". So, the preg_split() may return 1, 2, or 3 elements. If it returns only 1 or 2 elements, the interpreter complains loudly about the undefined references to $seconds and/or $minutes. I see that there is a LIMIT parameter that I could specify for preg_split() that gives it a maximum number of elements to return but there doesn't seem to be a complimentary parameter to tell it the MINIMUM number of elements to return. Any suggestions welcome.
Sample coords: '-97.74019' or '-97 44.411' or '-97 44 24.7'
Totally agree with Anant, but you can do it in bit more elegant way:
<?php
$coordArray = preg_split('/ /', $coord);
$degrees = $coordArray[0] ?? 0;
$minutes = $coordArray[1] ?? 0;
$seconds = $coordArray[2] ?? 0;
The line gives a E_NOTICE ("Notice: Undefined offset: X in Command line code on line 1"). You can either change the error reporting level to not include E_NOTICE or just hide disable the error reporting for this particular line with the # operator. There is no harm in using # here. Unmatched variables will be assigned NULL (in 5 and 7):
$coord = "x y";
#list($degrees, $minutes, $seconds) = preg_split("/ /", $coord);
var_dump($degrees, $minutes, $seconds);
Gives:
string(1) "x"
string(1) "y"
NULL
I wouldn't generally recommend it, but to suppress all E_NOTICE error notices, you can unset it in the error_reporting setting:
ini_set("error_reporting", E_ALL&~E_NOTICE);
You can convert that code like below:-
$d_m_s_array = preg_split("/ /", $coord);
$degrees = (!empty($d_m_s[0]) ? $d_m_s[0] :0;
$minutes = (!empty($d_m_s[1]) ? $d_m_s[1] :0;
$seconds = (!empty($d_m_s[2]) ? $d_m_s[2] :0;
Note:-
Also your original code will generate a notice only (if error reporting is on for that too). Look here:- https://eval.in/707979
It will not stop the program execution, but you can+have-to resolve this notice by the above code
Wrap the variably-sized array with array_pad as demonstrated below:
list($degrees, $minutes, $seconds) = array_pad( preg_split("/ /", $coord), 3, null);
Your intuition is right that you need a MINIMUM number of elements to return, and that is exactly what array_pad will do for you.

Php microtime() is not working on live site. Looking for workaround

I have Zend Server 6.3 and Php 5.4 on Windows. And system works very well. Now I moved code to live site, which runs Php 5.3.29 on Ubuntu Server with DirectAdmin. All other website are running well there. But my current website gives me this error (the site is on WordPress 4.3):
Warning: mysql_connect(): Headers and client library minor version mismatch.
Headers:50541 Library:50623 in /home/cheapauto/domains/*DOMAIN*/public_html/wp-includes/wp-db.php on line 1482
Parse error: syntax error, unexpected '[' in /home/*USER*/domains/*DOMAIN*/public_html/wp-content/plugins/*MY-PLUGIN*/includes/final.class.NRSBooking.php on line 101
The line is this:
$now = explode(' ', microtime())[1];
And my whole plugin function is this:
private function getIncrementalHash($length = 5)
{
//$charset = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
$charset = "ABCDEFGHIJKLMNPRSTUVYZ"; // fits LT & EN, O is skipped to similarity to Zero
$charsetLength = strlen($charset);
$result = '';
$now = explode(' ', microtime())[1];
while ($now >= $charsetLength)
{
$i = $now % $charsetLength;
$result = $charset[$i] . $result;
$now /= $charsetLength;
}
return substr($result, -$length);
}
Any ideas how to make it work on live site?
As per Php reference http://php.net/manual/en/function.microtime.php
it says:
microtime() returns the current Unix timestamp with microseconds. This
function is only available on operating systems that support the
gettimeofday() system call.
And I use that function to generate unique new booking code:
$newBookingCode = "R".$validNextMySQLInsertId."A".$this->getIncrementalHash(5);
Thank you!
Array dereferencing, i.e. getting results from function which returns array like:
$now = explode(' ', microtime())[1];
is available since php5.4
For php5.3 and older use:
$now = explode(' ', microtime());
$now = $now[1];

Parsing date in a Facebook application using PHP

i'm trying a simple facebook application, running on localhost using wamp 2.0 , i got the date using the following code as shown here, when i run echo($bd); i get the correct result but when the following code runs i get an error.
Code
$bd = $fbme['birthday'];
$datearr = "0";$month = "0"; $date = "0"; $year = "0";
$datearr = explode('-', $bd);
list($month,$date,$year) = $datearr;
echo($month);
Error :
Notice: Undefined offset: 2 in C:\wamp......\index.php on line 30
Notice: Undefined offset: 1 in C:\wamp.....\index.php on line 30
Could you please suggest the reason and why this is occuring, any way how to get rid of this. Thanks a lot!!
The string stored in $fbme['birthday'] does not contain any '-' chars. Most likely it is empty. Check where $fbme is populated and an actual birthday is present.

Categories