[]로 값을 추가하기 전에 PHP 배열을 선언해야합니까?


84
$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 버전에 따라 분명히 다르기 때문에 찬성되었습니다 .
Charles Sprayberry

1
나는 그 대답을 이해하지 못한다. 선언되지 않았고 추가되지 않았다는 것은 내가 소스 코드에 쓰지 않았 음을 의미합니다.
Gordon

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

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는 느슨하게 입력 된 언어입니다. 완벽하게 받아 들여집니다. 즉, 실제 프로그래머는 항상 var를 선언합니다.


1
@Gordon 정확히 내가 생각했던 것;)
AlienWebguy 2011

죄송하지만 "실제"프로그램은 99 %의 시간 동안 vars를 선언 할 필요가없는 방식으로 코드를 작성합니다. 그리고 일반적으로 null과 같은 잠재적 인 빈 데이터를 처리하는 개체를 사용합니다
James

멋진 이야기 형제.
AlienWebguy

7

당신을 쫓는 코더들을 생각해보세요! 그냥 볼 경우 $arr[] = 5, 당신은 무엇 아무 생각이없는 $arr범위에서 모든 앞의 코드를 읽지 않고 될 수 있습니다. 명시적인 $arr = array()줄은 그것을 명확하게합니다.


2
PHP 5.4.x-5.6.x에서 : $ arr = []도 작동합니다.
Anthony Rutledge

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

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
*/

이제 내가 구입 한 다른 스크립트의 파일이 맨 위에 있어야합니다. 배열 $ file의 값이 완전히 잘못된 반면 array $ path는 괜찮습니다. "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

오래된 질문이지만 배열이 선언되지 않은 경우 코드가 더 간단한 사용 사례이므로 이것을 공유합니다.

속성 중 하나에 대해 인덱싱해야하는 개체 목록이 있다고 가정 해 보겠습니다.

// $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)

경고 : 스칼라 값을 배열로 사용할 수 없습니다.

이런!

이것은 하나의 가능한 (때로는 예측할 수없는) 경우이므로 예가 $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 coalesce does isset($users)) 빈 배열이 표시 []되므로 PHP는 foreach오류, 경고 또는 알림없이 루프 할 항목이 없으므로 루프 를 반복하지 않습니다.

나는 코멘트 / 답변의 일부에 동의하지 않습니다. 일종의 안전망과 같이 단순히 빈 배열을 선언하거나 변수를 초기화해야한다고 생각하지 않습니다. 이러한 접근 방식은 제 생각에는 나쁜 프로그래밍입니다. 필요할 때 명시 적으로 수행하십시오.

당신이 하늘의 배열을 초기화해야하는 경우 그리고, 솔직히 생각 코드가 잘 구성 할 수 있다면, 나중에 또는 어떤 데이터를 확인하는 방법.

다음 코드는 무의미합니다. "의도"를 나타내지 않고 왜 초기화되었는지에 대해 사람들을 혼동시킬 수 있습니다 (기껏해야 읽고 처리하는 것이 무의미합니다).

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

두 번째 줄도 새 배열을 선언하며 실패하지 않습니다.


-3

게시하고 싶은 대안 중 하나 인 @djdy에 동의합니다.

<?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.