Строки и память в PHP
Вопрос
Как PHP хранит строки и как это влияет на производительность?
Попробуйте сами
Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.
Показать ответ и разбор
Коротко
Что должно прозвучать в ответе
zend_string: длина, хеш и счётчик ссылок
Копирование при записи: присваивание не копирует строку
Интернированные строки для литералов и имён
Склейка в цикле через .= обычно дешёвая, но большие строки лучше собирать массивом и implode
Для больших данных потоковая обработка вместо чтения всего в память
Что могут спросить следом
- Что такое copy-on-write?
- Почему file_get_contents на гигабайтном файле плохая идея?
Разбор
Внутри строка это структура zend_string: длина, закешированный хеш и счётчик ссылок. Присваивание $b = $a не копирует данные, а увеличивает счётчик. Копия создаётся только при изменении одной из переменных, это copy-on-write. Литералы и имена функций интернируются и живут весь запрос.
Конкатенация .= в цикле в PHP обычно не катастрофа: если на строку одна ссылка, движок часто дописывает её на месте с перевыделением памяти. Но для сборки большого результата из множества кусков удобнее и предсказуемее складывать части в массив и делать implode.
Самая частая проблема не в склейке, а в объёме: прочитать гигабайтный файл через file_get_contents значит упереться в memory_limit. Большие данные обрабатываю потоково: fgets построчно, SplFileObject или генераторы.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.