1
0
mirror of https://github.com/php/doc-ja.git synced 2026-04-24 00:18:15 +02:00
Files
archived-doc-ja/language/types/array.xml
T
2021-02-23 21:51:51 +09:00

1256 lines
36 KiB
XML

<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision$ -->
<!-- EN-Revision: 529359031bc69c5f635a459ae3891df4b8dc8df9 Maintainer: takagi Status: ready -->
<!-- CREDITS: hirokawa,shimooka,mumumu -->
<sect1 xml:id="language.types.array">
<title>配列</title>
<para>
PHP の配列は、実際には順番付けられたマップです。マップは型の一種で、
<emphasis></emphasis><emphasis>キー</emphasis>に関連付けます。
この型は、さまざまな使い道にあわせて最適化されます。
配列としてだけでなく、リスト (ベクター)、
ハッシュテーブル (マップの実装の一つ)、辞書、コレクション、スタック、
キュー等として使用することが可能です。
PHP の配列には他の PHP 配列を値として保持することができるため、
非常に簡単にツリー構造を表現することが可能です。
</para>
<para>
これらのデータ構造に関する説明は本マニュアルの範囲を超えるので省略しますが、
各々について、少なくとも一つは例を示します。
この分野は広範囲にまたがり、さまざまな文献が存在します。
より詳細な情報については、それらの文献を参照ください。
</para>
<sect2 xml:id="language.types.array.syntax">
<title>構文</title>
<sect3 xml:id="language.types.array.syntax.array-func">
<title><function>array</function> で指定</title>
<para>
<type>配列</type> は、言語に組み込まれた
<function>array</function> で作成することが可能です。この構造は、
特定の数のカンマで区切られた
<literal><replaceable>キー</replaceable> =&gt; <replaceable
></replaceable></literal> の組を引数とします。
</para>
<synopsis>
array(
<optional><replaceable>key</replaceable> =&gt; </optional><replaceable>value</replaceable>,
<optional><replaceable>key2</replaceable> =&gt; </optional><replaceable>value2</replaceable>,
<optional><replaceable>key3</replaceable> =&gt; </optional><replaceable>value3</replaceable>,
...
)</synopsis>
<!-- Do not fix the whitespace for the synopsis end element. A limitation of PhD prevents proper trimming -->
<para>
最後の要素のあとのカンマは、書いても書かなくてもかまいません。
配列を一行で定義する場合は、ふつうは最後のカンマを省略します。つまり、
<literal>array(1, 2)</literal> のほうが
<literal>array(1, 2, )</literal> よりおすすめだということです。
しかし複数行で定義する場合は、最後のカンマをつけることが一般的です。
そうしておけば、配列の最後に要素を追加するのが容易になるからです。
</para>
<note>
<para>
<literal>array()</literal><literal>[]</literal>
で置き換えることが出来る、配列の短縮構文も使えます。
</para>
</note>
<example>
<title>シンプルな配列定義</title>
<programlisting role="php">
<![CDATA[
<?php
$array = array(
"foo" => "bar",
"bar" => "foo",
);
// 配列の短縮構文
$array = [
"foo" => "bar",
"bar" => "foo",
];
?>
]]>
</programlisting>
</example>
<para>
<varname>key</varname> は、<type>整数</type> または
<type>文字列</type>です。
<replaceable>value</replaceable> には任意の型を指定できます。
</para>
<para xml:id="language.types.array.key-casts">
さらに、次のような <replaceable>key</replaceable> のキャストが発生します。
<itemizedlist>
<listitem>
<simpara>
10 進数の <type>int</type> として妥当な形式の <type>String</type> は、
数値の前に <literal>+</literal> 記号がついていない限り、
<type>int</type> 型にキャストされます。
つまり、キーに <literal>"8"</literal> を指定すると、実際には
<literal>8</literal> として格納されるということです。一方 <literal>"08"</literal>
はキャストされません。これは十進数として妥当な形式ではないからです。
</simpara>
</listitem>
<listitem>
<simpara>
<type>float</type>s もまた <type>int</type> にキャストされます。つまり、
小数部分は切り捨てられるということです。たとえばキーに <literal>8.7</literal> を指定すると、実際には
<literal>8</literal> として格納されます。
</simpara>
</listitem>
<listitem>
<simpara>
<type>bool</type><type>int</type> にキャストされます。つまり、
キーに <literal>true</literal> を指定すると実際には <literal>1</literal> に格納され、
同様にキーを <literal>false</literal> とすると実際には <literal>0</literal> となります。
</simpara>
</listitem>
<listitem>
<simpara>
<type>Null</type> は空文字列にキャストされます。つまり、キーに
<literal>null</literal> を指定すると、実際には <literal>""</literal> として格納されます。
</simpara>
</listitem>
<listitem>
<simpara>
<type>array</type><type>object</type> は、キーとして<emphasis>使えません</emphasis>
キーとして使おうとすると <literal>Illegal offset type</literal> という警告が発生します。
</simpara>
</listitem>
</itemizedlist>
</para>
<para>
配列の宣言時に同じキーで複数の要素を指定すると、
最後に指定したものがそれまでの値を上書きします。
</para>
<example>
<title>型のキャストと値の上書きの例</title>
<programlisting role="php">
<![CDATA[
<?php
$array = array(
1 => "a",
"1" => "b",
1.5 => "c",
true => "d",
);
var_dump($array);
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
array(1) {
[1]=>
string(1) "d"
}
]]>
</screen>
<para>
上の例では、すべてのキーが <literal>1</literal> にキャストされます。
そして後から指定した値がどんどん前の値を上書きしていき、最終的には最後に代入された
<literal>"d"</literal> だけが残ります。
</para>
</example>
<para>
PHP においては添字配列と連想配列の間に違いはなく、配列型は 1 つだけで、
同じ配列で整数のインデックスと文字列のインデックスを同時に使えます。
</para>
<example>
<title>整数と文字列のキーの混在例</title>
<programlisting role="php">
<![CDATA[
<?php
$array = array(
"foo" => "bar",
"bar" => "foo",
100 => -100,
-100 => 100,
);
var_dump($array);
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
array(4) {
["foo"]=>
string(3) "bar"
["bar"]=>
string(3) "foo"
[100]=>
int(-100)
[-100]=>
int(100)
}
]]>
</screen>
</example>
<para>
<replaceable>key</replaceable> はオプションです。省略した場合、PHP
はこれまでに使われた整数のキーの中で最大のものに 1 を加えた値を使います。
</para>
<example>
<title>数値添字配列でキーを省略する例</title>
<programlisting role="php">
<![CDATA[
<?php
$array = array("foo", "bar", "hello", "world");
var_dump($array);
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
array(4) {
[0]=>
string(3) "foo"
[1]=>
string(3) "bar"
[2]=>
string(5) "hello"
[3]=>
string(5) "world"
}
]]>
</screen>
</example>
<para>
一部の要素にだけキーを指定することもできます。
</para>
<example>
<title>一部の要素にだけキーを指定する例</title>
<programlisting role="php">
<![CDATA[
<?php
$array = array(
"a",
"b",
6 => "c",
"d",
);
var_dump($array);
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
array(4) {
[0]=>
string(1) "a"
[1]=>
string(1) "b"
[6]=>
string(1) "c"
[7]=>
string(1) "d"
}
]]>
</screen>
<para>
ごらんの通り、最後の値である <literal>"d"</literal> のキーは
<literal>7</literal> となります。それまでにキーとして使われた最大の整数が
<literal>6</literal> だからです。
</para>
</example>
<example>
<title>複雑な型のキャストと上書きの例</title>
<para>
以下の例は、型のキャストされた時と、要素が上書きされる時の全ての場合を示しています。
</para>
<programlisting role="php">
<![CDATA[
<?php
$array = array(
1 => "a",
"1" => "b", // 値 "a" は "b" で上書きされます。
1.5 => "c", // 値 "b" は "c" で上書きされます。
-1 => 'd',
"01" => "e",
true => "f", // 値 "c" は "f" で上書きされます。
false => 'g',
'' => 'h',
null => 'i', // 値 "h" は "i" で上書きされます。
'j', // 値 "j" はキー 2 が割り当てられます。なぜならこれより前の最大の整数のキーは1だからです。
2 => 'k', // 値 "j" は "k" で上書きされます。
);
var_dump($array);
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
array(6) {
[1]=>
string(1) "f"
[-1]=>
string(1) "d"
["01"]=>
string(1) "e"
[0]=>
string(1) "g"
[""]=>
string(1) "i"
[2]=>
string(1) "k"
}
]]>
</screen>
</example>
</sect3>
<sect3 xml:id="language.types.array.syntax.accessing">
<title>角括弧構文による配列要素へのアクセス</title>
<para>
配列の要素へのアクセスには <literal>array[key]</literal> 構文を使います。
</para>
<example>
<title>配列の要素へのアクセス</title>
<programlisting role="php">
<![CDATA[
<?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"]);
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
string(3) "bar"
int(24)
string(3) "foo"
]]>
</screen>
</example>
<note>
<para>
角括弧と波括弧は、配列の要素にアクセスするときにはどちらも同じ意味で使えます
(つまり、この例で <literal>$array[42]</literal><literal>$array{42}</literal>
は同じものを表しているということです)。
</para>
</note>
<example>
<title>配列のデリファレンス</title>
<programlisting role="php">
<![CDATA[
<?php
function getArray() {
return array(1, 2, 3);
}
$secondElement = getArray()[1];
// または、このように書くことができます
list(, $secondElement) = getArray();
?>
]]>
</programlisting>
</example>
<note>
<para>
配列に定義されていないキーへアクセスしたときの挙動は、
未定義の変数にアクセスしたときと同じです。
<constant>E_NOTICE</constant> メッセージが発行され、
返される結果は &null; となります。
</para>
</note>
<note>
<para>
配列で文字列以外のスカラー値をデリファレンスした場合は、
返される結果は &null; となります。
PHP 7.4.0 より前のバージョンでは、何もエラーは発生しませんでした。
PHP 7.4.0 以降では、<constant>E_NOTICE</constant> が発生します。
PHP 8.0.0 以降では、<constant>E_WARNING</constant> が発生します。
</para>
</note>
</sect3>
<sect3 xml:id="language.types.array.syntax.modifying">
<title>角括弧構文で作成/修正</title>
<para>
明示的に値を設定することにより、既存の配列を修正することも可能です。
</para>
<para>
これは、角括弧の中にキーを指定し、配列に値を代入することにより行います。
キーを省略することも可能です。この場合、空の角括弧
("<literal>[]</literal>") の変数名として追加してください。
</para>
<synopsis>
$arr[<replaceable>キー</replaceable>] = <replaceable></replaceable>;
$arr[] = <replaceable></replaceable>;
// <replaceable>キー</replaceable><type>文字列</type> または
// <type>整数</type>のどちらかです。
// <replaceable></replaceable> の型は、何でもかまいません。
</synopsis>
<para>
<varname>$arr</varname> がまだ存在しない場合は、新しく作成します。
つまり、これは配列を作成する方法のひとつでもあります。
とはいえ、この方法を使うことはおすすめしません。なぜなら、既に
<varname>$arr</varname> に何らかの値
(リクエスト変数からの文字列など) が入っている場合にはその値がそのまま残り、
<literal>[]</literal> が実際には
<link linkend="language.types.string.substr">文字列アクセス演算子</link>
を表してしまうからです。
変数を初期化するときには、直接代入するほうがよいでしょう。
</para>
<note>
<simpara>
PHP 7.1.0 以降では、文字列に空のインデックス演算子を適用すると
fatal エラーが発生するようになりました。
これまでのバージョンではエラーにならず、文字列が配列に変換されていました。
</simpara>
</note>
<para>
ある値を変更するには、
新しい値に値を代入します。特定のキー/値の組を削除したい場合には、
<function>unset</function> を使用する必要があります。
</para>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$arr = array(5 => 1, 12 => 2);
$arr[] = 56; // このスクリプトのこの位置に記述した場合、
// $arr[13] = 56; と同じです
$arr["x"] = 42; // キー"x"の新しい要素を配列に追加します
unset($arr[5]); // 配列から要素を削除します
unset($arr); // 配列全体を削除します
?>
]]>
</programlisting>
</informalexample>
<note>
<para>
上記のように、キーを省略して新規要素を追加する場合、
追加される数値添字は、使用されている添字の最大値 +1 (ただし、少なくとも 0 以上) になります。
まだ数値添字が存在しない場合は、添字は <literal>0</literal>
(ゼロ) となります。
</para>
<warning>
<simpara>
PHP 4.3.0 以降、上記のような添字生成動作は変更されました。
現在では、配列に追加する際に、
その配列の最大添字が負である場合は次の添え字はゼロ
(<literal>0</literal>) となります。
以前は、正の添字の場合と同様に新しい添字は最大添字に +1
したものがセットされました。
</simpara>
</warning>
<para>
次のキー生成において、オフセットとして使われる整数値
(添字の最大値) に対応するエントリーが、
必ずしも配列内に存在するわけではないことに注意してください。
しかし、その値は、多くの場合、
配列にある整数のキー値の最大値と等しいはずです。以下に例を示します。
</para>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
// 簡単な配列を生成します。
$array = array(1, 2, 3, 4, 5);
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);
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
)
Array
(
)
Array
(
[5] => 6
)
Array
(
[0] => 6
[1] => 7
)
]]>
</screen>
</informalexample>
</note>
</sect3>
</sect2><!-- end syntax -->
<sect2 xml:id="language.types.array.useful-funcs">
<title>有用な関数</title>
<para>
配列で使用する便利な関数がたくさんあります。
<link linkend="ref.array">配列関数</link> の節を参照ください。
</para>
<note>
<para>
<function>unset</function>関数は配列のキーを削除することが出来ます。
ただし、これによってインデックスの再構築が行われるわけではないことに
注意してください。
"通常の整数添字" (0 から始まり、1 つずつ増加) のみを使用している場合、
<function>array_values</function>
を用いてインデックスを再構築することができます。
</para>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$a = array(1 => 'one', 2 => 'two', 3 => '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')となります
?>
]]>
</programlisting>
</informalexample>
</note>
<para>
配列専用の制御構造として &foreach; があります。
この構造は、配列の要素に簡単に連続的にアクセスする手段を提供します。
</para>
</sect2>
<sect2 xml:id="language.types.array.donts">
<title>配列ですべきこととしてはならないこと</title>
<sect3 xml:id="language.types.array.foo-bar">
<title>なぜ、<literal>$foo[bar]</literal> は使用できないのか?</title>
<para>
連想配列の添字の前後は常に引用符で括る必要があります。
例えば、$foo[bar] ではなく $foo['bar'] を使用してください。
しかし、$foo[bar] はなぜ誤りなのでしょうか?
古いスクリプトで次のような構文を見たことがあるかもしれません。
</para>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$foo[bar] = 'enemy';
echo $foo[bar];
// etc
?>
]]>
</programlisting>
</informalexample>
<para>
これは間違っていますが、動作します。では、なぜ間違っているのでしょう?
それは、このコードには文字列 (<literal>'bar'</literal> - 引用符で括られている)
ではなく未定義の定数 (<literal>bar</literal>) が使用されているためです。
下位互換性の維持のため、未定義の定数は同じ名前の文字列に自動的に変換されます。
そのため、このコードは動作します。
例えば、<constant>bar</constant> という名前の定義されていない定数があるとすると、
PHP は <literal>'bar'</literal> という文字列でそれを置換して使用します。
</para>
<warning>
<simpara>
生の文字列を未定義の定数として扱う振る舞いは、PHP 7.2.0
以降では推奨されなくなり、
<constant>E_WARNING</constant> レベルの警告が発生するようになりました。
それ以前のバージョンでは、<constant>E_NOTICE</constant>
レベルの警告が発生していました。
</simpara>
</warning>
<note>
<simpara>
これは、添字を<emphasis>常に</emphasis>クォートするという意味ではありません。
<link linkend="language.constants">定数</link>
<link linkend="language.variables">変数</link>
を添字として使う際には、クォートしてしまうと PHP
はそれを解釈できなくなってしまいます。
</simpara>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
error_reporting(E_ALL);
ini_set('display_errors', true);
ini_set('html_errors', false);
// 単純な配列
$array = array(1, 2);
$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";
}
?>
]]>
</programlisting>
</informalexample>
&example.outputs;
<screen>
<![CDATA[
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
]]>
</screen>
</note>
<para>
この具体例を以下に示します。
</para>
<informalexample>
<programlisting role="php">
<![CDATA[
<?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
?>
]]>
</programlisting>
</informalexample>
<para>
<function>error_reporting</function>
(<constant>E_ALL</constant> を指定する等により)
<literal>E_NOTICE</literal> レベルのエラー出力を有効にした場合、
上記のエラーが出力されます。
デフォルトでは、<link linkend="ini.error-reporting">
error_reporting</link> はこれらを表示しない設定になっています。
</para>
<para>
<link linkend="language.types.array.syntax"
>構文</link>の節に記述したように、角括弧
('<literal>[</literal>' および '<literal>]</literal>')
の間には、式がなければなりません。これは、
次のように書くことが可能であることを意味します。
</para>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
echo $arr[somefunc($bar)];
?>
]]>
</programlisting>
</informalexample>
<para>
これは、関数の戻り値を配列の添字として使用する例です。PHP
は定数についても認識します。以下のような <literal>E_*</literal>
の使用例を見たことがあるかもしれません。
</para>
<informalexample>
<programlisting role="php">
<![CDATA[
<?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";
?>
]]>
</programlisting>
</informalexample>
<para>
最初の例の <literal>bar</literal> と全く同様に
<constant>E_ERROR</constant> も有効な添字であることに注意してください。
しかし、実際には最後の例は次のように書くことと同じです。
</para>
<informalexample>
<programlisting role="php">
<![CDATA[
<?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";
?>
]]>
</programlisting>
</informalexample>
<para>
これは、<constant>E_ERROR</constant><literal>1</literal>
と等しいこと等によります。
</para>
<para>
では、なぜ <literal>$foo[bar]</literal> は動作することが可能なのでしょう?
それは、<literal>bar</literal> が定数式であることを
期待される構文で使用されているためです。しかし、この場合、
<literal>bar</literal> という名前の定数は存在しません。PHP は、
この場合、あなたが文字列<literal>"bar"</literal> のようにリテラル
<literal>bar</literal> を指定したが引用符を忘れたと仮定します。
</para>
<sect4 xml:id="language.types.array.foo-bar.why">
<title>では、なぜ間違っているのでしょう?</title>
<para>
将来的に、PHP 開発チームが他の定数またはキーワードを追加したいと思うかもしれず、
問題となる可能性があります。例えば、現在でも、
単語 <literal>empty</literal> および
<literal>default</literal>を使用することはできません。
これは、これらが特別な
<link linkend="reserved">予約済みのキーワード</link>であるためです。
</para>
<note>
<simpara>
二重引用符で括られた<type>文字列</type>の中では
引用符で配列の添字を括らないことができ、このため、
<literal>"$foo[bar]"</literal> は有効です。
この理由の詳細については、上記の例や
<link linkend="language.types.string.parsing">
文字列中での変数のパース</link>を参照してください。
</simpara>
</note>
</sect4>
</sect3>
</sect2>
<sect2 xml:id="language.types.array.casting">
<title>配列への変換</title>
<para>
<type>int</type>, <type>float</type>, <type>string</type>,
<type>bool</type>, <type>resource</type>のいずれの型においても、
<type>array</type> に変換する場合、
最初のスカラー値が割り当てられている一つの要素 (添字は 0)
を持つ配列を得ることになります。
</para>
<para>
<type>object</type>を配列にする場合には、配列の要素として
オブジェクトの属性 (メンバ変数) を持つ配列を得ることになります。
添字はメンバ変数名となりますが、いくつか注意すべき例外があります。
整数のプロパティはアクセス不能になります。
private 変数の場合、変数名の頭にクラス名がつきます。また、
protected 変数の場合は、変数名の頭に '*' がつきます。
このとき、頭に追加される値の前後に <literal>NUL</literal> バイトがついてきます。
</para>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
class A {
private $B;
protected $C;
public $D;
function __construct()
{
$this->{1} = null;
}
}
var_export((array) new A());
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
array (
'' . "\0" . 'A' . "\0" . 'B' => NULL,
'' . "\0" . '*' . "\0" . 'C' => NULL,
'D' => NULL,
1 => NULL,
)
]]>
</screen>
</informalexample>
<para>
これらの <literal>NUL</literal> バイトは、以下のような予期せぬ振る舞いをすることがあります:
</para>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
class A {
private $A; // これは '\0A\0A' となります
}
class B extends A {
private $A; // これは '\0B\0A' となります
public $AA; // これは 'AA' となります
}
var_dump((array) new B());
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
array(3) {
["BA"]=>
NULL
["AA"]=>
NULL
["AA"]=>
NULL
}
]]>
</screen>
</informalexample>
<para>
上の例では 'AA' というキーがふたつあるように見えますが、
そのうちひとつは、実際は '\0A\0A' ということになります。
</para>
<para>
&null; を配列に変換すると、空の配列を得ます。
</para>
</sect2>
<sect2 xml:id="language.types.array.comparing">
<title>比較</title>
<para>
<function>array_diff</function>
<link linkend="language.operators.array">配列演算子</link>
を用いると、配列を比較することができます。
</para>
</sect2>
<sect2 xml:id="language.types.array.examples">
<title></title>
<para>
PHP の配列型は、いろいろな使い方ができます。配列の強力な機能を示すため、
ここでいくつかの例を紹介します。
</para>
<informalexample>
<programlisting role="php">
<![CDATA[
<?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') となります
?>
]]>
</programlisting>
</informalexample>
<example>
<title>array() の使用例</title>
<programlisting role="php">
<![CDATA[
<?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();
?>
]]>
<!-- TODO example of
- overwriting keys
- using vars/functions as key/values
- warning about references
-->
</programlisting>
</example>
<example xml:id="language.types.array.examples.loop">
<title>コレクション</title>
<programlisting role="php">
<![CDATA[
<?php
$colors = array('red', 'blue', 'green', 'yellow');
foreach ($colors as $color) {
echo "Do you like $color?\n";
}
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
Do you like red?
Do you like blue?
Do you like green?
Do you like yellow?
]]>
</screen>
</example>
<para>
配列を参照渡しすることでその値を直接変更できます。
</para>
<example xml:id="language.types.array.examples.changeloop">
<title>ループ内での要素の変更</title>
<programlisting role="php">
<![CDATA[
<?php
foreach ($colors as &$color) {
$color = strtoupper($color);
}
unset($color); /* これ以降の $color への書き込みが
配列の要素を書き換えてしまわないことを保証する */
print_r($colors);
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
Array
(
[0] => RED
[1] => BLUE
[2] => GREEN
[3] => YELLOW
)
]]>
</screen>
</example>
<para>
この例は、1 から始まる配列を作成します。
</para>
<example>
<title>1 から始まる添字</title>
<programlisting role="php">
<![CDATA[
<?php
$firstquarter = array(1 => 'January', 'February', 'March');
print_r($firstquarter);
?>
]]>
</programlisting>
&example.outputs;
<screen>
<![CDATA[
Array
(
[1] => 'January'
[2] => 'February'
[3] => 'March'
)
]]>
</screen>
</example>
<example>
<title>配列に代入する</title>
<programlisting role="php">
<![CDATA[
<?php
// ディレクトリから全てのアイテムを配列に代入する
$handle = opendir('.');
while (false !== ($file = readdir($handle))) {
$files[] = $file;
}
closedir($handle);
?>
]]>
</programlisting>
</example>
<para>
配列には順番が付けられます。異なったソート関数を用いて順番を変更することも可能です。
より詳細な情報については、<link linkend="ref.array">配列関数</link> を参照ください。
<function>count</function> 関数を使用することで、
配列の要素数を数えることが可能です。
</para>
<example>
<title>配列のソート</title>
<programlisting role="php">
<![CDATA[
<?php
sort($files);
print_r($files);
?>
]]>
</programlisting>
</example>
<para>
配列の値は何でも良いため、その値を他の配列とすることも可能です。
これにより、再帰的な配列や多次元の配列を作成することが可能です。
</para>
<example>
<title>再帰および多次元配列</title>
<programlisting role="php">
<![CDATA[
<?php
$fruits = array ( "fruits" => array ( "a" => "orange",
"b" => "banana",
"c" => "apple"
),
"numbers" => array ( 1,
2,
3,
4,
5,
6
),
"holes" => array ( "first",
5 => "second",
"third"
)
);
// 上の配列の内容を取得するための例
echo $fruits["holes"][5]; // "second" を表示します
echo $fruits["fruits"]["a"]; // "orange" を表示します
unset($fruits["holes"][0]); // "first" を削除します
// 新しい多次元配列を作成します
$juices["apple"]["green"] = "good";
?>
]]>
</programlisting>
</example>
<para>
配列への代入においては、常に値がコピーされることに注意してください。
配列をリファレンスでコピーする場合には、
リファレンス演算子を使う必要があります。
</para>
<informalexample>
<programlisting role="php">
<![CDATA[
<?php
$arr1 = array(2, 3);
$arr2 = $arr1;
$arr2[] = 4; // $arr2 が変更されます。
// $arr1 は array(2,3) のままです。
$arr3 = &$arr1;
$arr3[] = 4; // $arr1 と $arr3 は同じ内容になります。
?>
]]>
</programlisting>
</informalexample>
</sect2>
</sect1>
<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->