Unknown property (w)

2019-07-26 04:31发布

问题:

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...

回答1:

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



标签: php nginx