Предупреждение: смещению строки будет присвоен только первый байт.

Следующий код отлично работал в PHP 7, так почему я вижу это предупреждение в PHP 8?

$str = 'xy';
$str[0] = 'bc';

2 ответа

Решение

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

Так что вам просто нужно удалить лишний байт (c в этом случае)

$str = 'xy';
$str[0] = 'b';

Или если вы действительно хотите заменить x с участием bcвы можете использовать substr_replace

$str = 'xy';
var_dump(substr_replace($str, 'bc', 0, 1)); // output: string(2) "bcy"

Примечание: эта функция принимает байтовые смещения, а не смещения кодовых точек.

Собственно код работает так же, как в PHP 7.4. Единственная разница в том, что теперь выдает предупреждение.

$str = 'xy';
$str[0] = 'bc';

var_dump($str); // string(2) "by"
var_dump(phpversion()); // string(6) "7.4.10"

PHP 8

var_dump($str); // string(2) "by"
var_dump(phpversion()); // string(10) "8.0.0beta4"

Как говорится в документации PHP:

Внутри строки PHP представляют собой массивы байтов. В результате доступ к строке или ее изменение с помощью скобок массива небезопасно для многобайтовой передачи и должно выполняться только со строками в однобайтовой кодировке, например ISO-8859-1.

Если вы хотите вставить все байты из строки замены в строку назначения, вы можете использовать:

$str = 'xy';

function chars_replace(string $str, string $replacement, int $indexAt)
{
    return substr_replace($str, $replacement, $indexAt, $indexAt + strlen($replacement));
}

var_dump(chars_replace($str, 'bc', 0)); // string(2) "bc"

Однако он не будет работать с многобайтовой кодировкой.

Если вы хотите заменить только один символ, вы можете использовать:

$str = 'xy';
$str[0] = substr('bc', 0, 1);

var_dump($str); // string(2) "by"
Другие вопросы по тегам