PHPベストプラクティス >

自己参照

array

  • 自己参照が実現可能な環境においては、(arrayはオブジェクトではないので)比較などですべての要素の比較を行い、無限ループに陥います。要素の走査をする必要がある場合には注意しなければなりません。これは、オブジェクトの == による比較(フィールドそれぞれの比較になりますので)にも当てはまります*1
    $ php -r '$a = array(0,1); $a[] = $a; $b = $a; var_dump($a === $b);'
    
    Fatal error: Nesting level too deep - recursive dependency? in Command line code on line 1
    
    Call Stack:
        0.0002      59068   1. {main}() Command line code:0

5.2.0(Debian etch)

$ php -v
PHP 5.2.0-8+etch11 (cli) (built: May 10 2008 10:46:24)
Copyright (c) 1997-2006 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2006 Zend Technologies
    with Xdebug v2.0.2, Copyright (c) 2002-2007, by Derick Rethans
$ php -r '$a = array(0,1); $a[] = $a; var_dump($a);'
array(3) {
  [0]=>
  int(0)
  [1]=>
  int(1)
  [2]=>
  array(3) {
    [0]=>
    int(0)
    [1]=>
    int(1)
    [2]=>
    *RECURSION*
  }
}
$ php -r '$a = array(0,1); $a[] = $a; $a[0] = "mark"; var_dump($a);'
array(3) {
  [0]=>
  string(4) "mark"
  [1]=>
  int(1)
  [2]=>
  array(3) {
    [0]=>
    int(0)
    [1]=>
    int(1)
    [2]=>
    array(3) {
      [0]=>
      int(0)
      [1]=>
      int(1)
      [2]=>
      *RECURSION*
    }
  }
}
$ php -r '$a = array(0,1); $a[] = &$a; $a[0] = "mark"; var_dump($a);'
array(3) {
  [0]=>
  string(4) "mark"
  [1]=>
  int(1)
  [2]=>
  &array(3) {
    [0]=>
    string(4) "mark"
    [1]=>
    int(1)
    [2]=>
    &array(3) {
      [0]=>
      string(4) "mark"
      [1]=>
      int(1)
      [2]=>
      *RECURSION*
    }
  }
}

5.2.6(Debian lenny)

  • Suhosinパッチのためでしょうか。通常の要素代入では、ループしません。
    $ php -v
    PHP 5.2.6-3 with Suhosin-Patch 0.9.6.2 (cli) (built: Aug 21 2008 18:38:48)
    Copyright (c) 1997-2008 The PHP Group
    Zend Engine v2.2.0, Copyright (c) 1998-2008 Zend Technologies
        with Xdebug v2.0.2, Copyright (c) 2002-2007, by Derick Rethans
    $ php -r '$a = array(0,1); $a[] = $a; var_dump($a);'
    array(3) {
      [0]=>
      int(0)
      [1]=>
      int(1)
      [2]=>
      array(2) {
        [0]=>
        int(0)
        [1]=>
        int(1)
      }
    }
    $ php -r '$a = array(0,1); $a[] = $a; $a[0] = "mark"; var_dump($a);'
    array(3) {
      [0]=>
      string(4) "mark"
      [1]=>
      int(1)
      [2]=>
      array(2) {
        [0]=>
        int(0)
        [1]=>
        int(1)
      }
    }
    $ php -r '$a = array(0,1); $a[] = &$a; $a[0] = "mark"; var_dump($a);'
    array(3) {
      [0]=>
      string(4) "mark"
      [1]=>
      int(1)
      [2]=>
      &array(3) {
        [0]=>
        string(4) "mark"
        [1]=>
        int(1)
        [2]=>
        &array(3) {
          [0]=>
          string(4) "mark"
          [1]=>
          int(1)
          [2]=>
          *RECURSION*
        }
      }
    }

5.1.6(CentOS)

$ php -v
PHP 5.1.6 (cli) (built: Jul 16 2008 19:53:00)
Copyright (c) 1997-2006 The PHP Group
Zend Engine v2.1.0, Copyright (c) 1998-2006 Zend Technologies
    with Xdebug v2.0.3, Copyright (c) 2002-2007, by Derick Rethans
$ php -r '$a = array(0,1); $a[] = $a; var_dump($a);'
array(3) {
  [0]=>
  int(0)
  [1]=>
  int(1)
  [2]=>
  array(3) {
    [0]=>
    int(0)
    [1]=>
    int(1)
    [2]=>
    *RECURSION*
  }
}

*1 一方、=== によるオブジェクトの比較は、それぞれのリファレンスが同一のオブジェクトを指しているかを比較しますので、影響を受けません。

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2008-09-01 (月) 22:11:56 (3823d)