[]で値を追加する前にPHP配列を宣言する必要がありますか?


85
$arr = array(); // is this line needed?
$arr[] = 5;

最初の行がなくても機能することは知っていますが、実際には含まれていることがよくあります。

理由は何ですか?それなしでは安全ではありませんか?

私はあなたもこれを行うことができることを知っています:

 $arr = array(5);

しかし、私はあなたがアイテムを一つずつ追加する必要がある場合について話している。


2
宣言されていない変数に関する通知が気に入らない限り、初期化することをお勧めします。さらに、それは読みやすいコードを作成するだけです($foo = array()それが配列に変換された文字列ではなかったことは明らかですなど)。
Brad Christie

6
@Brad Christie:それがそのような通知をトリガーしないことを除いて。
BoltClock

3
@BoltClock:作業しているバージョンによって異なります
Brad Christie

回答:


92

新しい配列を宣言せず、配列を作成/更新するデータが何らかの理由で失敗した場合、その配列を使用しようとする将来のコードは E_FATAL存在しないため、配列。

たとえばforeach()、配列が宣言されておらず、値が追加されていない場合、エラーがスローされます。ただし、宣言した場合のように、配列が単に空の場合はエラーは発生しません。


foreach例とエラーがトリガーされるという事実は、実行しているPHPのバージョンに明らかに依存しているため、賛成です。
チャールズスプレーベリー2011年

1
私はその答えを理解していません。宣言されておらず、何かが追加されていないということは、ソースコードに書き込まなかったことを意味します。
ゴードン

2
@ Gordon、$ somethingが1と等しくない場合に正しく機能しないものの例:if($ something == 1){$ rows [] = "a"; $ rows [] = "b"; } foreach($ rows as $ row){} $ rowsが$ rows = array();として宣言されていれば、エラーを回避できたはずです。ifステートメントが発生する前。
djdy 2011年

1
私は同意します(私は投票しました)が、人生は短すぎて、それが「正しい」ことであるとわかっていても、常にすべてを宣言することはできません。あるいは、宣言されていない配列が心配な場合は、is_array()を使用できると思います。ほとんどのもののように、詳細に依存します。
PJ Brunet 2012

25

PHPドキュメントがarrays実際にドキュメントでこれについて話していることを指摘したかっただけです。

PHPサイトから、コードスニペットを添付して:

$arr[key] = value;
$arr[] = value;
// key may be an integer or string
// value may be any value of any type

$arrまだ存在しない場合は作成されるので、これはアレイを作成するための代替方法でもあります。」

しかし、他の回答が述べているように...そうしないとあらゆる種類の悪いことが起こる可能性があるため、変数の値を宣言する必要があります。


14

PHPは緩く型付けされた言語です。それは完全に受け入れられます。そうは言っても、本物のプログラマは常に変数を宣言します。


1
@Gordonはまさに私が考えていたものです;)
AlienWebguy 2011年

申し訳ありませんが、「実際の」プログラムは、99%の確率で変数を宣言する必要がないようにコーディングされています。そして通常、nullなどの潜在的な空のデータを処理するオブジェクトを使用します
James

クールな話仲間。
AlienWebguy

7

あなたの後に来るコーダーのことを考えてください!が表示されただけでは$arr[] = 5$arrスコープ内の前述のすべてのコードを読み取らなければ、何が起こるかわかりません。明示的な$arr = array()行はそれを明確にします。


2
PHP 5.4.x-5.6.xの場合:$ arr = []も機能します。
Anthony Rutledge 2015

4

それは良い習慣です。ループ内で配列に追加していたが(かなり一般的な方法)、ループ外で配列にアクセスしたとします。配列宣言がないと、ループに参加しなかった場合、コードはエラーをスローします。


3

値を追加する前に配列を宣言することを強くお勧めします。上記のすべてに加えて、配列がループ内にある場合、意図せずに要素を配列にプッシュする可能性があります。私はこれがコストのかかるバグを作成しているのを観察しました。

//Example code    
foreach ($mailboxes as $mailbox){
       //loop creating email list to get
       foreach ($emails as $email){
          $arr[] = $email;
       }
       //loop to get emails
       foreach ($arr as $email){
       //oops now we're getting other peoples emails
       //in other mailboxes because we didn't initialize the array
       }
}

何しないの?
ryanve 2017

1

使用する前に配列を宣言しないと、実際に問題が発生する可能性があります。私が見つけた1つの経験では、このテストスクリプトを次のように呼び出しました。indextest.php?file = 1STLSPGTGUSこれは期待どおりに機能します。

//indextest.php?file=1STLSPGTGUS
$path['templates']     = './mytemplates/';
$file['template']      = 'myindex.tpl.php';
$file['otherthing']      = 'otherthing';
$file['iamempty']    = '';

print ("path['templates'] = " . $path['templates'] . "<br>");
print ("file['template'] = " . $file['template'] . "<br>");
print ("file['otherthing'] = " . $file['otherthing'] . "<br>");
print ("file['iamempty'] = " . $file['iamempty'] . "<br>");

print ("file['file'] = " . $file['file'] . "<br>");// should give: "Notice: Undefined index: file"
print ("file = " . $file);// should give: "Notice: Undefined index: file"

//the Output is:
/*
path['templates'] = ./mytemplates/
file['template'] = myindex.tpl.php
file['otherthing'] = otherthing
file['iamempty'] =

Notice: Undefined index: file in D:\Server\Apache24\htdocs\DeliverText\indextest.php on line 14
file['file'] =

Notice: Array to string conversion in D:\Server\Apache24\htdocs\DeliverText\indextest.php on line 15
file = Array
*/

今度は、購入した別のスクリプトのファイルを上部に必要とします。配列$ pathが正常であるのに、配列$ fileの値が完全に間違っていることがわかります。「checkgroup.php」が有罪です。

//indextest.php?file=1STLSPGTGUS
require_once($_SERVER['DOCUMENT_ROOT']."/IniConfig.php");
$access = "PUBLIC";
require_once(CONFPATH . "include_secure/checkgroup.php");
$path['templates']     = './mytemplates/';
$file['template']      = 'myindex.tpl.php';
$file['otherthing']      = 'otherthing.php';
$file['iamempty']    = '';

print ("path['templates'] = " . $path['templates'] . "<br>");
print ("file['template'] = " . $file['template'] . "<br>");
print ("file['otherthing'] = " . $file['otherthing'] . "<br>");
print ("file['iamempty'] = " . $file['iamempty'] . "<br>");

print ("file['file'] = " . $file['file'] . "<br>");
print ("file = " . $file);

//the Output is:
/*
path['templates'] = ./mytemplates/
file['template'] = o
file['otherthing'] = o
file['iamempty'] = o
file['file'] = o
file = oSTLSPGTGUS
*/

前に配列を初期化してから、問題ありません!

//indextest.php?file=1STLSPGTGUS
require_once($_SERVER['DOCUMENT_ROOT']."/IniConfig.php");
$access = "PUBLIC";
require_once(CONFPATH . "include_secure/checkgroup.php");

$path = array();
$file = array();

$path['templates']     = './mytemplates/';
$file['template']      = 'myindex.tpl.php';
$file['otherthing']      = 'otherthing.php';
$file['iamempty']    = '';

print ("path['templates'] = " . $path['templates'] . "<br>");
print ("file['template'] = " . $file['template'] . "<br>");
print ("file['otherthing'] = " . $file['otherthing'] . "<br>");
print ("file['iamempty'] = " . $file['iamempty'] . "<br>");

print ("file['file'] = " . $file['file'] . "<br>");
print ("file = " . $file);

//the Output is:
/*
path['templates'] = ./mytemplates/
file['template'] = myindex.tpl.php
file['otherthing'] = otherthing.php
file['iamempty'] =
file['file'] =
file = Array
*/

後でどのような問題が発生するかわからないため、変数を初期化することがいかに重要であるかを理解しました。時間を節約したいだけで、最終的にはさらに無駄になる可能性があります。私のように専門家ではない人にも役立つことを願っています。


1

古い質問ですが、これは配列が宣言されていない場合にコードが単純になる1つのユースケースであるため、これを共有します。

プロパティの1つでインデックスを作成する必要があるオブジェクトのリストがあるとします。

// $list is array of objects, all having $key property.
$index = [];
foreach ($list as $item)
    $index[$item->key][] = $item; // Dont care if $index[$item->key] already exists or not.

0

エラーチェックによって異なります。strictに関するエラー報告がある場合は通知が表示されますが、それがなくても技術的には機能するはずです。


0

グローバル変数として必要な場合や、同じ配列を異なる関数で何度も再利用したい場合に適しています。


0

これはあなたのコードです

$var[]  = 2;
print_r($var)

正常に動作します!誰かがあなたの魅力的なコードの前に同じ変数名を宣言するまで

$var = 3; 

$var[]  = 2;
print_r($var)

警告:スカラー値を配列として使用することはできません

おっと!

これは考えられる(予測できない場合もある)ケースの1つであるため、はい$var = array()が必要です。

$var = 3;
$var = array();
$var[]  = 2;
print_r($var)

出力

Array
(
    [0] => 2
)

0

foreachデータがわからない場合のforループでは、次のように実行できます。

foreach($users ?? [] as $user) {
    // Do things with $user
}

$usersが設定されていない場合(null合体が設定されている場合isset($users))、空の配列が取得されるため、[]ループするforeachものがないため、PHPはループしません-エラー、警告、または通知はありません。

コメント/回答の一部に同意しません。ある種のセーフティネットとして、単に空の配列を宣言したり、変数を初期化したりする必要はないと思います。そのようなアプローチは私の意見では悪いプログラミングです。必要なときに明示的に実行してください。

正直なところ、空の配列を初期化する必要がある場合は、コードをより適切に構造化できるかどうか、後でデータをチェックする方法などを検討してください。

次のコードは無意味であり、「意図」を示していないため、初期化された理由について人々を混乱させる可能性があります(せいぜい、読んで処理するのは無意味なものです)。

$user = [];
$user['name'] = ['bob'];

2行目も新しい配列を宣言しており、失敗することはありません。


-3

@djdyに同意します。投稿したい選択肢の1つです。

<?php

// Passed array is empty, so we'll never have $items variable available.
foreach (array() AS $item)
    $items[] = $item;

isset($items) OR $items = array(); // Declare $items variable if it doesn't exist

?>

1
このすべてのポイントは何ですか?文字通り何もないことについては大騒ぎのようです。
BoltClock

$ items変数を事前に宣言する代わりに、ループの存在を確認します。それだけです。
Otar 2011年

array()空の配列です、foreach何もしませんか?
James
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.