Чи потрібно оголошувати масив PHP перед додаванням значень за допомогою []?


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

Я знаю, що це працює без першого рядка, але це часто застосовується на практиці.

В чому причина? Без нього небезпечно?

Я знаю, що ви також можете зробити це:

 $arr = array(5);

але я говорю про випадки, коли вам потрібно додавати елементи по одному.


2
Якщо вам не подобаються повідомлення про незадекларовані змінні, я б рекомендував ініціалізувати. Крім того, він просто робить розбірливий код (зрозуміло, що $foo = array()і що це не був рядок, перетворений на масив тощо).
Бред Крісті

6
@Brad Christie: За винятком того, що таке сповіщення не викликає.
BoltClock

3
@BoltClock: Залежить від того, над якою версією ви працюєте .
Бред Крісті

Відповіді:


92

Якщо ви не оголошуєте новий масив, а дані, що створюють / оновлюють масив, не вдаються з будь-якої причини, тоді будь-який майбутній код, який намагається використовувати масив, буде, E_FATALоскільки масив не існує.

Наприклад, foreach()викине помилку, якщо масив не оголошено і до нього не додано значень. Однак помилок не буде, якщо масив просто порожній, як це було б у випадку, якщо ви його оголосили.


Проголосував foreachза те, що приклад і той факт, що викликається помилка, очевидно, залежить від версії PHP, яку ви використовуєте.
Charles Sprayberry

1
Я не розумію цієї відповіді. Щось не оголошено і не додано, це означає, що я не записав у вихідний код.
Гордон,

2
@Gordon, приклад чогось, що не буде працювати правильно, якщо $ щось не дорівнює 1: if ($ something == 1) {$ рядків [] = "a"; $ рядків [] = "b"; } foreach ($ рядків як $ рядок) {} Помилки можна було б уникнути, якби $ рядки були оголошені як $ рядки = масив (); до заяви if.
djdy

1
Я погоджуюсь (я проголосував), але життя занадто коротке, щоб постійно заявляти про все, хоча ми знаємо, що це "правильна" справа. Як варіант, я здогадуюсь, що ви можете використовувати is_array (), якщо вас турбують незадекларовані масиви. Як і більшість речей, це залежить від конкретних даних.
PJ Brunet

25

Просто хотів зазначити, що документація PHParrays фактично говорить про це в документації.

З веб-сайту 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

Вибачте, але "справжні" програми кодують таким чином, що їм 99% випадків не потрібно оголошувати vars. І зазвичай використовують об'єкт, який обробляє потенційні порожні дані, такі як null
Джеймс

Крута історія, Бро.
AlienWebguy

7

Подумайте про кодерів, які йдуть за вами! Якщо ви просто бачите $arr[] = 5, ви навіть не уявляєте, що $arrможе бути, не прочитавши весь попередній код у області. Явний $arr = array()рядок робить це чітким.


2
У PHP 5.4.x - 5.6.x: $ arr = [] теж працює.
Ентоні Рутледж,

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, тоді як масив $ 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

Це залежить від вашої перевірки помилок. Якщо у вас є суворі повідомлення про помилки, ви отримаєте повідомлення, але технічно це все одно має працювати без нього.


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петель, якщо ви не впевнені в даних, ви можете зробити це:

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

Якщо $usersзначення не встановлене (null coalesce робить 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 ви перевірите наявність циклу, ось і все.
Отар

array()порожній масив, foreachніколи нічого не зробить?
Джеймс
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.