Вопросы на собеседовании: PHP-разработчик
100 реальных вопросов с образцовыми ответами и пояснениями для уровня Junior PHP-разработчик.
Смотреть пример резюме: PHP-разработчик →Тренировка флешкарточками
Интервальное повторение · Hunter Pass
Вопросы
PHP предоставляет скалярные, составные и специальные типы значений.
- К скалярным типам относятся bool, int, float и string.
- К составным типам относятся array, object, callable и iterable.
- null обозначает отсутствие значения, а resource представляет дескриптор внешнего ресурса.
Зачем это спрашивают: Интервьюер проверяет, знаете ли вы основные категории значений, с которыми работает PHP-код.
Динамическая типизация означает, что тип переменной определяется её текущим значением во время выполнения, а не фиксируется при объявлении.
- Одна переменная может хранить значения разных типов в течение своего жизненного цикла.
- PHP может приводить совместимые скалярные значения в некоторых операциях и вызовах функций.
- Типы параметров, свойств и возвращаемых значений всё равно позволяют задавать явные контракты.
Зачем это спрашивают: Сильный ответ отличает runtime-типы переменных PHP от необязательных объявленных контрактов типов.
Эта директива отключает приведение скалярных аргументов при вызовах функций из данного файла.
- Без strict mode PHP может привести совместимый скалярный аргумент, например числовую строку к int.
- В strict mode несовместимый скалярный аргумент обычно вызывает TypeError.
- Директива не делает PHP статически типизированным и не проверяет автоматически переменные без объявленного типа.
Зачем это спрашивают: Интервьюер оценивает, понимаете ли вы область действия и ограничения strict types в PHP.
Оператор == сравнивает значения после приведения типов PHP, а === требует совпадения и значения, и типа.
- Loose comparison может признать равными значения разных типов после преобразования.
- Strict comparison не выполняет преобразование типов.
- Строгое сравнение обычно безопаснее, когда вход может содержать строки, числа, boolean или null.
Зачем это спрашивают: Интервьюер проверяет, понимаете ли вы, как нестрогое сравнение может дать неожиданное равенство.
Cast преобразует значение в запрошенный тип через синтаксис вроде (int), (float), (string), (bool) или (array).
- Приведение числовой строки к int или float даёт числовое значение по правилам PHP.
- Приведение к bool следует правилам truthiness PHP, а не распознаёт смысл текста вроде false.
- Cast не проверяет, имело ли исходное значение смысл для приложения.
Зачем это спрашивают: Сильный ответ отделяет механическое преобразование от бизнес-валидации входных данных.
PHP поддерживает объявления типов для параметров функций, возвращаемых значений и свойств классов.
- Объявления документируют значения, которые API принимает, возвращает или хранит.
- Нарушения вызывают TypeError вместо молчаливого сохранения несовместимого значения.
- В объявлениях могут участвовать встроенные типы, классы, интерфейсы и составные типы.
Зачем это спрашивают: Интервьюер проверяет, знаете ли вы, как PHP выражает контракты функций и классов.
Nullable type допускает null, а union type допускает значение одного из нескольких перечисленных типов.
- ?User является сокращением для User|null.
- Объявление int|float принимает любой из двух перечисленных числовых типов.
- Члены union должны описывать осмысленный контракт, а не заменять понятную модель данных множеством вариантов.
Зачем это спрашивают: Сильный ответ объясняет и синтаксис, и назначение составных объявлений типов.
В логическом контексте PHP считает ложными false, 0, 0.0, пустую строку, строку '0', пустой массив и null.
- Другие непустые строки считаются истинными, даже если содержат текст 'false'.
- Пустые объекты также считаются истинными.
- Явное сравнение понятнее, когда ноль, пустая строка и null имеют разный смысл.
Зачем это спрашивают: Интервьюер оценивает знание falsey-значений, влияющих на условия и проверки входа.
Оператор ?? возвращает левый операнд, если значение существует и не равно null, иначе возвращает правый операнд.
- Его часто используют для необязательных ключей массива или параметров запроса.
- Проверка следует семантике isset, поэтому для существующего ключа со значением null используется запасное значение.
- Оператор не вызывает предупреждение о неопределённом ключе, которое могло бы появиться при прямом доступе.
Зачем это спрашивают: Интервьюер проверяет, понимаете ли вы и fallback-поведение, и обработку null.
Строки в одинарных кавычках выполняют минимальное экранирование, а строки в двойных кавычках интерпретируют переменные и больше управляющих последовательностей.
- В строку в двойных кавычках можно подставить переменную вроде $name.
- Оператор точки объединяет строки независимо от вида кавычек.
- Фигурные скобки делают границы подстановки понятными, когда переменная соприкасается с другим текстом.
Зачем это спрашивают: Интервьюер проверяет понимание строковых литералов, интерполяции и конкатенации в PHP.
strlen возвращает число байтов в строке, а mb_strlen считает символы для указанной многобайтовой кодировки.
- ASCII-символы обычно занимают один байт, поэтому для ASCII-текста результаты часто совпадают.
- Символы UTF-8 могут занимать несколько байтов, поэтому strlen не подходит для подсчёта символов.
- mb_strlen требует расширение mbstring и должна использовать известную приложению кодировку.
Зачем это спрашивают: Сильный ответ понимает, что строки PHP являются последовательностями байтов, а пользовательский текст может быть многобайтовым.
str_contains и strpos ищут внутри строк, а substr извлекает часть по смещению и длине.
- str_contains возвращает bool и удобна для простой проверки вхождения.
- strpos возвращает целую позицию или false, поэтому нулевую позицию нужно сравнивать через !== false.
- Для многобайтового текста могут понадобиться соответствующие функции mb_ со смещениями по символам.
Зачем это спрашивают: Интервьюер проверяет знание распространённых строковых API и важной особенности возврата strpos.
Индексный array использует целочисленные ключи, а ассоциативный array использует строковые ключи для именования значений.
- PHP реализует обе формы одним упорядоченным типом array.
- Целые и строковые ключи могут сосуществовать в одном array, хотя единая форма проще в поддержке.
- Индексные arrays обычно представляют списки, а ассоциативные arrays представляют записи или таблицы поиска.
Зачем это спрашивают: Сильный ответ понимает, что PHP arrays покрывают и list-like, и map-like структуры.
PHP использует квадратные скобки для доступа и присваивания, а [] добавляет значение со следующим целочисленным ключом.
- $items['name'] читает или записывает именованный ключ.
- $items[] = $value добавляет элемент без ручного вычисления index.
- unset($items[$key]) удаляет ключ без автоматической переиндексации оставшихся целочисленных ключей.
Зачем это спрашивают: Интервьюер проверяет знание основных операций и поведения ключей PHP-массивов.
isset проверяет, что ключ существует и его значение не равно null, а array_key_exists проверяет только существование ключа.
- Ключ со значением null заставляет isset вернуть false.
- Для того же ключа array_key_exists вернёт true.
- Выбор зависит от того, означает ли null отсутствие или является допустимым сохранённым значением.
Зачем это спрашивают: Сильный ответ объясняет смысловое различие для ключей со значением null.
Они преобразуют, выбирают и агрегируют значения array через callback-функции.
- array_map создаёт значения, применяя callback к входным элементам.
- array_filter сохраняет элементы, удовлетворяющие callback, и оставляет их исходные ключи.
- array_reduce объединяет все элементы в один накопленный результат.
Зачем это спрашивают: Интервьюер проверяет, различаете ли вы три основные операции обработки массивов.
sort упорядочивает значения и переиндексирует ключи, asort упорядочивает значения с сохранением связей ключей, а ksort сортирует по ключам.
- sort подходит для простого индексного списка, где исходные ключи не важны.
- asort сохраняет пару каждого значения с существующим ключом.
- Функции изменяют переданный array и возвращают boolean успеха, а не отсортированный array.
Зачем это спрашивают: Сильный ответ выбирает функцию сортировки по значимости ключей.
Все они объединяют arrays, но по-разному обрабатывают повторяющиеся и числовые ключи.
- array_merge перезаписывает повторяющиеся строковые ключи поздними значениями и переиндексирует числовые ключи.
- Распаковка array через ... удобна для создания нового массива и обычно следует merge-поведению числовых ключей.
- Оператор + сохраняет значение левого array, если один ключ существует с обеих сторон.
Зачем это спрашивают: Интервьюер оценивает, знаете ли вы различия семантики ключей у способов объединения PHP-массивов.
Деструктуризация array присваивает его элементы отдельным переменным через синтаксис [] или list.
- Позиционная деструктуризация читает значения по целочисленной позиции.
- Ассоциативная деструктуризация может явно указывать извлекаемые ключи.
- Отсутствующие элементы могут вызывать warnings, поэтому ожидаемая форма array должна быть известна.
Зачем это спрашивают: Интервьюер проверяет, знаете ли вы краткое извлечение данных из массивов известной формы.
По умолчанию foreach перебирает array по значению, а символ & связывает переменную цикла по ссылке.
- При обходе по значению изменение loop variable напрямую не меняет скалярные элементы.
- Обход по ссылке позволяет обновлять исходные элементы.
- После цикла reference variable нужно удалить через unset, чтобы последующие присваивания случайно не меняли последний элемент.
Зачем это спрашивают: Сильный ответ понимает обычное поведение foreach и опасность сохраняющейся ссылки.
Закрытые вопросы
- 21
Из каких частей состоит сигнатура PHP-функции?
formsphp - 22
Как работает область видимости переменных в PHP-функциях?
scopephp - 23
Что такое closure в PHP и как работает use?
closuresphp - 24
Чем arrow functions отличаются от обычных анонимных функций в PHP?
functionsphp - 25
В чём разница между передачей аргумента по значению и по ссылке в PHP?
php - 26
Что такое default, variadic и named arguments в PHP?
php - 27
В чём разница между классом и объектом в PHP?
oopphp - 28
Что такое constructor property promotion в PHP?
php - 29
Что означают public, protected и private в PHP?
cssphp - 30
Как работает наследование классов в PHP?
oopphpownership - 31
Что такое абстрактный класс в PHP?
php - 32
Что такое interface в PHP?
typesphp - 33
Что такое trait в PHP?
traitsphp - 34
Что такое static properties и methods в PHP?
php - 35
На что ссылаются $this, self и parent в PHP-классах?
php - 36
Что делает ключевое слово final в PHP OOP?
php - 37
Что такое magic methods в PHP?
magic-methodsphp - 38
Для чего нужны namespaces и statement use в PHP?
namespacesphpkubernetes - 39
Для чего Composer используется в PHP-проектах?
composerphp - 40
В чём разница между composer.json и composer.lock?
composer - 41
Как PSR-4 autoloading сопоставляет класс с файлом?
psrautoloading - 42
Чем различаются include, require, include_once и require_once?
- 43
Что такое суперглобальные массивы PHP и какие из них обычно используются в web requests?
php - 44
Как на базовом уровне работают PHP sessions?
sessionsphp - 45
Что такое cookie и для чего нужны её основные security attributes?
cookies - 46
Как связаны errors, exceptions и Throwable в современном PHP?
error-handlingphp - 47
Как работают try, catch, finally, throw и цепочка exceptions в PHP?
error-handlingphp - 48
Что такое PDO и каковы его основные понятия подключения и получения данных?
pdo - 49
Что такое prepared statements PDO и почему они важны?
pdo - 50
Что такое database transaction в PDO?
databasetransactionspdo - 51
Как посчитать частоту слов в PHP-массиве без учёта регистра и пробелов по краям?
php - 52
Как сгруппировать список массивов товаров по ID категории?
- 53
Как удалить повторяющиеся email-адреса, сохранив первое написание и порядок?
- 54
Как отсортировать заказы по убыванию суммы, а при равенстве по возрастанию даты создания?
- 55
Как безопасно прочитать город из вложенного массива запроса?
- 56
Как собрать все уникальные теги товаров, если теги хранятся во вложенных массивах?
- 57
Как разобрать строку CSV, в которой внутри кавычек могут быть запятые?
- 58
Как сократить UTF-8 заголовок до 60 символов, не разрезав многобайтовый символ?
- 59
Как заменить placeholders {name} и {order_id} в шаблоне сообщения?
- 60
Проверка роли считает целое число 0 равным строке '0'. Как сделать проверку типобезопасной?
- 61
Как написать типизированную функцию расчёта суммы заказа по строкам с ценой и количеством?
- 62
Как превратить ассоциативный массив запроса в типизированный объект регистрации?
- 63
Как разделить большой список ID на пакеты по 100 для обработки?
batchconcurrency - 64
Как провалидировать положительный целочисленный параметр page из $_GET?
validation - 65
Как провалидировать обязательное поле email из формы?
formsvalidation - 66
Снятый checkbox отсутствует в $_POST. Как правильно его обработать?
concurrency - 67
Как повторно показать значения формы после ошибки валидации и не создать XSS?
xssvalidationredis - 68
Как добавить CSRF-защиту в PHP-форму, изменяющую состояние?
formscsrfphp - 69
Как безопасно показать пользовательский комментарий на HTML-странице?
html - 70
Как не допустить повторной отправки успешной формы при обновлении страницы?
forms - 71
Как прочитать и провалидировать JSON-тело запроса в PHP endpoint?
validationendpointsphp - 72
Как хранить и проверять пароли пользователей в PHP?
passwordsphp - 73
PHP сообщает 'headers already sent' при redirect или установке cookie. Как это исправить?
cookiesphp - 74
Как разрешить обработчику формы только POST requests с ожидаемыми полями?
forms - 75
Поле multiple select может отправить одно, несколько или ни одного значения. Как его нормализовать?
normalization - 76
Как получить пользователя по ID через PDO без SQL injection?
sqlpdoinjection - 77
Как добавить новый товар через именованные placeholders PDO?
pdo - 78
Как безопасно реализовать поиск PDO-запросом с LIKE?
queriespdo - 79
Как построить подготовленный PDO-запрос для динамического списка ID в условии IN?
queriespdo - 80
Как атомарно сохранить заказ и его строки через PDO?
pdoconcurrency - 81
PDO fetch возвращает false, и последующий доступ к массиву вызывает warning. Как исправить код?
pdo - 82
Как добавить пагинацию в PDO-запрос товаров и не принимать произвольные SQL fragments?
sqlqueriespdo - 83
Как настроить PDO, чтобы ошибки базы не игнорировались молча?
databasepdoconfig - 84
Как не допустить попадания credentials PDO-подключения в source control?
pdo - 85
Как создать сессию после успешного входа пользователя?
sessions - 86
Как реализовать logout для PHP-сессии?
sessionsphp - 87
Как один раз показать сообщение об успехе после redirect формы?
forms - 88
Как настроить session cookie для HTTPS-приложения?
sessionscookieshttps - 89
Как сохранить языковое предпочтение пользователя в cookie?
cookies - 90
Как обработать ошибки загрузки файла в PHP и ограничить его размер?
php - 91
Как проверить, что загруженный файл действительно имеет разрешённый тип изображения?
- 92
Как сохранить загруженный файл без path traversal и конфликтов имён?
- 93
PDO transaction выбрасывает exception на середине. Как его обработать?
transactionspdoerror-handling - 94
Как вернуть безопасный ответ 500, если неожиданное исключение дошло до PHP endpoint?
error-handlingphpendpoints - 95
Как провалидировать дату в формате YYYY-MM-DD и не принять автоматические исправления PHP?
validationphp - 96
PHP сообщает об undefined array key в данных запроса. Как исправить проблему?
fundamentalsphp - 97
PHP печатает 'Array' и сообщает об array-to-string conversion. Как найти причину?
php - 98
После foreach со ссылками значения неожиданно меняются. Как это исправить?
- 99
Composer autoloading сообщает 'Class not found' для класса проекта. Что проверить?
composerautoloading - 100
PHP-страница остаётся пустой в production. Как безопасно найти проблему?
php