200 вопросов по PHP
200 вопросов по PHP
Базовый синтаксис и типы данных
Вопрос
Как начинается и заканчивается блок кода на PHP?
Ответ
Блок кода на PHP начинается с открывающего тега <?php и заканчивается закрывающим тегом ?>. В файлах, содержащих только PHP-код, закрывающий тег опускают, чтобы избежать случайного вывода пробельных символов после него.
<?php
echo "Hello, world!";
// Закрывающий тег не требуется
Вопрос
Какие существуют типы данных в PHP?
Ответ
PHP поддерживает следующие типы данных:
- Скалярные:
boolean,integer,float(илиdouble),string - Составные:
array,object,callable,iterable - Специальные:
resource,null - Начиная с PHP 8.0:
mixed,never,false,true,void,nullкак отдельные типы в контексте объявления
Тип переменной определяется автоматически при присваивании значения и может меняться во время выполнения.
Вопрос
Что такое динамическая типизация в PHP?
Ответ
Динамическая типизация означает, что переменная не имеет фиксированного типа. Тип определяется на основе значения, присвоенного переменной, и может изменяться в ходе выполнения программы.
$var = 42; // integer
$var = "text"; // string
$var = true; // boolean
Вопрос
Как проверить тип переменной в PHP?
Ответ
Для проверки типа используются функции:
is_bool()is_int(),is_integer(),is_long()is_float(),is_double(),is_real()is_string()is_array()is_object()is_null()is_resource()is_callable()
Пример:
if (is_string($value)) {
echo "Это строка";
}
Вопрос
Чем отличаются одинарные и двойные кавычки при определении строк?
Ответ
Строки в одинарных кавычках ('...') интерпретируются буквально — переменные и escape-последовательности (кроме \\ и \') не обрабатываются.
Строки в двойных кавычках ("...") поддерживают интерполяцию переменных и большинство escape-последовательностей (\n, \t, \$ и др.).
$name = "Мир";
echo 'Привет, $name'; // Выведет: Привет, $name
echo "Привет, $name"; // Выведет: Привет, Мир
Вопрос
Как объявить константу в PHP?
Ответ
Константу можно объявить двумя способами:
-
С помощью функции
define():define('MAX_SIZE', 100); -
С помощью ключевого слова
const(только в глобальной области видимости или внутри класса):const MAX_SIZE = 100;
Константы чувствительны к регистру по умолчанию (если не указано иное в define()), не имеют знака $ и доступны глобально.
Вопрос
Что такое null в PHP?
Ответ
null — это специальное значение, обозначающее отсутствие значения. Переменная считается null, если:
- ей явно присвоено значение
null - она была объявлена, но ей не присвоено никакое значение
- она была удалена с помощью
unset()
Проверка:
$var = null;
if ($var === null) {
echo "Переменная равна null";
}
Вопрос
Как работает оператор ===?
Ответ
Оператор === (строгое сравнение) возвращает true, только если оба операнда имеют одинаковое значение и одинаковый тип.
0 == "0" // true
0 === "0" // false
Вопрос
Что такое heredoc и nowdoc?
Ответ
heredoc — это синтаксис для многострочных строк с интерполяцией переменных, аналогичной двойным кавычкам.
$str = <<<EOD
Привет, $name!
Строка без ограничений.
EOD;
nowdoc — аналог heredoc, но без интерполяции (аналог одинарных кавычек). Использует одинарные кавычки вокруг метки.
$str = <<<'EOD'
Привет, $name! // выведется как есть
EOD;
Оба завершаются меткой на отдельной строке без отступов.
Вопрос
Как преобразовать строку в число?
Ответ
PHP автоматически преобразует строки в числа при арифметических операциях. Явное преобразование можно выполнить:
- Через приведение типов:
(int) "123",(float) "123.45" - Через функции:
intval("123"),floatval("123.45")
Если строка начинается с цифр, используется эта часть. Иначе результат — 0.
echo (int)"42abc"; // 42
echo (int)"abc42"; // 0
Переменные и область видимости
Вопрос
Какие правила именования переменных в PHP?
Ответ
Имя переменной:
- Начинается со знака
$ - Далее — буква или подчёркивание
- Может содержать буквы, цифры и подчёркивания
- Регистрозависимо
Примеры допустимых имён: $name, $_value, $User123
Недопустимые: $1var, $my-var
Вопрос
Что такое суперглобальные переменные?
Ответ
Суперглобальные переменные — это встроенные массивы, доступные в любом месте скрипта без объявления. Основные:
$_GET— параметры из URL$_POST— данные формы, отправленные методом POST$_REQUEST— комбинация$_GET,$_POSTи$_COOKIE$_SERVER— информация о сервере и запросе$_SESSION— данные сессии$_COOKIE— cookie-данные$_FILES— загруженные файлы$_ENV— переменные окружения$GLOBALS— все глобальные переменные
Вопрос
Что делает функция isset()?
Ответ
Функция isset() проверяет, существует ли переменная и не равна ли она null. Возвращает true, если переменная определена и не null.
$var = 0;
isset($var); // true
unset($var);
isset($var); // false
Вопрос
Что делает функция empty()?
Ответ
Функция empty() возвращает true, если переменная не существует или её значение считается «пустым»:
""(пустая строка)0,0.0"0"nullfalse[](пустой массив)
empty("0"); // true
empty(0); // true
empty([]); // true
Вопрос
Как передать переменную по ссылке?
Ответ
Переменную передают по ссылке, добавляя амперсанд & перед именем параметра в объявлении функции или при присваивании.
function increment(&$value) {
$value++;
}
$num = 5;
increment($num);
echo $num; // 6
При присваивании:
$a = 10;
$b = &$a;
$b = 20;
echo $a; // 20
Вопрос
Что такое статические переменные в функциях?
Ответ
Статическая переменная внутри функции сохраняет своё значение между вызовами функции. Объявляется с ключевым словом static.
function counter() {
static $count = 0;
$count++;
echo $count;
}
counter(); // 1
counter(); // 2
counter(); // 3
Вопрос
Как получить список всех переменных в текущей области видимости?
Ответ
Используется функция get_defined_vars(). Она возвращает ассоциативный массив всех определённых переменных.
$a = 1;
$b = "test";
print_r(get_defined_vars());
Условные конструкции и циклы
Вопрос
Какие условные конструкции есть в PHP?
Ответ
Основные условные конструкции:
if/elseif/elseswitch/case/default- Тернарный оператор:
$result = $condition ? $value1 : $value2; - Null coalescing operator (начиная с PHP 7.0):
$value = $var ?? 'default';
Вопрос
Как работает конструкция switch?
Ответ
switch сравнивает выражение с каждым case с помощью оператора == (нестрогое сравнение). При совпадении выполняется соответствующий блок кода до break.
$day = 2;
switch ($day) {
case 1:
echo "Понедельник";
break;
case 2:
echo "Вторник";
break;
default:
echo "Неизвестный день";
}
Без break происходит «проваливание» в следующий case.
Вопрос
Какие циклы поддерживаются в PHP?
Ответ
PHP поддерживает следующие циклы:
forwhiledo-whileforeach
Пример foreach:
$arr = ['a', 'b', 'c'];
foreach ($arr as $value) {
echo $value;
}
С индексами:
foreach ($arr as $key => $value) {
echo "$key: $value";
}
Вопрос
Чем отличается while от do-while?
Ответ
Цикл while проверяет условие до выполнения тела цикла. Если условие изначально ложно, тело не выполнится ни разу.
Цикл do-while выполняет тело хотя бы один раз, а затем проверяет условие.
$i = 0;
while ($i > 0) {
echo "Это не выведется";
}
do {
echo "Это выведется один раз";
} while ($i > 0);
Вопрос
Как прервать цикл или перейти к следующей итерации?
Ответ
break— немедленно завершает циклcontinue— пропускает оставшуюся часть текущей итерации и переходит к следующей
Можно указать уровень вложенности: break 2 — выйти из двух вложенных циклов.
Функции
Вопрос
Как объявить функцию в PHP?
Ответ
Функция объявляется с помощью ключевого слова function, за которым следует имя и список параметров.
function greet($name) {
return "Привет, $name!";
}
Имя функции нечувствительно к регистру, но рекомендуется использовать согласованный стиль.
Вопрос
Можно ли функции возвращать несколько значений?
Ответ
Функция напрямую возвращает одно значение. Чтобы вернуть несколько значений, используют массив.
function getCoordinates() {
return [10, 20];
}
list($x, $y) = getCoordinates();
// или [$x, $y] = getCoordinates(); (PHP 7.1+)
Вопрос
Что такое аргументы по умолчанию?
Ответ
Аргументы по умолчанию задаются в объявлении функции. Если при вызове аргумент не передан, используется значение по умолчанию.
function say($message = "Привет") {
echo $message;
}
say(); // Привет
say("Здравствуй"); // Здравствуй
Аргументы по умолчанию должны идти после обязательных.
Вопрос
Что такое вариадические функции?
Ответ
Вариадическая функция принимает переменное число аргументов. Объявляется с помощью троеточия ... перед параметром.
function sum(...$numbers) {
return array_sum($numbers);
}
echo sum(1, 2, 3, 4); // 10
Также можно использовать ... при вызове для распаковки массива.
Вопрос
Что такое анонимные функции?
Ответ
Анонимная функция (замыкание) — это функция без имени, которую можно присвоить переменной или передать как аргумент.
$greet = function($name) {
return "Привет, $name";
};
echo $greet("Мир");
Может захватывать переменные из внешней области с помощью use.
$message = "Привет";
$greet = function($name) use ($message) {
return "$message, $name";
};
Вопрос
Как проверить, существует ли функция?
Ответ
Используется функция function_exists().
if (function_exists('json_encode')) {
echo "Функция доступна";
}
Вопрос
Что такое рекурсия в PHP?
Ответ
Рекурсия — это вызов функцией самой себя. Требует условия выхода, чтобы избежать бесконечного цикла.
function factorial($n) {
if ($n <= 1) return 1;
return $n * factorial($n - 1);
}
По умолчанию PHP ограничивает глубину рекурсии (обычно ~1000 уровней), но это зависит от конфигурации.
Вопрос
Что такое стрелочные функции?
Ответ
Стрелочные функции — краткая форма записи анонимных функций, введённая в PHP 7.4. Поддерживают только одно выражение и автоматически возвращают его результат.
$double = fn($x) => $x * 2;
echo $double(5); // 10
Автоматически захватывают переменные из родительской области (по значению).
Вопрос
Можно ли в PHP перегружать функции?
Ответ
PHP не поддерживает перегрузку функций в классическом смысле (несколько функций с одинаковым именем, но разными параметрами). Однако можно эмулировать поведение с помощью:
- Аргументов по умолчанию
- Вариадических функций
- Проверки типов внутри функции
Вопрос
Что такое генераторы?
Ответ
Генератор — это функция, которая возвращает объект Generator и позволяет перебирать данные без их предварительного хранения в памяти. Использует ключевое слово yield.
function xrange($start, $end) {
for ($i = $start; $i <= $end; $i++) {
yield $i;
}
}
foreach (xrange(1, 3) as $value) {
echo $value; // 1, 2, 3
}
Экономит память при работе с большими последовательностями.
Массивы
Вопрос
Какие типы массивов существуют в PHP?
Ответ
В PHP существует только один тип массива — ассоциативный массив, реализованный как упорядоченный хеш-мап. Он может использоваться как:
- Индексированный массив (ключи — целые числа, начиная с 0)
- Ассоциативный массив (ключи — строки или целые числа в произвольном порядке)
Примеры:
$indexed = [10, 20, 30]; // индексированный
$assoc = ['name' => 'Иван', 'age' => 30]; // ассоциативный
PHP не различает эти формы на уровне типа — оба являются array.
Вопрос
Как создать массив в PHP?
Ответ
Массив можно создать двумя способами:
-
С помощью литерала (рекомендуется):
$arr = [1, 2, 3]; -
С помощью функции
array()(устаревший стиль):$arr = array(1, 2, 3);
Оба варианта эквивалентны, но короткий синтаксис [...] предпочтительнее.
Вопрос
Как добавить элемент в конец массива?
Ответ
Используется функция array_push() или прямое присваивание без указания ключа:
$arr = [1, 2];
$arr[] = 3; // Добавит 3 в конец
array_push($arr, 4); // То же самое
Для одного элемента $arr[] = ... эффективнее, так как не вызывает функцию.
Вопрос
Как удалить последний элемент массива?
Ответ
Функция array_pop() удаляет и возвращает последний элемент массива:
$arr = [1, 2, 3];
$last = array_pop($arr); // $last = 3, $arr = [1, 2]
Если массив пуст, функция вернёт null.
Вопрос
Как объединить два массива?
Ответ
Существует несколько способов:
-
Оператор
+— объединяет, сохраняя ключи из левого массива:$a = ['a' => 1, 'b' => 2];
$b = ['b' => 3, 'c' => 4];
$c = $a + $b; // ['a' => 1, 'b' => 2, 'c' => 4] -
Функция
array_merge()— перезаписывает значения по числовым ключам, объединяет по строковым:$c = array_merge($a, $b); // ['a' => 1, 'b' => 3, 'c' => 4]
Разница особенно заметна при работе с числовыми ключами.
Вопрос
Как проверить, существует ли ключ в массиве?
Ответ
Используется функция array_key_exists():
$arr = ['name' => 'Иван', 'age' => null];
var_dump(array_key_exists('age', $arr)); // true
var_dump(isset($arr['age'])); // false (так как значение null)
isset() не подходит, если значение может быть null.
Вопрос
Что делает функция array_values()?
Ответ
Функция array_values() возвращает новый массив, содержащий только значения исходного массива с числовыми ключами, начинающимися с 0.
$arr = ['a' => 1, 'b' => 2];
$new = array_values($arr); // [1, 2]
Полезно для преобразования ассоциативного массива в индексированный.
Вопрос
Как отфильтровать массив?
Ответ
Используется функция array_filter(), принимающая массив и callback-функцию:
$numbers = [1, 2, 3, 4, 5];
$evens = array_filter($numbers, fn($n) => $n % 2 === 0);
// [2 => 2, 4 => 4]
Ключи сохраняются. Чтобы сбросить ключи, применяют array_values().
Вопрос
Как преобразовать массив?
Ответ
Функция array_map() применяет callback к каждому элементу массива и возвращает новый массив:
$numbers = [1, 2, 3];
$squares = array_map(fn($n) => $n * $n, $numbers);
// [1, 4, 9]
Поддерживает несколько массивов одновременно.
Вопрос
Что такое многомерный массив?
Ответ
Многомерный массив — это массив, элементами которого являются другие массивы.
$matrix = [
[1, 2],
[3, 4]
];
echo $matrix[0][1]; // 2
PHP поддерживает массивы любой глубины вложенности.
Строки
Вопрос
Как определить длину строки?
Ответ
Функция strlen() возвращает количество байтов в строке. Для UTF-8 строк корректнее использовать mb_strlen():
echo strlen("café"); // 5 (из-за é в UTF-8 занимает 2 байта)
echo mb_strlen("café", 'UTF-8'); // 4
Рекомендуется использовать mb_* функции при работе с Unicode.
Вопрос
Как объединить строки?
Ответ
Оператор конкатенации — точка (.):
$greeting = "Привет" . " " . "мир!"; // "Привет мир!"
Также можно использовать оператор .= для присваивания с конкатенацией:
$message = "Привет";
$message .= ", друг!"; // "Привет, друг!"
Вопрос
Как сравнить две строки?
Ответ
Для точного сравнения используется оператор ===. Для регистронезависимого — strcasecmp() или mb_strtolower() + ===.
if (strcasecmp("Привет", "ПРИВЕТ") === 0) {
echo "Строки равны без учёта регистра";
}
Никогда не используйте == для сравнения строк — возможны неожиданные приведения типов.
Вопрос
Как найти подстроку в строке?
Ответ
Функция strpos() возвращает позицию первого вхождения подстроки или false, если не найдено:
$haystack = "Здравствуй, мир!";
$pos = strpos($haystack, "мир");
if ($pos !== false) {
echo "Найдено на позиции $pos";
}
Важно использовать !== false, так как позиция 0 — валидный результат.
Вопрос
Как заменить подстроку?
Ответ
Функция str_replace() заменяет все вхождения:
$text = "Я люблю яблоки.";
$new = str_replace("яблоки", "апельсины", $text);
// "Я люблю апельсины."
Для замены с учётом регистра — str_ireplace().
Для регулярных выражений — preg_replace().
Вопрос
Как разбить строку на массив?
Ответ
Функция explode() разбивает строку по разделителю:
$list = "яблоко,банан,апельсин";
$fruits = explode(",", $list); // ['яблоко', 'банан', 'апельсин']
Обратная операция — implode():
$csv = implode(",", $fruits);
Вопрос
Как обрезать пробелы в начале и конце строки?
Ответ
Функция trim() удаляет пробелы (и другие символы по умолчанию) с обоих концов:
$input = " текст ";
$clean = trim($input); // "текст"
Аналоги: ltrim() (только слева), rtrim() (только справа).
Вопрос
Как экранировать HTML-символы?
Ответ
Функция htmlspecialchars() преобразует специальные символы в HTML-сущности:
$userInput = '<script>alert("XSS")</script>';
$safe = htmlspecialchars($userInput, ENT_QUOTES | ENT_HTML5, 'UTF-8');
// <script>alert("XSS")</script>
Это базовая защита от XSS при выводе пользовательских данных.
Объектно-ориентированное программирование (ООП)
Вопрос
Как объявить класс в PHP?
Ответ
Класс объявляется с помощью ключевого слова class, за которым следует имя:
class User {
public $name;
public function greet() {
return "Привет, {$this->name}!";
}
}
Имя класса должно начинаться с буквы или подчёркивания и может содержать буквы, цифры и подчёркивания.
Вопрос
Как создать объект класса?
Ответ
Объект создаётся с помощью оператора new:
$user = new User();
$user->name = "Анна";
echo $user->greet(); // Привет, Анна!
Начиная с PHP 8.0, можно использовать new без скобок, если конструктор не принимает аргументов.
Вопрос
Что такое свойства и методы?
Ответ
Свойства — это переменные внутри класса, хранящие состояние объекта.
Методы — это функции внутри класса, определяющие поведение объекта.
class Car {
public $color = "красный"; // свойство
public function startEngine() { // метод
return "Двигатель запущен";
}
}
Вопрос
Какие уровни видимости существуют в PHP?
Ответ
В PHP три уровня видимости для свойств и методов:
public— доступны из любого контекстаprotected— доступны только внутри класса и его наследниковprivate— доступны только внутри самого класса
class Example {
public $a;
protected $b;
private $c;
}
Вопрос
Что такое конструктор?
Ответ
Конструктор — это специальный метод, вызываемый при создании объекта. Объявляется как __construct():
class User {
public $name;
public function __construct($name) {
$this->name = $name;
}
}
$user = new User("Иван");
Начиная с PHP 8.0, поддерживается синтаксис «конструкторного продвижения» параметров.
Вопрос
Что такое конструкторное продвижение (constructor property promotion)?
Ответ
Конструкторное продвижение позволяет объявлять и инициализировать свойства прямо в сигнатуре конструктора:
class User {
public function __construct(
public string $name,
protected int $age
) {}
}
$user = new User("Мария", 28);
echo $user->name; // Мария
Это сокращает шаблонный код и делает классы компактнее.
Вопрос
Что такое деструктор?
Ответ
Деструктор — метод __destruct(), вызываемый автоматически, когда объект удаляется из памяти или скрипт завершается:
class Logger {
public function __destruct() {
echo "Логгер завершает работу";
}
}
Используется редко, чаще для закрытия ресурсов (файлов, соединений), хотя в PHP сборщик мусора обычно справляется сам.
Вопрос
Что такое наследование?
Ответ
Наследование позволяет одному классу (дочернему) унаследовать свойства и методы другого класса (родительского) с помощью ключевого слова extends:
class Animal {
public function speak() {
return "Звук";
}
}
class Dog extends Animal {
public function speak() {
return "Гав";
}
}
Дочерний класс может переопределять методы родителя.
Вопрос
Как вызвать метод родительского класса?
Ответ
Используется ключевое слово parent:::
class Dog extends Animal {
public function speak() {
return parent::speak() . " — но я собака!";
}
}
Это позволяет расширять, а не полностью заменять поведение родителя.
Вопрос
Что такое абстрактный класс?
Ответ
Абстрактный класс — это класс, который нельзя инстанцировать напрямую. Объявляется с abstract. Может содержать как обычные, так и абстрактные методы:
abstract class Shape {
abstract public function area();
public function describe() {
return "Это фигура";
}
}
class Circle extends Shape {
public function area() {
// реализация обязательна
}
}
Любой класс, наследующий абстрактный, обязан реализовать все его абстрактные методы.
Вопрос
Что такое интерфейс?
Ответ
Интерфейс — это контракт, определяющий, какие методы должен реализовать класс. Объявляется с interface. Класс реализует интерфейс с помощью implements:
interface LoggerInterface {
public function log(string $message): void;
}
class FileLogger implements LoggerInterface {
public function log(string $message): void {
file_put_contents('log.txt', $message . PHP_EOL, FILE_APPEND);
}
}
Класс может реализовывать несколько интерфейсов.
Вопрос
Можно ли наследовать несколько классов?
Ответ
Нет, PHP не поддерживает множественное наследование классов. Класс может наследовать только один родительский класс.
Для повторного использования кода из нескольких источников используются трейты.
Вопрос
Что такое трейт?
Ответ
Трейт — это механизм повторного использования кода в языках с одиночным наследованием. Объявляется с trait и подключается в класс с use:
trait Timestampable {
public function getTimestamp(): int {
return time();
}
}
class Event {
use Timestampable;
}
Трейты могут содержать свойства, методы, даже абстрактные методы.
Вопрос
Как разрешаются конфликты имён при использовании нескольких трейтов?
Ответ
Если два трейта определяют метод с одинаковым именем, необходимо явно указать, какой использовать, с помощью insteadof, и при необходимости создать псевдоним через as:
trait A { public function say() { echo "A"; } }
trait B { public function say() { echo "B"; } }
class C {
use A, B {
A::say insteadof B;
B::say as sayB;
}
}
Вопрос
Что такое статические методы и свойства?
Ответ
Статические методы и свойства принадлежат классу, а не экземпляру. Объявляются с static. Доступ к ним осуществляется через ::, без создания объекта:
class Math {
public static function add($a, $b) {
return $a + $b;
}
}
echo Math::add(2, 3); // 5
Внутри статического метода недоступен $this.
Вопрос
Что такое позднее статическое связывание?
Ответ
Позднее статическое связывание позволяет ссылаться на вызванный класс в контексте наследования с помощью static:: вместо self:::
class ParentClass {
public static function who() {
echo static::class; // выведет реальный вызванный класс
}
}
class ChildClass extends ParentClass {}
ChildClass::who(); // "ChildClass"
Без static:: (self::) всегда выводился бы ParentClass.
Вопрос
Что такое магические методы?
Ответ
Магические методы — это специальные методы с двойным подчёркиванием, которые автоматически вызываются при определённых операциях:
__construct(),__destruct()__get(),__set()— доступ к недоступным свойствам__call(),__callStatic()— вызов недоступных методов__toString()— преобразование объекта в строку__invoke()— возможность вызывать объект как функцию
Пример:
class Box {
private $data = [];
public function __get($key) {
return $this->data[$key] ?? null;
}
public function __set($key, $value) {
$this->data[$key] = $value;
}
}
Вопрос
Как запретить клонирование объекта?
Ответ
Объявите приватный метод __clone():
class Singleton {
private function __clone() {}
}
Попытка клонирования вызовет фатальную ошибку.
Вопрос
Что такое финальный класс или метод?
Ответ
Класс, объявленный с final, не может быть унаследован. Метод с final не может быть переопределён в дочерних классах:
final class Utils {
final public function helper() {
// нельзя переопределить
}
}
Используется для защиты критически важного поведения.
Типизация и строгий режим
Вопрос
Поддерживает ли PHP объявление типов?
Ответ
Да. Начиная с PHP 7.0, поддерживаются скалярные типы: int, float, string, bool.
PHP 7.1 добавил void и nullable-типы (?string).
PHP 7.2 — object.
PHP 8.0 — mixed, static, never.
Пример:
function add(int $a, int $b): int {
return $a + $b;
}
Вопрос
Что такое строгий режим типов?
Ответ
Строгий режим включается директивой declare(strict_types=1); в начале файла. В этом режиме PHP не выполняет неявное приведение типов для аргументов и возвращаемых значений:
declare(strict_types=1);
function square(int $n): int {
return $n * $n;
}
square("5"); // Ошибка: передан string, ожидается int
Без strict_types PHP попытался бы преобразовать "5" в 5.
Вопрос
Что такое nullable-тип?
Ответ
Nullable-тип допускает значение null в дополнение к указанному типу. Обозначается знаком ? перед типом:
function setName(?string $name): void {
// $name может быть string или null
}
Эквивалентно union-типу string|null (начиная с PHP 8.0).
Вопрос
Что такое union-типы?
Ответ
Union-тип (введён в PHP 8.0) позволяет указать несколько допустимых типов через вертикальную черту:
function process(int|string $value): void {
// $value может быть int или string
}
Можно комбинировать с null: int|string|null.
Вопрос
Что такое intersection-типы?
Ответ
Intersection-типы (введены в PHP 8.1) позволяют указать, что значение должно реализовывать несколько типов одновременно. Используются только с объектами:
function handle(
JsonSerializable&Countable $obj
): string {
return json_encode($obj);
}
Значение должно быть объектом, реализующим оба интерфейса.
Пространства имён и автозагрузка
Вопрос
Зачем нужны пространства имён?
Ответ
Пространства имён (namespace) предотвращают конфликты имён классов, функций и констант. Позволяют группировать связанный код:
namespace App\Models;
class User { }
Полное имя класса — App\Models\User.
Вопрос
Как использовать класс из другого пространства имён?
Ответ
С помощью use:
namespace App\Controllers;
use App\Models\User;
use DateTime;
class UserController {
public function show() {
$user = new User();
$now = new DateTime();
}
}
Можно задавать псевдонимы: use App\Models\User as UserModel;.
Вопрос
Что такое PSR-4?
Ответ
PSR-4 — стандарт автозагрузки классов, опубликованный PHP-FIG. Он связывает пространства имён с файловой структурой:
- Пространство имён
App\Models→ директория/src/Models/ - Класс
User→ файлUser.php
Автозагрузчик загружает файл по имени класса без явного require.
Вопрос
Как реализовать автозагрузку классов?
Ответ
Рекомендуется использовать Composer, который генерирует автозагрузчик на основе PSR-4.
Вручную можно зарегистрировать функцию через spl_autoload_register():
spl_autoload_register(function ($class) {
$file = str_replace('\\', '/', $class) . '.php';
if (file_exists($file)) {
require $file;
}
});
Но на практике почти всегда используется Composer.
Обработка ошибок и исключений
Вопрос
Какие типы ошибок существуют в PHP?
Ответ
В PHP различают несколько уровней ошибок:
E_ERROR— фатальная ошибка, прерывает выполнениеE_WARNING— предупреждение, выполнение продолжаетсяE_NOTICE— уведомление о потенциальной проблеме (например, несуществующая переменная)E_DEPRECATED— использование устаревшей функциональностиE_USER_*— ошибки, сгенерированные пользователем (trigger_error())
Современный код использует исключения вместо традиционных ошибок.
Вопрос
Как обрабатывать исключения?
Ответ
Исключения обрабатываются с помощью блоков try, catch, finally:
try {
$value = riskyOperation();
} catch (Exception $e) {
echo "Ошибка: " . $e->getMessage();
} finally {
// Выполняется всегда
}
Начиная с PHP 7, многие фатальные ошибки преобразуются в Error, который также наследует Throwable.
Вопрос
Что такое Throwable?
Ответ
Throwable — это интерфейс, реализуемый всеми выбрасываемыми объектами в PHP 7+. Он является родителем для двух классов:
Exception— для логических ошибок в приложенииError— для фатальных ошибок движка (например, вызов несуществующего метода)
Любой обработчик исключений должен ловить Throwable, чтобы быть совместимым с PHP 7+.
try {
// код
} catch (Throwable $t) {
// обработка всех выбросов
}
Вопрос
Как создать собственное исключение?
Ответ
Создайте класс, наследующий от Exception или одного из его подклассов:
class ValidationException extends Exception {}
// Использование
throw new ValidationException("Данные не прошли валидацию");
Рекомендуется группировать исключения по смыслу (например, DatabaseException, AuthException).
Вопрос
Что делает функция set_exception_handler()?
Ответ
Функция set_exception_handler() регистрирует обработчик для неперехваченных исключений:
set_exception_handler(function (Throwable $t) {
error_log($t->getMessage());
echo "Произошла ошибка. Пожалуйста, попробуйте позже.";
});
throw new Exception("Необработанная ошибка");
Вызывается, если исключение не поймано ни одним catch.
Вопрос
Как отключить вывод ошибок в production?
Ответ
Установите в php.ini или через ini_set():
ini_set('display_errors', '0');
ini_set('log_errors', '1');
ini_set('error_log', '/path/to/php-errors.log');
Это предотвращает утечку информации о внутреннем устройстве приложения конечным пользователям.
Работа с базами данных
Вопрос
Какие расширения PHP поддерживают работу с MySQL?
Ответ
Основные расширения:
MySQLi(MySQL Improved) — процедурный и объектно-ориентированный интерфейс, поддерживает prepared statementsPDO(PHP Data Objects) — унифицированный интерфейс для работы с разными СУБД, включая MySQL
Расширение mysql устарело и удалено в PHP 7.0.
Вопрос
Что такое prepared statements и зачем они нужны?
Ответ
Prepared statements — это предварительно скомпилированные SQL-запросы с параметрами-заполнителями. Они предотвращают SQL-инъекции, так как данные передаются отдельно от кода запроса.
Пример с PDO:
$stmt = $pdo->prepare("SELECT * FROM users WHERE email = ?");
$stmt->execute([$email]);
$user = $stmt->fetch();
Значения автоматически экранируются.
Вопрос
Как подключиться к базе данных через PDO?
Ответ
Создайте экземпляр класса PDO, передав DSN, имя пользователя и пароль:
$dsn = "mysql:host=localhost;dbname=test;charset=utf8mb4";
$pdo = new PDO($dsn, $user, $pass, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
]);
Рекомендуется включать режим исключений и ассоциативную выборку по умолчанию.
Вопрос
Как получить все строки из результата запроса?
Ответ
Используйте метод fetchAll():
$stmt = $pdo->query("SELECT id, name FROM users");
$users = $stmt->fetchAll(); // массив ассоциативных массивов
Если ожидается много строк, лучше использовать fetch() в цикле, чтобы не перегружать память.
Вопрос
Как вставить запись и получить её ID?
Ответ
После выполнения INSERT вызовите lastInsertId():
$stmt = $pdo->prepare("INSERT INTO users (name) VALUES (?)");
$stmt->execute(["Анна"]);
$userId = $pdo->lastInsertId();
Метод возвращает строку, содержащую ID новой записи.
Вопрос
Что такое транзакция и как её использовать?
Ответ
Транзакция — это группа операций, выполняемых как единое целое: либо все успешно завершаются, либо ни одна не применяется.
Пример:
$pdo->beginTransaction();
try {
$pdo->exec("UPDATE accounts SET balance = balance - 100 WHERE id = 1");
$pdo->exec("UPDATE accounts SET balance = balance + 100 WHERE id = 2");
$pdo->commit();
} catch (Throwable $e) {
$pdo->rollBack();
throw $e;
}
Вопрос
Как обрабатывать ошибки подключения к БД?
Ответ
PDO выбрасывает исключение PDOException, если включён режим ERRMODE_EXCEPTION. Его можно перехватить:
try {
$pdo = new PDO($dsn, $user, $pass);
} catch (PDOException $e) {
die("Ошибка подключения: " . $e->getMessage());
}
Никогда не выводите детали ошибки в production.
Сессии и куки
Вопрос
Как начать сессию в PHP?
Ответ
Вызовите функцию session_start() в начале скрипта:
session_start();
$_SESSION['user_id'] = 123;
Сессия сохраняет данные между запросами на стороне сервера. Идентификатор сессии обычно передаётся через cookie PHPSESSID.
Вопрос
Как уничтожить сессию?
Ответ
Используйте комбинацию функций:
session_start();
session_unset(); // удаляет все переменные сессии
session_destroy(); // удаляет данные сессии на сервере
Также рекомендуется удалить cookie сессии, установив его в прошлое.
Вопрос
Как установить cookie?
Ответ
Функция setcookie() отправляет заголовок Set-Cookie:
setcookie('theme', 'dark', [
'expires' => time() + 86400 * 30, // 30 дней
'path' => '/',
'domain' => '.example.com',
'secure' => true,
'httponly' => true,
'samesite' => 'Strict'
]);
Cookie доступны в следующем запросе через $_COOKIE.
Вопрос
Чем отличается сессия от cookie?
Ответ
Сессия хранит данные на сервере, а клиенту передаётся только идентификатор (обычно через cookie).
Cookie хранят данные непосредственно в браузере пользователя.
Сессии безопаснее для хранения конфиденциальной информации, так как данные не покидают сервер.
Вопрос
Как защитить сессию от hijacking?
Ответ
Примените следующие меры:
- Установите
session.cookie_httponly = 1— запрет доступа к cookie через JavaScript - Установите
session.cookie_secure = 1— передача только по HTTPS - Используйте
session_regenerate_id(true)после входа пользователя - Привязывайте сессию к IP-адресу или User-Agent (осторожно — может нарушить UX)
HTTP и веб-специфика
Вопрос
Как отправить HTTP-заголовок в PHP?
Ответ
Используйте функцию header() до любого вывода:
header("Content-Type: application/json; charset=utf-8");
header("Cache-Control: no-store");
Если вывод уже начат, заголовки нельзя отправить (если не включён output buffering).
Вопрос
Как выполнить редирект?
Ответ
Отправьте заголовок Location и завершите скрипт:
header("Location: /new-page.php", true, 302);
exit;
Важно вызвать exit, чтобы предотвратить выполнение последующего кода.
Вопрос
Как получить метод HTTP-запроса?
Ответ
Метод доступен в суперглобальной переменной $_SERVER['REQUEST_METHOD']:
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// обработка POST-запроса
}
Вопрос
Как получить тело POST-запроса в формате JSON?
Ответ
Когда клиент отправляет JSON, данные не попадают в $_POST. Их нужно прочитать из входного потока:
$input = file_get_contents('php://input');
$data = json_decode($input, true);
Всегда проверяйте результат json_decode() на null.
Вопрос
Что такое CORS и как его настроить?
Ответ
CORS (Cross-Origin Resource Sharing) — механизм, позволяющий браузеру выполнять запросы с одного домена на другой. Настройка на стороне сервера:
header("Access-Control-Allow-Origin: https://trusted-site.com");
header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type, Authorization");
Для preflight-запросов (OPTIONS) нужно отдельно обрабатывать и завершать скрипт.
Управление зависимостями и инструменты
Вопрос
Что такое Composer?
Ответ
Composer — это менеджер зависимостей для PHP. Он управляет библиотеками и их версиями, автоматически загружает классы и обеспечивает совместимость между пакетами.
Файл composer.json описывает зависимости проекта:
{
"require": {
"monolog/monolog": "^3.0"
}
}
Команда composer install устанавливает указанные пакеты в директорию vendor/.
Вопрос
Как работает автозагрузка классов в Composer?
Ответ
Composer генерирует файл vendor/autoload.php, который регистрирует функцию автозагрузки на основе PSR-4 или других стандартов. Подключение этого файла даёт доступ ко всем установленным классам без явного require.
require_once 'vendor/autoload.php';
$log = new Monolog\Logger('name');
Вопрос
Что такое autoload в composer.json?
Ответ
Раздел autoload в composer.json определяет, как автозагружать классы текущего проекта:
{
"autoload": {
"psr-4": {
"App\\": "src/"
}
}
}
После изменения требуется выполнить composer dump-autoload.
CLI и скрипты командной строки
Вопрос
Можно ли запускать PHP-скрипты из командной строки?
Ответ
Да. PHP поддерживает режим CLI (Command Line Interface). Скрипт запускается командой:
php script.php arg1 arg2
Аргументы доступны через глобальный массив $argv.
Вопрос
Как получить аргументы командной строки?
Ответ
Аргументы передаются в массиве $argv. Первый элемент — имя скрипта, остальные — переданные параметры:
// cli.php
if ($argc < 2) {
echo "Использование: php cli.php <имя>\n";
exit(1);
}
echo "Привет, $argv[1]!\n";
Переменная $argc содержит количество аргументов.
Вопрос
Как обрабатывать опции вроде --verbose или -v?
Ответ
Используется встроенная функция getopt():
$options = getopt("v", ["verbose"]);
if (isset($options['v']) || isset($options['verbose'])) {
echo "Режим отладки включён\n";
}
Для сложных случаев применяют библиотеки, например symfony/console.
Тестирование
Вопрос
Какой фреймворк используется для unit-тестирования в PHP?
Ответ
PHPUnit — стандартный фреймворк для unit-тестирования в PHP. Он поддерживает assertions, моки, покрытие кода и интеграцию с CI.
Пример теста:
use PHPUnit\Framework\TestCase;
class MathTest extends TestCase {
public function testAdd(): void {
$this->assertEquals(4, add(2, 2));
}
}
Вопрос
Что такое мок-объект?
Ответ
Мок-объект — это имитация реального объекта, используемая в тестах для изоляции тестируемого кода. В PHPUnit создаётся через createMock():
$mock = $this->createMock(LoggerInterface::class);
$mock->method('log')->with('test');
Это позволяет контролировать поведение зависимостей.
Вопрос
Как проверить покрытие кода тестами?
Ответ
PHPUnit может генерировать отчёт о покрытии с помощью расширения Xdebug или PCOV:
phpunit --coverage-html coverage/
Отчёт показывает, какие строки и методы были выполнены во время тестов.
Фреймворки и архитектура
Вопрос
Что такое MVC?
Ответ
MVC (Model-View-Controller) — архитектурный паттерн, разделяющий приложение на три компонента:
- Model — работа с данными и бизнес-логикой
- View — отображение данных пользователю
- Controller — обработка входных запросов и координация Model и View
Большинство PHP-фреймворков (Laravel, Symfony) основаны на MVC или его вариациях.
Вопрос
Какие популярные PHP-фреймворки существуют?
Ответ
Наиболее распространённые фреймворки:
- Laravel — современный, богатый функционал, Eloquent ORM, Artisan CLI
- Symfony — модульный, enterprise-ориентированный, основа для многих систем
- CodeIgniter — лёгкий, минималистичный
- Yii — высокопроизводительный, с мощной генерацией кода
Выбор зависит от масштаба проекта и требований.
Вопрос
Что такое middleware?
Ответ
Middleware — это промежуточный слой, обрабатывающий HTTP-запрос до контроллера и/или ответ после него. Используется для:
- Аутентификации
- Логирования
- CORS
- Ограничения скорости
В Laravel middleware регистрируется в цепочке обработки запроса.
Вопрос
Что такое сервис-контейнер?
Ответ
Сервис-контейнер — это механизм управления зависимостями и внедрения зависимостей (DI). Он позволяет:
- Регистрировать классы и их зависимости
- Автоматически разрешать зависимости при создании объектов
- Кэшировать одиночные экземпляры (singleton)
Laravel и Symfony имеют мощные контейнеры.
Вопрос
Что такое репозиторий в архитектуре?
Ответ
Репозиторий — это паттерн, абстрагирующий доступ к данным. Он предоставляет методы вроде find(), save(), delete(), скрывая детали работы с БД.
interface UserRepository {
public function findById(int $id): ?User;
public function save(User $user): void;
}
Упрощает тестирование и замену источника данных.
Производительность и оптимизация
Вопрос
Что такое OPcache?
Ответ
OPcache — это встроенный в PHP модуль, кэширующий байт-код скриптов в памяти. Это устраняет необходимость повторной компиляции PHP-файлов при каждом запросе.
Включается в php.ini:
opcache.enable=1
opcache.memory_consumption=128
Обязателен в production-средах.
Вопрос
Как ускорить выполнение PHP-скриптов?
Ответ
Основные методы:
- Включить OPcache
- Минимизировать автозагрузку (оптимизировать
composer dump-autoload --optimize) - Использовать кэширование (Redis, Memcached) для тяжёлых вычислений или данных
- Избегать лишних запросов к БД (жадная загрузка, кэширование результатов)
- Использовать продакшен-режим (отключить
display_errors, включитьlog_errors)
Вопрос
Поддерживает ли PHP JIT?
Ответ
Да. Начиная с PHP 8.0, включена поддержка JIT (Just-In-Time компиляции) через OPcache. JIT компилирует горячие участки кода в машинный код, что может значительно ускорить CPU-интенсивные задачи (например, математические вычисления).
Включается в php.ini:
opcache.jit_buffer_size=100M
opcache.jit=1235
Для веб-приложений выигрыш часто незначителен, так как узкое место — I/O.
Совместимость и эволюция языка
Вопрос
Как проверить версию PHP?
Ответ
Версия доступна через константу PHP_VERSION или функцию phpversion():
echo PHP_VERSION; // например, "8.2.7"
Также можно использовать version_compare() для сравнения версий.
Вопрос
Как обеспечить совместимость кода с разными версиями PHP?
Ответ
Рекомендуется:
- Указать минимальную версию в
composer.json:"php": "^8.1" - Использовать статический анализатор (PHPStan, Psalm)
- Применять инструменты вроде
rectorдля автоматического обновления синтаксиса - Избегать устаревших функций (например,
ereg(),mysql_*)
Вопрос
Что такое полифилл?
Ответ
Полифилл — это библиотека, реализующая функциональность новой версии PHP в старых версиях. Например, пакет symfony/polyfill-php80 добавляет функции из PHP 8.0 в PHP 7.4.
Устанавливается через Composer и подключается автоматически.
Вопрос
Какие функции были удалены в PHP 8?
Ответ
В PHP 8 удалены устаревшие функции и расширения, включая:
- Все функции
mysql_* create_function()$GLOBALSкак superglobal в некоторых контекстах- Некоторые устаревшие параметры в функциях (
track_errors,allow_url_include)
Полный список доступен в официальной документации по миграции.
Вопрос
Что такое тип never?
Ответ
Тип never (введён в PHP 8.1) указывает, что функция никогда не завершается нормально — она либо выбрасывает исключение, либо завершает скрипт.
function abort(string $message): never {
throw new RuntimeException($message);
}
Используется для сигнализирования о нештатном завершении.
Вопрос
Что такое readonly-свойства?
Ответ
Readonly-свойства (PHP 8.1) могут быть инициализированы только один раз — при создании объекта. После этого любая попытка записи вызывает ошибку.
class User {
public function __construct(
public readonly string $name
) {}
}
$user = new User("Анна");
echo $user->name; // OK
$user->name = "Мария"; // Ошибка
Повышает безопасность и предсказуемость состояния объекта.
Вопрос
Что такое enums в PHP?
Ответ
Перечисления (enums), введённые в PHP 8.1, позволяют определить набор допустимых значений:
enum Status: string {
case Draft = 'draft';
case Published = 'published';
}
function publish(Status $status) { /* ... */ }
publish(Status::Published);
Поддерживаются скалярные (string, int) и чистые (без скалярных значений) перечисления.
Вопрос
Что такое fibers?
Ответ
Fibers (введены в PHP 8.1) — это примитив для легковесной кооперативной многозадачности. Позволяют приостанавливать и возобновлять выполнение функций без блокировки потока.
$fiber = new Fiber(function () {
$value = Fiber::suspend('пауза');
return $value + 1;
});
echo $fiber->start(); // "пауза"
echo $fiber->resume(10); // 11
Используются в асинхронных библиотеках (например, ReactPHP).
Вопрос
Как обрабатывать асинхронные операции в PHP?
Ответ
PHP сам по себе однопоточный, но поддерживает асинхронность через:
- Расширения:
Swoole,RoadRunner - Библиотеки:
ReactPHP,Amp - Fibers (начиная с PHP 8.1)
Эти инструменты позволяют обрабатывать множество соединений без блокировки, особенно полезно для микросервисов и очередей.
Вопрос
Что такое очередь задач (queue)?
Ответ
Очередь задач — это механизм отложенного выполнения операций (например, отправка email, обработка изображений). Задача помещается в очередь (Redis, RabbitMQ, база данных), а воркер обрабатывает её позже.
В Laravel используется компонент Queue с драйверами: database, redis, sqs.