PHP从while循环

时间:2015-09-05 08:08:48

标签: php arrays loops while-loop

首先,我搜索了类似的主题,但我无法找到问题的答案。所以我有一个重复发生事件的事件管理器。我想将重复事件的每个实例的开始日期存储到正在进行的事件中。

目标:

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个小时,似乎无法解决这个问题。谢谢。

1 个答案:

答案 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方法可以防止对象被覆盖,因此我现在可以获得所需的输出。