PHP Неверное объявление переменной

Отладка устаревшего кода, и у меня есть странная проблема. Устаревший код переносится на PHP 7.2. Я не знаю, для какой версии PHP он был изначально написан, но он работает в PHP 5.6.

Ниже мой пример проблемы...

$variable = '';
$variable['key'] = 'Hello World!';

echo $variable['key'] // H

Когда я повторяю $variable['key'], он получает только первый символ из значения. Теперь я знаю, что это потому, что $variable изначально объявлен как строка.

Но почему это работает в PHP 5.6? Что я могу сделать, чтобы это работало в 7.2, не просматривая тысячи строк кода?

Есть ли такая директива, как strict_types, которую я могу использовать?


person itsliamoco    schedule 16.11.2018    source источник
comment
Для всех, кто интересуется выводом в разных версиях PHP: 3v4l.org/Q8iiY   -  person Namoshek    schedule 16.11.2018
comment
Это потому, что строка 'key' при обработке как целое число становится 0 - поскольку $variable - это строка, вы делаете 'Hello World'[0] ... что H   -  person CD001    schedule 16.11.2018
comment
^^^ Так что удали $variable = ''; или сделай $variable = [];   -  person AbraCadaver    schedule 16.11.2018
comment
Я не могу найти никаких ссылок на это поведение в моих ограниченных поисках, но есть вероятность, что вы просто захотите исправить весь код с ошибками, который, надеюсь, ваш проект не слишком велик. Это неправильный синтаксис в любом случае, не совсем уверен, почему PHP 5 будет вести себя так, кроме: PHP. Также не удается найти какие-либо связанные настройки php.ini.   -  person Sheng Slogar    schedule 16.11.2018
comment
К сожалению, phpstan не считает этот код плохим. Поэтому я также не вижу хорошего способа автоматического устранения этих проблем.   -  person Namoshek    schedule 16.11.2018
comment
Не уверен, но, возможно, call_user_func() может помочь: php.net/manual/ ru/function.call-user-func.php . Туда тоже можно eval(), но плохо видно будет ;) Удачи!   -  person NVRM    schedule 16.11.2018
comment
Может быть я ошибаюсь.. Но попробуй var_dump($variable) будет веселее..   -  person Confused    schedule 16.11.2018


Ответы (1)


Из php.net

Предупреждение При записи со смещением вне допустимого диапазона строка дополняется пробелами. Нецелые типы преобразуются в целые. Недопустимый тип смещения выдает E_NOTICE. Используется только первый символ назначенной строки. Начиная с PHP 7.1.0, присваивание пустой строки приводит к фатальной ошибке. Раньше ему присваивался байт NULL.

http://php.net/manual/en/language.types.string.php#language.types.string.substr

Таким образом, «ключ» преобразуется в 0 и устанавливается первый символ. Поскольку это тип char, из заданной строки устанавливается только "H".

$variable = '';
$variable['key'] = 'Hello World!';

echo $variable;       
echo $variable['key'];

Если вы измените свой код на приведенный выше, вы сможете лучше увидеть, что происходит.

Итак, текст «привет, мир!» теряется и исчезает в PHP >= 7.1, потому что вы устанавливаете первый символ, тип остается string.

В php 5.6 вы получите Notice: Array to string conversion in /in/N2poP on line 6

Таким образом, в предыдущих версиях вы перезаписывали полную переменную, и исходная пустая строка исчезала, PHP просто создавал новый массив. Такое поведение происходит только с пустой строкой!

Это также отмечено в документации: http://php.net/manual/en/language.types.string.php#language.types.string.substr

Примечание. Начиная с PHP 7.1.0, применение оператора пустого индекса к пустой строке приводит к фатальной ошибке. Раньше пустая строка автоматически преобразовывалась в массив.

Самым простым решением было бы удалить часть $variable = '';, она в любом случае недействительна и никогда не используется в вашем устаревшем коде. или заменив его на $variable = [];

Поскольку такое поведение происходит только с пустой строкой в ​​php ‹ 7.1, вы можете использовать регулярное выражение, чтобы найти все места, где вы должны провести рефакторинг, чтобы исправить проблему.

person Sander Visser    schedule 16.11.2018