Цикл for с isset ()! = null - почему?

for($i=0; isset($_POST['key_str'][$i]) != null; $i++)
{
    // some php here
}

Я унаследовал некоторый устаревший код на работе, и я нашел выше цикл for () в нескольких местах. Я уже много лет пишу PHP, Javascript и Python и никогда не видел ничего подобного. Моя интуиция подсказывает мне, что это человек, который написал этот устаревший код, пришел с другого языка. И, возможно, был не очень опытным.

Вопросов:

1) isset($_POST['key_str'][$i]) работает лучше, чем count($_POST['key_str'])?

2) Похож ли это на синтаксис, который обычно встречается на другом языке? Если да, то на каком языке?

С сайта php.net Returns TRUE if var exists and has value other than NULL. FALSE otherwise.

Sfili_81 09.08.2018 17:24

Я понимаю isset (). Что для меня не имеет смысла, так это то, почему он находится внутри цикла for ().

b_dubb 09.08.2018 17:25
What doesn't make sense to me is why it is inside a for() loop. Добро пожаловать в чудесный мир Legacy Code! : D
IsThisJavascript 09.08.2018 17:26

Я разрабатываю на PHP более десяти лет и никогда не видел ничего подобного. Это заставляет меня съеживаться, но это работает, поэтому я оставляю это в покое. Нахожу такие странные вещи повсюду.

b_dubb 09.08.2018 17:27

@d_bubb это хороший вопрос, и я понятия не имею .... :(

Sfili_81 09.08.2018 17:28

Я бы сделал изменение @b_dubb, просто чтобы избавить от головной боли следующего кодера, который столкнется с этим.

IsThisJavascript 09.08.2018 17:29
$_POST['key_str'][$i] может быть установлен, но это может быть строка, а не массив. Я бы заключил цикл for в условное выражение, которое проверяет правильный тип (массив) var и значение count ()> 0. Это выглядит крайне проблематично и хорошо ... неправильно.
b_dubb 09.08.2018 17:37
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
3
7
76
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Внутри isset в этом выражении используется $i (который увеличивается в цикле). $_POST['key_str'][$i], который входит в чек.

Таким образом, ожидается, что $_POST['key_str'] будет массивом, и этот цикл будет перебирать все элементы в этом массиве.

Если хотите, вы можете использовать count() или заменить все это циклом foreach, хотя это может привести к предупреждению, если $_POST['key_str'] вообще не установлен или не является массивом. isset - это очень простой способ обойти это, потому что он обрабатывает все эти ситуации и возвращает false, поэтому в этом сценарии цикл просто не будет введен.

это работает лучше, чем count ($ _ POST ['key_str'])?

b_dubb 09.08.2018 17:29

Я не знаю о производительности (и я бы не стал беспокоиться об этом, если вы не ожидаете, что этот массив будет содержать тысячи элементов). Но я думаю, что есть небольшая мера предосторожности, потому что текущий цикл по-прежнему будет «работать», если эта переменная post не установлена ​​или не является массивом, в то время как цикл foreach или использование count приведет к предупреждению.

GolezTrol 09.08.2018 17:32
foreach() намного быстрее, чем for(), и я сильно подозреваю, что for() намного быстрее, чем: доступ к индексу массива-> проверка, установлен ли он-> проверка того, что значение не равно нулю
IsThisJavascript 09.08.2018 17:36

Итак ... нет ... это не лучше, чем count($arr) > 0?

b_dubb 09.08.2018 17:39

@GolezTrol "isset () - очень простой способ обойти это, потому что он обрабатывает все эти ситуации и возвращает false, поэтому цикл просто не будет введен в этом сценарии". На данный момент похоже, что при использовании этого метода производительность может снизиться, но это сэкономит пару строк кода / условия. Я за более эффективный код, так как в этом массиве могут быть тысячи варов.

b_dubb 09.08.2018 17:45

Я бы предпочел быстро читать в любое время, кроме тех случаев, когда производительность действительно является ключевым фактором. Но я думаю, что isset работает довольно быстро, и чтобы сделать это по-другому, вам, возможно, придется выполнить несколько проверок. Если вы хотите быстрее, вам нужно будет проверить, получает ли массив и счет за пределами цикла. И даже тогда, что займет больше времени: отправка этих элементов с клиента на сервер или выполнение isset пару раз? Нужна ли оптимизация? Так или иначе, целью моего ответа было объяснить код и указать на возможные подводные камни при его изменении. Я не хотел защищать это как хорошее решение. :-)

GolezTrol 09.08.2018 22:56
Ответ принят как подходящий

isset () - это языковая конструкция, которая возвращает логическое значение, поэтому она никогда не может быть null. Однако сравнение использует оператор равный (==), а не оператор идентичный (===), таким образом, применяется жонглирование шрифтами:

Type of Operand 1   Type of Operand 2   Result
bool or null        anything            Convert both sides to bool

… И nullбросает в логическое значение false, поэтому:

true  != null → true  != false → true
false != null → false != false → false

Таким образом, цикл эквивалентен:

for($i=0; isset($_POST['key_str'][$i]); $i++){}

Другими словами, != null избыточен и ухудшает читаемость.

Теперь квадратные скобки используются для чтения элемента массива по ключу или строкового байта по смещению. Поскольку $_POST - внешняя переменная, цикл фактически может делать и то, и другое - я предполагаю, что первая была предназначена. Без дальнейшего контекста невозможно сказать, для чего он предназначен или как его переписать, но я подозреваю, что это запутанная альтернатива foreach().

Итак, чтобы ответить на ваши вопросы:

  1. Это не имеет значения. Они делают совершенно разные вещи.

  2. Это основано на мнении (для меня это синтаксис человека, не знакомого с программированием в целом).

Другие вопросы по теме