Потому что у строки не может быть строкового смещения.
В ответе выше написана чушь.
Обращаться к строке по
индексу можно. И в РНР7, и в РНР 8. Без всяких предупреждений.
К отдельным
байтам (но не символам) в строке можно обращаться, указывая смещение в квадратных скобках:
echo 'hello'[0];
Но в сообщении об ошибке говорится конкретно про
строковые ключи. А это уже действительно бессмыслица, никаких строковых смещений в строке быть не может. Что и написано черным по белому в ошибке.
И проблема действительно находится выше, в совершенно дурацком присвоении пустой строки массиву.
Если мы хотим использовать массив, то и присваивать начальное значение надо в виде пустого массива, а не строки.
При этом отдельно проверять наличие $aUnit[$server['unit']] и $aUnit[$server['unit']][$server['game']] не нужно. Достаточно проверить на существование сразу конечный элемент.
В 8.2 это можно красиво написать одной строчкой
$aUnit[$server['unit']][$server['game']] ??= '';
Но если почитать код дальше, то станет видно, что и здесь нам строка
тоже не нужна. А снова нужен массив.
Потому что в коде ниже эта строка разбивается через explode(???).
То есть, надо написать
$aUnit[$server['unit']][$server['game']] ??= [];
$aUnit[$server['unit']][$server['game']][] = $server['id'];
А ниже выкинуть всё от explode() до unset()
spoilerВообще, складывается ощущение, что исходный код писал либо ребенок, либо шизофреник - две разные личности, которые не видят код друг друга. Вот как с этим массивом например.
Или вот этот кусок кода еще мне очень понравился
$sql->query('SELECT `id` FROM `servers` LIMIT 1');
if(!$sql->num())
return NULL;
$sql->query('SELECT `id`, `unit`, `game` FROM `servers` ORDER BY `unit` DESC');
$all = $sql->num();
Напоминает анекдот про ирландца, который перед тем как поспорить, выпьет ли он 10 кружек пива, сначала сбегал в соседний паб. Проверить, выпьет ли он 10 кружек пива.