PHP 5.4.31 Released

配列

PHP の配列は、実際には順番付けられたマップです。マップは型の一種で、 キーに関連付けます。 この型は、さまざまな使い道にあわせて最適化されます。 配列としてだけでなく、リスト (ベクター)、 ハッシュテーブル (マップの実装の一つ)、辞書、コレクション、スタック、 キュー等として使用することが可能です。 PHP の配列には他の PHP 配列を値として保持することができるため、 非常に簡単にツリー構造を表現することが可能です。

これらのデータ構造に関する説明は本マニュアルの範囲を超えるので省略しますが、 各々について、少なくとも一つは例を示します。 この分野は広範囲にまたがり、さまざまな文献が存在します。 より詳細な情報については、それらの文献を参照ください。

構文

array() で指定

配列 は、言語に組み込まれた array() で作成することが可能です。この構造は、 特定の数のカンマで区切られた キー => の組を引数とします。

array(
    key  => value,
    key2 => value2,
    key3 => value3,
    ...
)

最後の要素のあとのカンマは、書いても書かなくてもかまいません。 配列を一行で定義する場合は、ふつうは最後のカンマを省略します。つまり、 array(1, 2) のほうが array(1, 2, ) よりおすすめだということです。 しかし複数行で定義する場合は、最後のカンマをつけることが一般的です。 そうしておけば、配列の最後に要素を追加するのが容易になるからです。

PHP 5.4 以降では配列の短縮構文が追加され、 array() の代わりに [] を使えるようになりました。

例1 シンプルな配列定義

<?php
$array 
= array(
    
"foo" => "bar",
    
"bar" => "foo",
);

// PHP 5.4 ではこのようにも書けます
$array = [
    
"foo" => "bar",
    
"bar" => "foo",
];
?>

key は、整数 または 文字列です。 value には任意の型を指定できます。

さらに、次のような key のキャストが発生します。

  • integer として妥当な形式の文字列は integer 型にキャストされます。 つまり、キーに "8" を指定すると、実際には 8 として格納されるということです。一方 "08" はキャストされません。これは十進数として妥当な形式ではないからです。
  • floats もまた integer にキャストされます。つまり、 小数部分は切り捨てられるということです。たとえばキーに 8.7 を指定すると、実際には 8 として格納されます。
  • boolinteger にキャストされます。つまり、 キーに true を指定すると実際には 1 に格納され、 同様にキーを false とすると実際には 0 となります。
  • Null は空文字列にキャストされます。つまり、キーに null を指定すると、実際には "" として格納されます。
  • arrayobject は、キーとして使えません。 キーとして使おうとすると Illegal offset type という警告が発生します。

配列の宣言時に同じキーで複数の要素を指定すると、 最後に指定したものがそれまでの値を上書きします。

例2 型のキャストと値の上書きの例

<?php
$array 
= array(
    
1    => "a",
    
"1"  => "b",
    
1.5  => "c",
    
true => "d",
);
var_dump($array);
?>

上の例の出力は以下となります。

array(1) {
  [1]=>
  string(1) "d"
}

上の例では、すべてのキーが 1 にキャストされます。 そして後から指定した値がどんどん前の値を上書きしていき、最終的には最後に代入された "d" だけが残ります。

PHP においては添字配列と連想配列の間に違いはなく、配列型は 1 つだけで、 同じ配列で整数のインデックスと文字列のインデックスを同時に使えます。

例3 整数と文字列のキーの混在例

<?php
$array 
= array(
    
"foo" => "bar",
    
"bar" => "foo",
    
100   => -100,
    -
100  => 100,
);
var_dump($array);
?>

上の例の出力は以下となります。

array(4) {
  ["foo"]=>
  string(3) "bar"
  ["bar"]=>
  string(3) "foo"
  [100]=>
  int(-100)
  [-100]=>
  int(100)
}

key はオプションです。省略した場合、PHP はこれまでに使われた整数のキーの中で最大のものに 1 を加えた値を使います。

例4 数値添字配列でキーを省略する例

<?php
$array 
= array("foo""bar""hello""world");
var_dump($array);
?>

上の例の出力は以下となります。

array(4) {
  [0]=>
  string(3) "foo"
  [1]=>
  string(3) "bar"
  [2]=>
  string(5) "hello"
  [3]=>
  string(5) "world"
}

一部の要素にだけキーを指定することもできます。

例5 一部の要素にだけキーを指定する例

<?php
$array 
= array(
         
"a",
         
"b",
    
=> "c",
         
"d",
);
var_dump($array);
?>

上の例の出力は以下となります。

array(4) {
  [0]=>
  string(1) "a"
  [1]=>
  string(1) "b"
  [6]=>
  string(1) "c"
  [7]=>
  string(1) "d"
}

ごらんの通り、最後の値である "d" のキーは 7 となります。それまでにキーとして使われた最大の整数が 6 だからです。

角括弧構文による配列要素へのアクセス

配列の要素へのアクセスには array[key] 構文を使います。

例6 配列の要素へのアクセス

<?php
$array 
= array(
    
"foo" => "bar",
    
42    => 24,
    
"multi" => array(
         
"dimensional" => array(
             
"array" => "foo"
         
)
    )
);

var_dump($array["foo"]);
var_dump($array[42]);
var_dump($array["multi"]["dimensional"]["array"]);
?>

上の例の出力は以下となります。

string(3) "bar"
int(24)
string(3) "foo"

注意:

角括弧と波括弧は、配列の要素にアクセスするときにはどちらも同じ意味で使えます (つまり、この例で $array[42]$array{42} は同じものを表しているということです)。

PHP 5.4 以降では、関数やメソッドの返す結果を直接配列として扱えるようになりました。 以前は、いったん一次変数に代入しないと配列としては扱えませんでした。

PHP 5.5 以降では、配列リテラルをデリファレンスできるようになりました。

例7 配列のデリファレンス

<?php
function getArray() {
    return array(
123);
}

// PHP 5.4 ではこのように書けます。
$secondElement getArray()[1];

// 以前は、このようにするか
$tmp getArray();
$secondElement $tmp[1];

// あるいはこのようにしなければなりませんでした。
list(, $secondElement) = getArray();
?>

注意:

配列に定義されていないキーへアクセスしたときの挙動は、 未定義の変数にアクセスしたときと同じです。 E_NOTICE メッセージが発行され、 返される結果は NULL となります。

角括弧構文で作成/修正

明示的に値を設定することにより、既存の配列を修正することも可能です。

これは、角括弧の中にキーを指定し、配列に値を代入することにより行います。 キーを省略することも可能です。この場合、空の角括弧 ("[]") の変数名として追加してください。

$arr[キー] = ;
$arr[] = ;
// キー文字列 または
// 整数のどちらかです。
//  の型は、何でもかまいません。
   

$arr がまだ存在しない場合は、新しく作成します。 つまり、これは配列を作成する方法のひとつでもあります。 とはいえ、この方法を使うことはおすすめしません。なぜなら、既に $arr に何らかの値 (リクエスト変数からの文字列など) が入っている場合にはその値がそのまま残り、 [] が実際には 文字列アクセス演算子 を表してしまうからです。 変数を初期化するときには、直接代入するほうがよいでしょう。

ある値を変更するには、 新しい値に値を代入します。特定のキー/値の組を削除したい場合には、 unset() を使用する必要があります。

<?php
$arr 
= array(=> 112 => 2);

$arr[] = 56;    // このスクリプトのこの位置に記述した場合、
                // $arr[13] = 56; と同じです

$arr["x"] = 42// キー"x"の新しい要素を配列に追加します
                
unset($arr[5]); // 配列から要素を削除します

unset($arr);    // 配列全体を削除します
?>

注意:

上記のように、キーを省略して新規要素を追加する場合、 追加される数値添字は、使用されている添字の最大値 +1 (ただし、少なくとも 0 以上) になります。 まだ数値添字が存在しない場合は、添字は 0 (ゼロ) となります。

警告

PHP 4.3.0 以降、上記のような添字生成動作は変更されました。 現在では、配列に追加する際に、 その配列の最大添字が負である場合は次の添え字はゼロ (0) となります。 以前は、正の添字の場合と同様に新しい添字は最大添字に +1 したものがセットされました。

次のキー生成において、オフセットとして使われる整数値 (添字の最大値) に対応するエントリーが、 必ずしも配列内に存在するわけではないことに注意してください。 しかし、その値は、多くの場合、 配列にある整数のキー値の最大値と等しいはずです。以下に例を示します。

<?php
// 簡単な配列を生成します。
$array = array(12345);
print_r($array);

// 全てのアイテムを削除しますが、配列自体は削除しないでおきます。
foreach ($array as $i => $value) {
    unset(
$array[$i]);
}
print_r($array);

// アイテムを追加します(新しい添え字は0ではなく
// 5となることに注意)
$array[] = 6;
print_r($array);

// 添え字を振りなおします。
$array array_values($array);
$array[] = 7;
print_r($array);
?>

上の例の出力は以下となります。

Array
(
    [0] => 1
    [1] => 2
    [2] => 3
    [3] => 4
    [4] => 5
)
Array
(
)
Array
(
    [5] => 6
)
Array
(
    [0] => 6
    [1] => 7
)

有用な関数

配列で使用する便利な関数がたくさんあります。 配列関数 の節を参照ください。

注意:

unset()関数は配列のキーを削除することが出来ます。 ただし、これによってインデックスの再構築が行われるわけではないことに 注意してください。 "通常の整数添字" (0 から始まり、1 つずつ増加) のみを使用している場合、 array_values() を用いてインデックスを再構築することができます。

<?php
$a 
= array(=> 'one'=> 'two'=> 'three');
unset(
$a[2]);
/* これにより配列は以下の様に定義されます。
   $a = array(1 => 'one', 3 => 'three');
   以下ではありません:
   $a = array(1 => 'one', 2 =>'three');
*/

$b array_values($a);
// $b は、array(0 => 'one', 1 =>'three')となります
?>

配列専用の制御構造として foreach があります。 この構造は、配列の要素に簡単に連続的にアクセスする手段を提供します。

配列ですべきこととしてはならないこと

なぜ、$foo[bar] は使用できないのか?

連想配列の添字の前後は常に引用符で括る必要があります。 例えば、$foo[bar] ではなく $foo['bar'] を使用してください。 しかし、$foo[bar] はなぜ誤りなのでしょうか? 古いスクリプトで次のような構文を見たことがあるかもしれません。

<?php
$foo
[bar] = 'enemy';
echo 
$foo[bar];
// etc
?>

これは間違っていますが、動作します。では、なぜ間違っているのでしょう? その理由は、このコードには文字列 ('bar' - 引用符で括られている) ではなく未定義の定数 (bar) が使用されており、PHP が同じ名前の定数を不幸にして同じコードの中に定義する可能性があるためです。 下位互換性の維持のため、未定義の定数は同じ名前の文字列に自動的に変換されます。 そのため、このコードは動作します。 例えば、bar という名前の定義されていない定数があるとすると、 PHP は 'bar' という文字列でそれを置換して使用します。

注意: これは、添字を常にクォートするという意味ではありません。 定数変数 を添字として使う際には、クォートしてしまうと PHP はそれを解釈できなくなってしまいます。

<?php
error_reporting
(E_ALL);
ini_set('display_errors'true);
ini_set('html_errors'false);
// 単純な配列
$array = array(12);
$count count($array);
for (
$i 0$i $count$i++) {
    echo 
"\nChecking $i: \n";
    echo 
"Bad: " $array['$i'] . "\n";
    echo 
"Good: " $array[$i] . "\n";
    echo 
"Bad: {$array['$i']}\n";
    echo 
"Good: {$array[$i]}\n";
}
?>

上の例の出力は以下となります。

Checking 0: 
Notice: Undefined index:  $i in /path/to/script.html on line 9
Bad: 
Good: 1
Notice: Undefined index:  $i in /path/to/script.html on line 11
Bad: 
Good: 1

Checking 1: 
Notice: Undefined index:  $i in /path/to/script.html on line 9
Bad: 
Good: 2
Notice: Undefined index:  $i in /path/to/script.html on line 11
Bad: 
Good: 2

この具体例を以下に示します。

<?php
// エラーを全て表示するよう設定
error_reporting(E_ALL);

$arr = array('fruit' => 'apple''veggie' => 'carrot');

// 正しい
print $arr['fruit'];  // apple
print $arr['veggie']; // carrot

// 間違い。これは動作しますが、未定義の定数fruitを使用しているため、
// 同時にE_NOTICEレベルのPHPエラーを発生します
//
// Notice: Use of undefined constant fruit - assumed 'fruit' in...
print $arr[fruit];    // apple

// 検証のため、定数を定義してみましょう。
// fruitという名前の定数に値'veggie'を代入します。
define('fruit''veggie');

// ここでは、出力が異なることに注意してください。
print $arr['fruit'];  // apple
print $arr[fruit];    // carrot

// 以下は文字列の中であるためOKです。定数は、文字列の中では解釈されな
// いため、E_NOTICEエラーはここでは発生しません。
print "Hello $arr[fruit]";      // Hello apple

// 例外が1つあり、文字列の中で波括弧で配列を括った場合には、
// 定数が解釈されます
print "Hello {$arr[fruit]}";    // Hello carrot
print "Hello {$arr['fruit']}";  // Hello apple

// これは動作せず、以下のようなパースエラーを発生します:
// Parse error: parse error, expecting T_STRING' or T_VARIABLE' or T_NUM_STRING'
// 文字列の中でスーパーグローバルを使用した場合も無論同様です。
print "Hello $arr['fruit']";
print 
"Hello $_GET['foo']";

// 文字列結合で同じことをすることもできます。
print "Hello " $arr['fruit']; // Hello apple
?>

error_reporting() で (E_ALL を指定する等により) E_NOTICE レベルのエラー出力を有効にした場合、 上記のエラーが出力されます。 デフォルトでは、 error_reporting はこれらを表示しない設定になっています。

構文の節に記述したように、角括弧 ('[' および ']') の間には、式がなければなりません。これは、 次のように書くことが可能であることを意味します。

<?php
echo $arr[somefunc($bar)];
?>

これは、関数の戻り値を配列の添字として使用する例です。PHP は定数についても認識します。以下のような E_* の使用例を見たことがあるかもしれません。

<?php
$error_descriptions
[E_ERROR]   = "A fatal error has occurred";
$error_descriptions[E_WARNING] = "PHP issued a warning";
$error_descriptions[E_NOTICE]  = "This is just an informal notice";
?>

最初の例の bar と全く同様に E_ERROR も有効な添字であることに注意してください。 しかし、実際には最後の例は次のように書くことと同じです。

<?php
$error_descriptions
[1] = "A fatal error has occurred";
$error_descriptions[2] = "PHP issued a warning";
$error_descriptions[8] = "This is just an informal notice";
?>

これは、E_ERROR1 と等しいこと等によります。

では、なぜ $foo[bar] は動作することが可能なのでしょう? それは、bar が定数式であることを 期待される構文で使用されているためです。しかし、この場合、 bar という名前の定数は存在しません。PHP は、 この場合、あなたが文字列"bar" のようにリテラル bar を指定したが引用符を忘れたと仮定します。

では、なぜ間違っているのでしょう?

将来的に、PHP 開発チームが他の定数またはキーワードを追加したいと思うかもしれず、 問題となる可能性があります。例えば、現在でも、 単語 empty および defaultを使用することはできません。 これは、これらが特別な 予約済みのキーワードであるためです。

注意: 二重引用符で括られた文字列の中では 引用符で配列の添字を括らないことができ、このため、 "$foo[bar]" は有効です。 この理由の詳細については、上記の例や 文字列中での変数のパースを参照してください。

配列への変換

integer, float, string, boolean, resourceのいずれの型においても、 array に変換する場合、 最初のスカラー値が割り当てられている一つの要素 (添字は 0) を持つ配列を得ることになります。

objectを配列にする場合には、配列の要素として オブジェクトの属性 (メンバ変数) を持つ配列を得ることになります。 添字はメンバ変数名となりますが、いくつか注意すべき例外があります。 整数のプロパティはアクセス不能になります。 private 変数の場合、変数名の頭にクラス名がつきます。また、 protected 変数の場合は、変数名の頭に '*' がつきます。 このとき、頭に追加される値の前後に null バイトがついてきます。 その結果、予期せぬ振る舞いをすることがあります。

<?php

class {
    private 
$A// これは '\0A\0A' となります
}

class 
extends {
    private 
$A// これは '\0B\0A' となります
    
public $AA// これは 'AA' となります
}

var_dump((array) new B());
?>

上の例では 'AA' というキーがふたつあるように見えますが、 そのうちひとつは、実際は '\0A\0A' ということになります。

NULL を配列に変換すると、空の配列を得ます。

比較

array_diff()配列演算子 を用いると、配列を比較することができます。

PHP の配列型は、いろいろな使い方ができます。配列の強力な機能を示すため、 ここでいくつかの例を紹介します。

<?php
// これは、
$a = array( 'color' => 'red',
            
'taste' => 'sweet',
            
'shape' => 'round',
            
'name'  => 'apple',
            
4        // キーは0になります
          
);

$b = array('a''b''c');

// は、完全にこれと同じです。
$a = array();
$a['color'] = 'red';
$a['taste'] = 'sweet';
$a['shape'] = 'round';
$a['name']  = 'apple';
$a[]        = 4;        // キーは0になります

$b = array();
$b[] = 'a';
$b[] = 'b';
$b[] = 'c';

// 上のコードを実行すると、$a は次のような配列
// array('color' => 'red', 'taste' => 'sweet', 'shape' => 'round', 
// 'name' => 'apple', 0 => 4) となり、$b は
// array(0 => 'a', 1 => 'b', 2 => 'c') あるいは単に array('a', 'b', 'c') となります
?>

例8 array() の使用例

<?php
// マップを行う配列
$map = array( 'version'    => 4,
              
'OS'         => 'Linux',
              
'lang'       => 'english',
              
'short_tags' => true
            
);
            
// 数値キーのみを有する
$array = array( 7,
                
8,
                
0,
                
156,
                -
10
              
);
// これは、array( 0 => 7, 1 => 8, ...) と同じです

$switching = array(         10// key = 0
                    
5    =>  6,
                    
3    =>  7
                    
'a'  =>  4,
                            
11// key = 6 (最大の添字は5です)
                    
'8'  =>  2// key = 8 (整数!)
                    
'02' => 77// key = '02'
                    
0    => 12  // 値10は12で上書きされます
                  
);
                  
// 空の配列
$empty = array();         
?>

例9 コレクション

<?php
$colors 
= array('red''blue''green''yellow');

foreach (
$colors as $color) {
    echo 
"Do you like $color?\n";
}

?>

上の例の出力は以下となります。

Do you like red?
Do you like blue?
Do you like green?
Do you like yellow?

PHP 5 以降では、配列を参照渡しすることでその値を直接変更できるようになりました。 それ以前のバージョンでは、以下のような回避策が必要です。

例10 ループ内での要素の変更

<?php
// PHP 5
foreach ($colors as &$color) {
    
$color strtoupper($color);
}
unset(
$color); /* これ以降の $color への書き込みが
配列の要素を書き換えてしまわないことを保証する */

// 旧バージョンでの回避策
foreach ($colors as $key => $color) {
    
$colors[$key] = strtoupper($color);
}

print_r($colors);
?>

上の例の出力は以下となります。

Array
(
    [0] => RED
    [1] => BLUE
    [2] => GREEN
    [3] => YELLOW
)

この例は、1 から始まる配列を作成します。

例11 1 から始まる添字

<?php
$firstquarter  
= array(=> 'January''February''March');
print_r($firstquarter);
?>

上の例の出力は以下となります。

Array 
(
    [1] => 'January'
    [2] => 'February'
    [3] => 'March'
)

例12 配列に代入する

<?php
// ディレクトリから全てのアイテムを配列に代入する
$handle opendir('.');
while (
false !== ($file readdir($handle))) {
    
$files[] = $file;
}
closedir($handle); 
?>

配列には順番が付けられます。異なったソート関数を用いて順番を変更することも可能です。 より詳細な情報については、配列関数 を参照ください。 count() 関数を使用することで、 配列の要素数を数えることが可能です。

例13 配列のソート

<?php
sort
($files);
print_r($files);
?>

配列の値は何でも良いため、その値を他の配列とすることも可能です。 これにより、再帰的な配列や多次元の配列を作成することが可能です。

例14 再帰および多次元配列

<?php
$fruits 
= array ( "fruits"  => array ( "a" => "orange",
                                       
"b" => "banana",
                                       
"c" => "apple"
                                     
),
                  
"numbers" => array ( 1,
                                       
2,
                                       
3,
                                       
4,
                                       
5,
                                       
6
                                     
),
                  
"holes"   => array (      "first",
                                       
=> "second",
                                            
"third"
                                     
)
                );

// 上の配列の内容を取得するための例
echo $fruits["holes"][5];    // "second" を表示します
echo $fruits["fruits"]["a"]; // "orange" を表示します
unset($fruits["holes"][0]);  // "first"  を削除します

// 新しい多次元配列を作成します
$juices["apple"]["green"] = "good"
?>

配列への代入においては、常に値がコピーされることに注意してください。 配列をリファレンスでコピーする場合には、 リファレンス演算子を使う必要があります。

<?php
$arr1 
= array(23);
$arr2 $arr1;
$arr2[] = 4// $arr2 が変更されます。
             // $arr1 は array(2,3) のままです。
             
$arr3 = &$arr1;
$arr3[] = 4// $arr1 と $arr3 は同じ内容になります。
?>
add a note add a note

User Contributed Notes 21 notes

up
66
mlvljr
3 years ago
please note that when arrays are copied, the "reference status" of their members is preserved (http://www.php.net/manual/en/language.references.whatdo.php).
up
33
chris at ocportal dot com
1 year ago
Note that array value buckets are reference-safe, even through serialization.

<?php
$x
='initial';
$test=array('A'=>&$x,'B'=>&$x);
$test=unserialize(serialize($test));
$test['A']='changed';
echo
$test['B']; // Outputs "changed"
?>

This can be useful in some cases, for example saving RAM within complex structures.
up
44
ken underscore yap atsign email dot com
6 years ago
"If you convert a NULL value to an array, you get an empty array."

This turns out to be a useful property. Say you have a search function that returns an array of values on success or NULL if nothing found.

<?php $values = search(...); ?>

Now you want to merge the array with another array. What do we do if $values is NULL? No problem:

<?php $combined = array_merge((array)$values, $other); ?>

Voila.
up
3
note dot php dot lorriman at spamgourmet dot org
6 months ago
There is another kind of array (php>=  5.3.0) produced by

$array = new SplFixedArray(5);

Standard arrays, as documented here, are marvellously flexible and, due to the underlying hashtable, extremely fast for certain kinds of lookup operation.

Supposing a large string-keyed array

$arr=['string1'=>$data1, 'string2'=>$data2 etc....]

when getting the keyed data with

$data=$arr['string1'];

php does *not* have to search through the array comparing each key string to the given key ('string1') one by one, which could take a long time with a large array. Instead the hashtable means that php takes the given key string and computes from it the memory location of the keyed data, and then instantly retrieves the data. Marvellous! And so quick. And no need to know anything about hashtables as it's all hidden away.

However, there is a lot of overhead in that. It uses lots of memory, as hashtables tend to (also nearly doubling on a 64bit server), and should be significantly slower for integer keyed arrays than old-fashioned (non-hashtable) integer-keyed arrays. For that see more on SplFixedArray :

http://uk3.php.net/SplFixedArray

Unlike a standard php (hashtabled) array, if you lookup by integer then the integer itself denotes the memory location of the data, no hashtable computation on the integer key needed. This is much quicker. It's also quicker to build the array compared to the complex operations needed for hashtables. And it uses a lot less memory as there is no hashtable data structure. This is really an optimisation decision, but in some cases of large integer keyed arrays it may significantly reduce server memory and increase performance (including the avoiding of expensive memory deallocation of hashtable arrays at the exiting of the script).
up
42
jeff splat codedread splot com
9 years ago
Beware that if you're using strings as indices in the $_POST array, that periods are transformed into underscores:

<html>
<body>
<?php
    printf
("POST: "); print_r($_POST); printf("<br/>");
?>
<form method="post" action="<?php echo $_SERVER['PHP_SELF']; ?>">
    <input type="hidden" name="Windows3.1" value="Sux">
    <input type="submit" value="Click" />
</form>
</body>
</html>

Once you click on the button, the page displays the following:

POST: Array ( [Windows3_1] => Sux )
up
32
ia [AT] zoznam [DOT] sk
8 years ago
Regarding the previous comment, beware of the fact that reference to the last value of the array remains stored in $value after the foreach:

<?php
foreach ( $arr as $key => &$value )
{
   
$value = 1;
}

// without next line you can get bad results...
//unset( $value );

$value = 159;
?>

Now the last element of $arr has the value of '159'. If we remove the comment in the unset() line, everything works as expected ($arr has all values of '1').

Bad results can also appear in nested foreach loops (the same reason as above).

So either unset $value after each foreach or better use the longer form:

<?php
foreach ( $arr as $key => $value )
{
   
$arr[ $key ] = 1;
}
?>
up
16
ivegner at yandex dot ru
10 months ago
Note that objects of classes extending ArrayObject SPL class are treated as arrays, and not as objects when converting to array.

<?php
class ArrayObjectExtended extends ArrayObject
{
    private
$private = 'private';
    public
$hello = 'world';
}

$object = new ArrayObjectExtended();
$array = (array) $object;

// This will not expose $private and $hello properties of $object,
// but return an empty array instead.
var_export($array);
?>
up
32
lars-phpcomments at ukmix dot net
9 years ago
Used to creating arrays like this in Perl?

@array = ("All", "A".."Z");

Looks like we need the range() function in PHP:

<?php
$array
= array_merge(array('All'), range('A', 'Z'));
?>

You don't need to array_merge if it's just one range:

<?php
$array
= range('A', 'Z');
?>
up
24
caifara aaaat im dooaat be
8 years ago
[Editor's note: You can achieve what you're looking for by referencing $single, rather than copying it by value in your foreach statement. See http://php.net/foreach for more details.]

Don't know if this is known or not, but it did eat some of my time and maybe it won't eat your time now...

I tried to add something to a multidimensional array, but that didn't work at first, look at the code below to see what I mean:

<?php

$a1
= array( "a" => 0, "b" => 1 );
$a2 = array( "aa" => 00, "bb" => 11 );

$together = array( $a1, $a2 );

foreach(
$together as $single ) {
   
$single[ "c" ] = 3 ;
}

print_r( $together );
/* nothing changed result is:
Array
(
    [0] => Array
        (
            [a] => 0
            [b] => 1
        )
    [1] => Array
        (
            [aa] => 0
            [bb] => 11
        )
) */

foreach( $together as $key => $value ) {
   
$together[$key]["c"] = 3 ;
}

print_r( $together );

/* now it works, this prints
Array
(
    [0] => Array
        (
            [a] => 0
            [b] => 1
            [c] => 3
        )
    [1] => Array
        (
            [aa] => 0
            [bb] => 11
            [c] => 3
        )
)
*/

?>
up
0
Ray.Paseur often uses Gmail
12 days ago
Array-to-String conversion by assignment or by using an array in a string context gives a string of data that contains only the word, 'Array' and this data substitution often occurs silently.  This happens because the standard PHP installation suppresses Notice-level messages, and the array-to-string conversion, even though it causes data loss, is only considered a Notice condition.  Here is how to discern what PHP is doing.
http://php.net/manual/en/language.types.array.php
http://php.net/manual/en/language.types.string.php#language.types.string.casting

<?php // demo/array_to_string.php
/**
* Starting with the default standard error-level of E_ALL ~ E_NOTICE
* OUTPUTS:
* Array
*/
$xyz = array('X', 'Y', 'Z');
echo
$xyz;

/**
* Setting the error-level of E_ALL causes Notice messages to appear
* OUTPUTS:
* Notice: Array to string conversion in /path/to/demo/array_to_string.php on line XXX
* Array
*/
error_reporting(E_ALL);
$xyz = array('X', 'Y', 'Z');
echo
$xyz;
up
-1
martijntje at martijnotto dot nl
2 years ago
Please note that adding the magic __toString() method to your objects will not allow you to seek an array with it, it still throws an Illegal Offset warning.

The solution is to cast it to a string first, like this

$array[(string) $stringableObject]
up
-6
cromney at pointslope dot com
1 year ago
One thing to be careful of is making any assumptions about the underlying implementation with respect to performance. For example, the documentation talks about hash-maps, which might lead you to expect O(1) key lookups.

<?php

function find_val($n) {
 
$t = array();
 
$last = null;
 
  for (
$x = 0; $x < $n; $x++) {
   
$last = "" . $x;
   
$t[] = $last;
  }
 
 
var_dump(in_array($last, $t));


 
function
find_key($n) {
 
$t = array();
 
$last = null;
 
  for (
$x = 0; $x < $n; $x++) {
   
$last = "" . $x;
   
$t[$last] = true;
  }
 
 
var_dump(array_key_exists($last, $t));


$n = 1600000;

find_val($n);
// Time taken: 1123ms

find_key($n);
// Time taken: 803

/*

Additional Timings:

n        find_val(ms)  find_key(ms)
100000   99             82
200000   169            130
400000   301            217
800000   570            416
1600000  1123           803

*/
?>

In my tests, both in_array and array_key_exists exhibited the same order of growth.
up
-5
Anonymous
7 years ago
This page should include details about how associative arrays are implemened inside PHP; e.g. using hash-maps or b-trees.

This has important implictions on the permance characteristics of associative arrays and how they should be used; e.g. b-tree are slow to insert but handle collisions better than hashmaps.  Hashmaps are faster if there are no collisions, but are slower to retrieve when there are collisions.  These factors have implictions on how associative arrays should be used.
up
-6
Spudley
7 years ago
On array recursion...

Given the following code:

<?php
$myarray
= array('test',123);
$myarray[] = &$myarray;
print_r($myarray);
?>

The print_r() will display *RECURSION* when it gets to the third element of the array.

There doesn't appear to be any other way to scan an array for recursive references, so if you need to check for them, you'll have to use print_r() with its second parameter to capture the output and look for the word *RECURSION*.

It's not an elegant solution, but it's the only one I've found, so I hope it helps someone.
up
-9
harry at ddtechnologies dot com
1 year ago
PHP array_diff_assoc() Function

You can compare the keys and values of two arrays, and return the differences:

<?php
$a1
=array("red","green","blue","yellow");
$a2=array("red","green","blue");

$result=array_diff_assoc($a1,$a2);
print_r($result);
?>

http://www.show-ip.org
up
-17
Walter Tross
3 years ago
It is true that "array assignment always involves value copying", but the copy is a "lazy copy". This means that the data of the two variables occupy the same memory as long as no array element changes.

E.g., if you have to pass an array to a function that only needs to read it, there is no advantage at all in passing it by reference.
up
-20
gtisza at gmail dot com
1 year ago
Be very careful when using a result as an array. <?php echo $a['foo']['bar']['baz'] ?> will throw an error if $a is an object, and throw a warning if $a is an array but does not have the right keys, but it will silently return true if $a is null or boolean or int, and if $a is a string, it will return its first character. (This is true even with E_STRICT set.) This can be a major gotcha with functions which return null or false if they are unsuccessful.
up
-5
brta dot akos at gmail dot com
6 months ago
Why not to user one-based arrays:

<?php
$a 
= array(1 => 'a', 'b', 'd');
print_r($a);
array_splice($a,2,0,'c');
print_r($a);
?>

output:
Array ( [1] => a [2] => b [3] => d ) Array ( [0] => a [1] => b [2] => c [3] => d )
up
-7
ffe
6 months ago
<?php

error_reporting
(E_ALL);

$res=42;

echo(
"+".$res[0]."+".$res[10]."+");

$res[0]=1;

?>

The last line correctly states "Warning: Cannot use a scalar value as an array", but the echo produces +++ as output with no warning. This seems strange to me.
up
-59
carl at linkleaf dot com
6 years ago
Its worth noting that there does not appear to be any functional limitations on the length or content of string indexes. The string indexes for your arrays can contain any characters, including new line characters, and can be of any length:

<?php

$key
= "XXXXX";
$test = array($key => "test5");

for (
$x = 0; $x < 500; $x++) {
 
$key .= "X";
 
$value = "test" . strlen($key);
 
$test[$key] = $value;
}

echo
"<pre>";
print_r($test);
echo
"</pre>";

?>

Keep in mind that using extremely long array indexes is not a good practice and could cost you lots of extra CPU time. However, if you have to use a long string as an array index you won't have to worry about the length or content.
up
-37
azuleta at eycambiental dot com
10 months ago
I think there's a mistake in the las example:
...'<?php
$arr1
= array(2, 3);
$arr2 = $arr1;
$arr2[] = 4; // $arr2 ha cambiado,
             // $arr1 sigue siendo array(2, 3)
           
$arr3 = &$arr1;
$arr3[] = 4; // ahora $arr1 y $arr3 son iguales
?>'

I think it should be: ...'ahora $arr2 y $arr3 son iguales'...

Thanks.
To Top