1

I'm getting this error on my nginx hosted server:

 Fatal error: TimeElapsedString(): Unknown property (w) in /var/www/script/system/framework.engine.php on line 51 

TimeElapsedString:

function TimeElapsedString($datetime, $full = false)
{
    date_default_timezone_set('UTC');

    $now = new DateTime;
    $ago = new DateTime($datetime);
    $diff = $now->diff($ago);

    $diff->w = floor($diff->d / 7); // LINE 51
    $diff->d -= $diff->w * 7;

    $string = array
    (
        'y' => 'year',
        'm' => 'month',
        'w' => 'week',
        'd' => 'day',
        'h' => 'hour',
        'i' => 'minute',
        's' => 'second',
    );

    foreach ($string as $k => &$v)
    {
        if ($diff->$k)
        {
            $v = $diff->$k . ' ' . $v . ($diff->$k > 1 ? 's' : '');
        }
        else
        {
            unset($string[$k]);
        }
    }

    if (!$full) $string = array_slice($string, 0, 1);
    return $string ? implode(', ', $string) . ' ago' : 'just now';
}

Everything just working perfect on the localhost (wamp) the php version in the hosted server is 5.3.3 so I ca'nt really see that problem. also I used this function in another nginx server and its also working without any problem.

the function is from this answer : Converting timestamp to time ago in PHP e.g 1 day ago, 2 days ago...

Community
  • 1
  • 1
Ido
  • 2,034
  • 1
  • 17
  • 16
  • 3
    Well, assigning properties to PHP Internal objects is usually a bad idea in the first place. Especially if the properties are not part of the official definition of the class ([DateInterval](http://www.php.net/manual/en/class.dateinterval.php)). DateInterval::d is an existing property. But DateInterval::w does not exist. Why are you attempting to assign it anyway?? – Tularis Feb 28 '14 at 00:16
  • 1
    http://stackoverflow.com/questions/1416697/converting-timestamp-to-time-ago-in-php-e-g-1-day-ago-2-days-ago – Ido Feb 28 '14 at 00:30

1 Answers1

6

As @Tularis said, it's because you can't assign new properties to PHP internal objects in PHP 5.3. This is because the DateTime method diff() returns an object and new object properties can not be created on the fly.

object(DateInterval)#8 (8) {
  ["y"]=>
  int(0)
  ["m"]=>
  int(6)
  ["d"]=>
  int(11)
  ["h"]=>
  int(9)
  ["i"]=>
  int(45)
  ["s"]=>
  int(10)
  ["invert"]=>
  int(1)
  ["days"]=>
  int(195)
}

To fix it, I converted $now->diff($then) into an array,

array(8) {
  ["y"]=>
  int(0)
  ["m"]=>
  int(6)
  ["d"]=>
  int(11)
  ["h"]=>
  int(9)
  ["i"]=>
  int(45)
  ["s"]=>
  int(10)
  ["invert"]=>
  int(1)
  ["days"]=>
  int(195)
}

and make the code reflect the changes by using $diff as an array rather than an object,

// Find how much time has elapsed since now()
// from: https://stackoverflow.com/a/18602474/235633
//
function timeElapsedSinceNow( $datetime, $full = false )
{
    $now = new DateTime;
    $then = new DateTime( $datetime );
    $diff = (array) $now->diff( $then );

    $diff['w']  = floor( $diff['d'] / 7 );
    $diff['d'] -= $diff['w'] * 7;

    $string = array(
        'y' => 'year',
        'm' => 'month',
        'w' => 'week',
        'd' => 'day',
        'h' => 'hour',
        'i' => 'minute',
        's' => 'second',
    );

    foreach( $string as $k => & $v )
    {
        if ( $diff[$k] )
        {
            $v = $diff[$k] . ' ' . $v .( $diff[$k] > 1 ? 's' : '' );
        }
        else
        {
            unset( $string[$k] );
        }
    }

    if ( ! $full ) $string = array_slice( $string, 0, 1 );
    return $string ? implode( ', ', $string ) . ' ago' : 'just now';
}

BTW, I believe OP's original question comes from this post where his issue went unanswered: https://stackoverflow.com/a/18602474/235633

Community
  • 1
  • 1
bafromca
  • 1,926
  • 4
  • 27
  • 42
  • I did answer the question, you can see that in comments: `Are you using PHP version 5.3.0 - 5.3.5? If you do, upgrade it :D or slightly modify the function.`, and OP was OK with this answer, he did not ask how to modify the function, so I assumed he knows how. And this is not v5.3.x error, but it doesn't work only on v5.3.0 - 5.3.5. And yes, great work converting object to array, this is `slightly modified function` :D – Glavić Sep 23 '15 at 06:11
  • Ah, sounds good! I just thought I'd write it out for him since our one business server is using PHP 5.3.3 and I ran into the same problem. Thanks for writing out the original function! – bafromca Sep 23 '15 at 16:18