PHP | Вопросы собесов
前往频道在 Telegram
Сайт: https://easyoffer.ru/ Все каналы: t.me/+xGeAw6ckJ4liYzQy Контакт для рекламы: @easyoffer_adv
显示更多2 341
订阅者
-124 小时
-47 天
-2430 天
帖子存档
🤔 Какое свойство ReflectionClass в PHP возвращает имена всех констант класса?
Что такое интерфейсы и для чего они нужны ?
Спросят с вероятностью 13%
Интерфейсы являются важным инструментом для определения контракта, который должны соблюдать классы. Интерфейс описывает набор методов, которые должны быть реализованы классом, но не содержит реализации этих методов. Помогают обеспечить гибкость, модульность и масштабируемость кода.
Что это такое?
Интерфейс — это абстрактный тип данных, который определяет набор методов, но не содержит их реализацию. Класс, реализующий интерфейс, должен предоставить конкретную реализацию всех методов, определенных в интерфейсе.
Определение
С помощью ключевого слова
interface. Все методы, объявленные в интерфейсе, должны быть публичными, и класс, реализующий интерфейс, обязан реализовать все его методы.
Пример
<?php
interface Logger {
public function log(string $message);
}
?>
Реализация
Класс, реализующий интерфейс, должен использовать ключевое слово implements и реализовать все методы, объявленные в интерфейсе.
<?php
class FileLogger implements Logger {
public function log(string $message) {
// Реализация записи сообщения в файл
file_put_contents('log.txt', $message . PHP_EOL, FILE_APPEND);
}
}
class DatabaseLogger implements Logger {
public function log(string $message) {
// Реализация записи сообщения в базу данных
// $db->query("INSERT INTO logs (message) VALUES ('$message')");
}
}
?>
Зачем они нужны?
1️⃣Определение контракта:
Интерфейсы задают контракт, который должны соблюдать классы. Это гарантирует, что класс, реализующий интерфейс, будет иметь все необходимые методы с определенными сигнатурами.
2️⃣Гибкость и расширяемость:
Интерфейсы позволяют легко расширять функциональность приложения. Если необходимо добавить новый способ логирования, достаточно создать новый класс, реализующий интерфейс Logger, без изменения существующего кода.
3️⃣Многообразие реализаций:
Интерфейсы позволяют использовать различные реализации одного и того же набора методов. Это особенно полезно при использовании паттернов проектирования, таких как стратегия или фабричный метод.
4️⃣Поддержка полиморфизма:
Интерфейсы позволяют использовать полиморфизм, где объекты разных классов могут быть обработаны одинаковым образом, если они реализуют один и тот же интерфейс.
Пример
<?php
function logMessage(Logger $logger, string $message) {
$logger->log($message);
}
$fileLogger = new FileLogger();
$databaseLogger = new DatabaseLogger();
logMessage($fileLogger, "Сообщение для файла");
logMessage($databaseLogger, "Сообщение для базы данных");
?>
5️⃣Упрощение тестирования:
Интерфейсы облегчают создание заглушек и моков для юнит-тестирования, что упрощает процесс тестирования компонентов приложения.
Примеры
1️⃣Проектирование систем с плагинами:
Интерфейсы позволяют создавать расширяемые системы, в которых можно легко добавлять новые плагины.
2️⃣Разделение ответственности:
Использование интерфейсов помогает четко разделять ответственность между различными компонентами системы.
3️⃣Инверсия управления (IoC):
Интерфейсы часто используются в контейнерах инверсии управления для внедрения зависимостей.
Интерфейсы определяют набор методов, которые должны быть реализованы классами. Они обеспечивают гибкость, модульность, масштабируемость и поддержку полиморфизма, упрощая расширение функциональности и тестирование кода.
👉 Можно посмотреть Примеры как отвечают люди на этот вопрос, или перейти к списку 385 вопросов на PHP разработчика. Ставь 👍 если нравится контент
🔐 База собесов | 🔐 База тестовыхЧто такое стрелочные и анонимные функции ?
Спросят с вероятностью 13%
Стрелочные функции (также известные как лямбда-функции) и анонимные функции служат для создания функций без имени, которые могут быть использованы в качестве значений переменных, параметров функций или просто для выполнения некоторого действия на месте.
Анонимные функции
Это функции без имени, которые часто используются для создания функций-замыканий. Замыкания позволяют функциям захватывать переменные из своей области видимости. Анонимные функции создаются с использованием ключевого слова
function.
<?php
$sayHello = function($name) {
return "Привет, $name!";
};
echo $sayHello("Мир"); // Выведет: Привет, Мир!
?>
В этом примере функция, которая выводит приветствие, создана без имени и присвоена переменной $sayHello.
Стрелочные функции
Были введены в PHP 7.4 и представляют собой более компактный способ создания анонимных функций. Они используют синтаксис fn и автоматически захватывают переменные из внешней области видимости по значению.
<?php
$factor = 10;
$multiply = fn($x) => $x * $factor;
echo $multiply(5); // Выведет: 50
?>
В этом примере стрелочная функция умножает переданное значение на переменную $factor, которая была захвачена из внешней области видимости.
Зачем это нужно?
✅Удобство: Создание функций на месте без необходимости придумывать имена.
✅Замыкания: Возможность захвата переменных из внешней области видимости.
✅Читабельность кода: Стрелочные функции делают код более лаконичным и читаемым.
Как это используется?
✅Фильтрация и сортировка массивов: Часто используются в функциях вроде array_filter, array_map и usort.
✅Колбэки: Передача функции в качестве аргумента в другие функции (например, для обработки событий).
Пример:
<?php
$numbers = [1, 2, 3, 4, 5];
$squared = array_map(fn($n) => $n * $n, $numbers);
print_r($squared); // Выведет: Array ( [0] => 1 [1] => 4 [2] => 9 [3] => 16 [4] => 25 )
?>
Анонимные функции и стрелочные функции в PHP позволяют создавать функции без имени, что удобно для быстрого и лаконичного кода. Они часто используются для создания замыканий и обработки массивов.
👉 Можно посмотреть Примеры как отвечают люди на этот вопрос, или перейти к списку 385 вопросов на PHP разработчика. Ставь 👍 если нравится контент
🔐 База собесов | 🔐 База тестовых🤔 Какое ключевое слово используется для наследования класса в PHP?
Что такое типизация ?
Спросят с вероятностью 13%
Типизация — это концепция, которая определяет, каким образом и когда типы данных присваиваются переменным. Типы данных определяют, какие операции могут быть выполнены с данными, как они хранятся в памяти и как интерпретируются. Существует несколько аспектов типизации, включая строгость и время проверки типов.
Основные виды
1️⃣Статическая и динамическая типизация
✅Статическая типизация: Типы переменных определяются во время компиляции, и их проверка осуществляется компилятором. Это позволяет обнаруживать ошибки типов до выполнения программы. Языки со статической типизацией включают Java, C++, и TypeScript.
int number = 10; // Тип переменной number определён как int
number = "Hello"; // Ошибка: Нельзя присвоить строку переменной типа int
✅Динамическая типизация: Типы переменных определяются во время выполнения программы, и типы могут изменяться. Это обеспечивает большую гибкость, но ошибки типов могут возникать только во время выполнения. Языки с динамической типизацией включают Python, JavaScript и PHP.
number = 10 # Тип переменной number определяется как int
number = "Hello" # Теперь тип переменной number определяется как str
2️⃣Сильная и слабая типизация
✅Сильная типизация: Типы строго контролируются, и не допускается неявное преобразование типов, которое могло бы привести к ошибкам. Языки со строгой типизацией включают Python и Java.
number = 10
result = number + "10" # Ошибка: нельзя складывать int и str
✅Слабая типизация: Языки допускают неявное преобразование типов, что может приводить к неожиданным результатам. Языки со слабой типизацией включают JavaScript и PHP.
var number = 10;
var result = number + "10"; // Неявное преобразование int в str, result будет "1010"
Поддерживает динамическую и слабую типизацию, но с введением PHP 7, также поддерживается и строгая типизация с помощью деклараций типов и строгих типов.
Динамическая типизация
<?php
$var = 10; // $var — это integer
$var = "Hello"; // Теперь $var — это string
?>
Преобразование типов
<?php
$number = 10;
$string = "20";
$result = $number + $string; // $string будет неявно преобразован в integer, результат будет 30
?>
Строгая типизация
<?php
declare(strict_types=1);
function add(int $a, int $b): int {
return $a + $b;
}
echo add(5, 10); // Работает нормально
echo add(5, "10"); // Ошибка: аргумент должен быть int
?>
Зачем она нужна?
1️⃣Повышение надежности кода: Помогает обнаруживать и предотвращать ошибки типов на ранних стадиях разработки.
2️⃣Улучшение читаемости кода: Типы данных делают код более понятным для разработчиков, позволяя легко понять, какие значения ожидаются и возвращаются функциями.
3️⃣Оптимизация производительности: Статическая типизация позволяет компиляторам выполнять оптимизации, улучшая производительность программы.
4️⃣Улучшение безопасности кода: Строгая типизация предотвращает неявные преобразования типов, которые могут привести к непредсказуемым результатам.
Типизация — это концепция, определяющая, как и когда типы данных присваиваются переменным в программе. Существует статическая и динамическая типизация, а также сильная и слабая типизация. Помогает повысить надежность, читаемость, производительность и безопасность кода.
👉 Можно посмотреть Примеры как отвечают люди на этот вопрос, или перейти к списку 385 вопросов на PHP разработчика. Ставь 👍 если нравится контент
🔐 База собесов | 🔐 База тестовыхPodlodka PHP Crew — это серия онлайн-конференций для php-разработчиков с упором на практическую пользу.
Сессии проходят в удобное время утром и вечером, так что можно участвовать без отрыва от работы или отдыха.
Уже 30 сентября стартует новый сезон, где обсудим архитектуру:
- Как документировать сложные системы по модели C4, разберемся с Кириллом Сурогатовым (Oxagile);
- Как выбрать между RabbitMQ и Kafka для обработки большого количества сообщений, обсудим на конкретных кейсах с Михаилом Камориным (Skyeng);
- Лайвкодинг по Temporal — Алексей Гагарин, Павел Бучнев (Spiral Scout) наглядно покажут, как этот инструмент упрощает жизнь разработчикам;
- Как ускорить работу PHP-монолита с RoadRunner, поделится Владимир Плахотников (Yclients).
Каждый доклад — это готовое решение, которое можно внедрить в свой проект. Билеты и подробности на сайте: https://podlodka.io/phpcrew
🤔Какой оператор используется для проверки эквивалентности, учитывая типы данных, в PHP?
📌 Что такое первичный ключ?
💬 Спрашивают в 13% собеседований
Первичный ключ (primary key) — это одно или несколько полей (колонок) в таблице базы данных, которые однозначно идентифицируют каждую запись (строку) в этой таблице. Первичный ключ должен быть уникальным для каждой строки и не должен содержать NULL значения.
🤔 Основные характеристики:
1️⃣ Уникальность:
➕ Значения первичного ключа должны быть уникальными. Это означает, что ни одна запись в таблице не может иметь одинаковые значения в столбце или комбинации столбцов, которые образуют первичный ключ.
2️⃣ Необходимость значения:
➕ Поле первичного ключа не может содержать NULL значение. Каждая запись должна иметь определенное значение первичного ключа.
3️⃣ Идентификация записей:
➕ Первичный ключ используется для идентификации и поиска отдельных записей в таблице. Это помогает ускорить операции поиска и сортировки.
🤔 Пример:
CREATE TABLE users (
id INT AUTO_INCREMENT,
username VARCHAR(50) NOT NULL,
email VARCHAR(100) NOT NULL,
PRIMARY KEY (id)
);
В этом примере:
➕ Поле id является первичным ключом. Оно автоматически увеличивается (AUTO_INCREMENT) с каждой новой записью, обеспечивая уникальность.
➕ username и email — это другие поля таблицы, которые могут содержать информацию о пользователе.
🤔 Составной первичный ключ:
Иногда для уникальной идентификации записи требуется несколько полей. В этом случае используется составной первичный ключ.
Пример таблицы с составным первичным ключом:
CREATE TABLE orders (
order_id INT,
product_id INT,
quantity INT,
PRIMARY KEY (order_id, product_id)
);
В этом примере:
➕ Комбинация полей order_id и product_id уникально идентифицирует каждую запись в таблице, обеспечивая, что для каждого заказа и продукта существует только одна запись.
🤔 Преимущества:
1️⃣ Ускорение поиска:
➕ Индексирование по первичному ключу позволяет значительно ускорить операции поиска, сортировки и фильтрации данных.
2️⃣ Обеспечение целостности данных:
➕ Уникальность и наличие значений в первичном ключе помогают предотвратить дублирование записей и обеспечивают целостность данных.
3️⃣ Связи между таблицами:
➕ Первичные ключи играют важную роль в создании и поддержании связей между таблицами (внешние ключи), что важно для нормализации баз данных и поддержания структурированной информации.
Если объяснить совсем просто: первичный ключ — это как уникальный номер паспорта для каждой записи в таблице, который помогает быстро найти и отличить одну запись от другой.
🔥 ТОП ВОПРОСОВ С СОБЕСОВ
🔒 База собесов | 🔒 База тестовыхМентор поможет сэкономить время и быстрее зайти в IT
https://easyoffer.ru/mentor
🤔 Какой интерфейс используется для создания коллекций, которые можно перебрать с помощью foreach в PHP?
В чем отличие self от static ?
Спросят с вероятностью 13%
self и static используются для доступа к статическим методам и свойствам класса, но между ними есть важные различия. Эти различия касаются поведения при наследовании классов.
self
✅Прямое обращение к текущему классу: Используется для обращения к статическим методам и свойствам текущего класса. Он не учитывает наследование, поэтому всегда ссылается на класс, в котором он был написан.
✅Раннее связывание (early binding): Осуществляет раннее связывание, что означает, что он связывается с классом во время компиляции.
<?php
class Base {
public static function who() {
echo __CLASS__;
}
public static function test() {
self::who(); // всегда вызывает метод who() класса Base
}
}
class Child extends Base {
public static function who() {
echo CLASS;
}
}
Child::test(); // Выведет: Base
?>
В этом примере, несмотря на то, что метод test вызывается у класса Child, использование self::who() приводит к вызову метода who() класса Base.
static
✅Позднее статическое связывание: Используется для обращения к статическим методам и свойствам класса и учитывает контекст вызова, что означает, что он ссылается на класс, в котором метод был вызван, а не в котором он был написан.
✅Позднее связывание (late binding): Осуществляет позднее связывание, что означает, что он связывается с классом во время выполнения.
<?php
class Base {
public static function who() {
echo() {
}
public static function test() {
static::who(); // вызывает метод who() класса, от которого был вызван метод test
}
}
class Child extends Base {
public static function who() {
echo CLASS;
}
}
Child::test(); // Выведет: Child
?>
В этом примере использование static::who() приводит к вызову метода who() класса Child, потому что метод test был вызван у класса Child.
✅`self` всегда ссылается на текущий класс, в котором он был написан, и не учитывает наследование. Он использует раннее связывание.
✅`static` учитывает наследование и ссылается на класс, от которого был вызван метод, использует позднее связывание.
👉 Можно посмотреть Примеры как отвечают люди на этот вопрос, или перейти к списку 385 вопросов на PHP разработчика. Ставь 👍 если нравится контент
🔐 База собесов | 🔐 База тестовых🤔 Какое ключевое слово используется для импорта пространств имен в PHP?
В composer.json чем отличаются require и require-dev ?
Спросят с вероятностью 13%
В файле
composer.json секции require и require-dev используются для определения зависимостей вашего проекта, но у них разные назначения.
require
Содержит список пакетов, которые необходимы для работы вашего приложения в любой среде. Эти зависимости требуются для выполнения основного функционала приложения, и они будут установлены независимо от того, в какой среде (разработка, тестирование, продуктив) вы находитесь.
{
"require": {
"monolog/monolog": "^2.0",
"guzzlehttp/guzzle": "^7.0"
}
}
В этом примере указаны две зависимости, необходимые для работы приложения:
✅monolog/monolog: библиотека для логирования.
✅guzzlehttp/guzzle: HTTP-клиент.
Эти библиотеки будут установлены при запуске команды composer install как в среде разработки, так и в продуктивной среде.
require-dev
Содержит список пакетов, которые необходимы только для разработки и тестирования приложения. Эти зависимости включают в себя инструменты тестирования, отладки и другие пакеты, которые не требуются в продуктивной среде.
{
"require-dev": {
"phpunit/phpunit": "^9.0",
"friendsofphp/php-cs-fixer": "^2.0"
}
}
В этом примере указаны две зависимости, необходимые только для разработки:
✅phpunit/phpunit: библиотека для написания и выполнения тестов.
✅friendsofphp/php-cs-fixer: инструмент для автоматического форматирования кода.
Эти библиотеки будут установлены только при запуске команды composer install с флагом --dev или composer install в среде разработки, но не будут установлены в продуктивной среде, если команда composer install выполняется с флагом --no-dev.
Основные отличия:
1️⃣Назначение:
✅require: Зависимости, необходимые для работы приложения в любой среде.
✅require-dev: Зависимости, необходимые только для разработки и тестирования.
2️⃣Установка:
✅require: Устанавливаются всегда при выполнении команды composer install.
✅require-dev: Устанавливаются только при выполнении команды composer install без флага --no-dev.
3️⃣Использование в продакшн среде:
✅require: Всегда устанавливаются в продакшн среде.
✅require-dev: Не устанавливаются в продакшн среде, если используется флаг --no-dev.
{
"name": "myproject",
"description": "A simple project.",
"authors": [
{
"name": "John Doe",
"email": "john.doe@example.com"
}
],
"require": {
"monolog/monolog": "^2.0",
"guzzlehttp/guzzle": "^7.0"
},
"require-dev": {
"phpunit/phpunit": "^9.0",
"friendsofphp/php-cs-fixer": "^2.0"
}
}
Команды Composer:
✅Установка всех зависимостей:
composer install
Эта команда установит все зависимости из секций require и require-dev.
✅Установка только продакшн зависимостей:
composer install --no-dev
Эта команда установит только зависимости из секции require.
Если объяснить совсем просто: require — это обязательные библиотеки для работы приложения, а require-dev — это дополнительные библиотеки, нужные только разработчикам для работы и тестирования.
👉 Можно посмотреть Примеры как отвечают люди на этот вопрос, или перейти к списку 385 вопросов на PHP разработчика. Ставь 👍 если нравится контент
🔐 База собесов | 🔐 База тестовых🤔 Какой из модификаторов доступа в PHP делает свойство или метод доступным только внутри класса?
В чем заключается смысл полиморфизма ?
Спросят с вероятностью 13%
Полиморфизм — это одна из основных концепций ООП, которая позволяет объектам разных классов быть обработанными через один и тот же интерфейс. Это достигается благодаря способности методов принимать объекты различных типов, что позволяет использовать один и тот же код для обработки разных типов объектов.
Основные виды
1️⃣Полиморфизм подтипов (или включения):
✅Это наиболее распространенный вид полиморфизма в ООП, который достигается через наследование и интерфейсы. Он позволяет объекту производного класса использоваться везде, где ожидается объект базового класса.
✅Использование базового класса или интерфейса для работы с объектами производных классов.
2️⃣Ад-хок полиморфизм (или перегрузка):
✅Это способность функций обрабатывать объекты разного типа, используя перегрузку методов или операторов. Это достигается за счет объявления нескольких версий одной и той же функции с разными параметрами.
✅Перегрузка методов в одном классе, когда методы имеют одинаковое имя, но разные параметры.
Рассмотрим пример, где полиморфизм подтипов используется для обработки объектов различных классов через общий интерфейс.
<?php
// Определение интерфейса
interface Shape {
public function draw();
}
// Реализация интерфейса в классе Circle
class Circle implements Shape {
public function draw() {
echo "Drawing a Circle\n";
}
}
// Реализация интерфейса в классе Square
class Square implements Shape {
public function draw() {
echo "Drawing a Square\n";
}
}
// Функция, принимающая объект любого класса, реализующего интерфейс Shape
function renderShape(Shape $shape) {
$shape->draw();
}
// Создание объектов классов Circle и Square
$circle = new Circle();
$square = new Square();
// Вызов функции renderShape для каждого объекта
renderShape($circle); // Выведет "Drawing a Circle"
renderShape($square); // Выведет "Drawing a Square"
?>
В этом примере функция renderShape принимает аргумент типа Shape, что позволяет ей работать с любым объектом, реализующим этот интерфейс, будь то Circle или Square. Это и есть полиморфизм подтипов.
Хотя не поддерживает перегрузку методов непосредственно, вы можете использовать аргументы с заданными значениями по умолчанию и типизацию аргументов для достижения похожего результата.
<?php
class Printer {
// Метод с необязательным аргументом
public function printData($data = null) {
if (is_null($data)) {
echo "No data provided\n";
} elseif (is_array($data)) {
echo "Array: " . implode(", ", $data) . "\n";
} elseif (is_string($data)) {
echo "String: " . $data . "\n";
} else {
echo "Unknown type\n";
}
}
}
$printer = new Printer();
$printer->printData(); // Выведет "No data provided"
$printer->printData("Hello"); // Выведет "String: Hello"
$printer->printData([1, 2, 3]); // Выведет "Array: 1, 2, 3"
?>
Смысл
✅Универсальность кода: Позволяет писать более универсальный и гибкий код, который может работать с объектами разных типов без необходимости изменять его.
✅Расширяемость: Легче добавлять новые классы и методы, которые интегрируются с существующей системой, не затрагивая её структуру.
✅Упрощение дизайна: Помогает создавать более чистую и понятную архитектуру, где объекты взаимодействуют через общие интерфейсы.
Полиморфизм позволяет объектам разных классов обрабатываться одинаково через общий интерфейс, улучшая универсальность, расширяемость и дизайн кода.
👉 Можно посмотреть Примеры как отвечают люди на этот вопрос, или перейти к списку 385 вопросов на PHP разработчика. Ставь 👍 если нравится контент
🔐 База собесов | 🔐 База тестовых🤔 Какой метод используется для объединения массивов в PHP?
Чем отличается stop от мока ?
Спросят с вероятностью 13%
В ООП и, в частности, в тестировании, существуют разные методы и инструменты для создания поддельных объектов, которые используются для замены реальных зависимостей в тестах. Два из таких методов — это stubs (стабы) и mocks (моки). Они имеют разные цели и используются по-разному.
Stubs (Стабы)
Это простые поддельные объекты, которые возвращают заранее заданные данные, когда их методы вызываются. Они не проверяют, как они были вызваны, а лишь предоставляют фиксированные ответы, необходимые для теста.
Основные характеристики:
✅Цель: Возврат фиксированных значений.
✅Использование: Подставляют зависимости, чтобы изолировать тестируемый код от внешних влияний.
✅Проверка: Не проверяют взаимодействия с тестируемым кодом.
class User {
private $database;
public function __construct(Database $database) {
$this->database = $database;
}
public function getUserName($userId) {
return $this->database->fetchUserName($userId);
}
}
class DatabaseStub {
public function fetchUserName($userId) {
return 'John Doe';
}
}
$databaseStub = new DatabaseStub();
$user = new User($databaseStub);
echo $user->getUserName(1); // Выведет "John Doe"
В этом примере DatabaseStub возвращает фиксированное значение 'John Doe', когда вызывается метод fetchUserName.
Mocks (Моки)
Это поддельные объекты, которые не только возвращают фиксированные данные, но и проверяют, как они были вызваны. Моки позволяют задавать ожидания относительно вызовов их методов и проверяют, что эти ожидания выполнены во время выполнения теста.
Основные характеристики:
✅Цель: Проверка взаимодействий и поведения.
✅Использование: Подменяют зависимости и проверяют, как тестируемый код взаимодействует с ними.
✅Проверка: Проверяют вызовы методов, аргументы вызовов и количество вызовов.
use PHPUnit\Framework\TestCase;
class UserTest extends TestCase {
public function testGetUserName() {
// Создаем мок объекта Database
$databaseMock = $this->createMock(Database::class);
// Задаем ожидания: метод fetchUserName должен быть вызван с аргументом 1 и вернуть 'John Doe'
$databaseMock->expects($this->once())
->method('fetchUserName')
->with($this->equalTo(1))
->willReturn('John Doe');
$user = new User($databaseMock);
$this->assertEquals('John Doe', $user->getUserName(1));
}
}
В этом примере мы используем PHPUnit для создания мока Database. Мы задаем ожидание, что метод fetchUserName будет вызван один раз с аргументом 1 и вернет 'John Doe'.
Основные отличия:
1️⃣Назначение:
✅Стабы: Возвращают заранее заданные данные, изолируя тестируемый код от реальных зависимостей.
✅Моки: Проверяют взаимодействия и поведение тестируемого кода с его зависимостями.
2️⃣Фокус:
✅Стабы: Сфокусированы на данных, которые возвращаются.
✅Моки: Сфокусированы на том, как методы были вызваны, с какими аргументами и сколько раз.
3️⃣Простота:
✅Стабы: Просты в реализации и не проверяют взаимодействия.
✅Моки: Более сложные, так как включают проверки взаимодействий и поведения.
Если объяснить совсем просто: стабы возвращают заранее заданные ответы, а моки проверяют, как именно и сколько раз их методы были вызваны.
👉 Можно посмотреть Примеры как отвечают люди на этот вопрос, или перейти к списку 385 вопросов на PHP разработчика. Ставь 👍 если нравится контент
🔐 База собесов | 🔐 База тестовых🤔 Какой оператор в PHP проверяет, определена ли переменная?
