首先,我搜索了类似的主题,但我无法找到问题的答案。所以我有一个重复发生事件的事件管理器。我想将重复事件的每个实例的开始日期存储到正在进行的事件中。
目标:
array (size=5)
0 =>
object(DateTime)[288]
public 'date' => string '2015-08-11 14:30:00' (length=19)
public 'timezone_type' => int 3
public 'timezone' => string 'UTC' (length=3)
1 =>
object(DateTime)[288]
public 'date' => string '2015-08-18 14:30:00' (length=19)
public 'timezone_type' => int 3
public 'timezone' => string 'UTC' (length=3)
2 =>
object(DateTime)[288]
public 'date' => string '2015-08-25 14:30:00' (length=19)
public 'timezone_type' => int 3
public 'timezone' => string 'UTC' (length=3)
3 =>
object(DateTime)[288]
public 'date' => string '2015-09-01 14:30:00' (length=19)
public 'timezone_type' => int 3
public 'timezone' => string 'UTC' (length=3)
我得到了什么:
array (size=5)
0 =>
object(DateTime)[288]
public 'date' => string '2015-09-01 14:30:00' (length=19)
public 'timezone_type' => int 3
public 'timezone' => string 'UTC' (length=3)
1 =>
object(DateTime)[288]
public 'date' => string '2015-09-01 14:30:00' (length=19)
public 'timezone_type' => int 3
public 'timezone' => string 'UTC' (length=3)
2 =>
object(DateTime)[288]
public 'date' => string '2015-09-01 14:30:00' (length=19)
public 'timezone_type' => int 3
public 'timezone' => string 'UTC' (length=3)
3 =>
object(DateTime)[288]
public 'date' => string '2015-09-01 14:30:00' (length=19)
public 'timezone_type' => int 3
public 'timezone' => string 'UTC' (length=3)
简而言之,当代码在循环中运行时,数组中的所有先前值都会被最后指定的值覆盖。
代码:
class Model_Event {
private $post_id;
private $count;
private $instances;
public function __construct( $post_id ) {
$this->post_id = $post_id;
$this->count = (int) 0;
$this->instances = array();
$this->fetch_instances();
}
private function fetch_instances() {
// Abort if no starting date defined.
if ( !$this->has_date() )
return;
// Set the original instance.
$this->instances[ $this->count ] = $this->datetime( 'both', 'from', false, true );
// Abort if event not repeating.
if ( !$this->is_repeating() )
return;
while ( !$this->is_stop_reached( $this->instances[ $this->count ], $this->count ) && $this->is_instance_started( $this->instances[ $this->count ] ) ) :
$this->instances[ $this->count + 1 ] = $this->next_instance( $this->instances[ $this->count ] );
$this->count++;
endwhile;
var_dump($this->instances);
return;
}
private function next_instance( DateTime $dateObject ) {
if ( $this->repeat_unit() === 'h' )
return $this->add_hours( $this->repeat_value(), $dateObject );
if ( $this->repeat_unit() === 'd' )
return $this->add_days( $this->repeat_value(), $dateObject );
if ( $this->repeat_unit() === 'w' )
return $this->add_weeks( $this->repeat_value(), $dateObject );
if ( $this->repeat_unit() === 'm' )
return $this->add_months( $this->repeat_value(), $dateObject );
if ( $this->repeat_unit() === 'y' )
return $this->add_years( $this->repeat_value(), $dateObject );
}
/**
* Currently only testing on "repeat every X weeks".
*/
private function add_weeks( $weeks, DateTime $dateObject ) {
return $dateObject->modify('+'.$weeks.' week');
}
...
}
我试图解决这个问题超过5个小时,似乎无法解决这个问题。谢谢。
答案 0 :(得分:1)
我发现问题出在以下几行:
$this->instances[ $this->count + 1 ] = $this->next_instance( $this->instances[ $this->count ] );
@J Santosh和this answer让我意识到,新实例不是复制所分配对象的内容,而是指向旧实例,依此类推,因此所有先前的对象都会被覆盖。所以我不得不改变这一行:
$this->instances[ $this->count + 1 ] = $this->next_instance( clone $this->instances[ $this->count ] );
clone方法可以防止对象被覆盖,因此我现在可以获得所需的输出。