Решение
1. Миграции для таблиц
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration {
public function up(): void {
// Таблица ролей
Schema::create("roles", function (Blueprint $table) {
$table->id();
$table->string("name", 50)->unique();
$table->timestamps();
});
// Добавляем role_id к пользователям
Schema::table("users", function (Blueprint $table) {
$table->foreignId("role_id")->constrained("roles")->default(2);
});
Мини-блог на Laravel: Полная реализация
Архитектура проекта
Используем современную архитектуру Laravel 10+ с разделением на:
Миграции БД
// database/migrations/create_users_table.php
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
// database/migrations/create_categories_table.php
Schema::create('categories', function (Blueprint $table) {
$table->id();
$table->string('name')->unique();
$table->string('slug')->unique();
$table->text('description')->nullable();
$table->timestamps();
});
Решение
1. Миграция базы данных
Создание таблицы items:
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration {
public function up(): void {
Schema::create("items", function (Blueprint $table) {
$table->id();
$table->string("name", 255)->nullable();
$table->string("key", 25)->unique();
$table->timestamps();
});
}
public function down(): void {
Schema::dropIfExists("items");
}
};
2. Eloquent модель
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Item extends Model {
protected $fillable = ["name", "key"];
protected $casts = [
"created_at" => "datetime",
"updated_at" => "datetime",
];
}
3. Form Request для валидации
<?php
namespace App\Http\Requests;
Решение
1. Миграция базы данных
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration {
public function up(): void {
Schema::create("short_links", function (Blueprint $table) {
$table->id();
$table->string("original_url", 2048);
$table->string("code", 10)->unique();
$table->unsignedInteger("clicks")->default(0);
$table->timestamps();
$table->index("code");
});
}
public function down(): void {
Schema::dropIfExists("short_links");
}
};
2. Eloquent модель
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class ShortLink extends Model {
protected $fillable = ["original_url", "code", "clicks"];
}
3. Service класс для логики
<?php
namespace App\Services;
Решение
1. Простая реализация Singleton
<?php
class Database {
// Статическое свойство для хранения единственного экземпляра
private static ?self $instance = null;
// Приватный конструктор - запрещает создание через new
private function __construct() {}
// Приватный метод клонирования - запрещает клонирование
private function __clone() {}
// Приватный метод десериализации - запрещает десериализацию
public function __wakeup() {
throw new Exception("Нельзя десериализовать Singleton");
}
// Статический метод для получения единственного экземпляра
public static function getInstance(): self {
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
public function connect() {
return "Connected to database";
}
}
// Использование
$db1 = Database::getInstance();
$db2 = Database::getInstance();
Решение
1. Миграции
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration {
public function up(): void {
// Таблица авторов
Schema::create("authors", function (Blueprint $table) {
$table->id();
$table->string("name", 255);
$table->date("birth_date")->nullable();
$table->text("biography")->nullable();
$table->timestamps();
$table->index("name");
});
Решение
1. Миграции и модели
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
class TaskStatus extends Model {
protected $fillable = ["name", "color", "description"];
public function tasks(): HasMany {
return $this->hasMany(Task::class, "status_id");
}
}
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class Task extends Model {
protected $fillable = ["title", "description", "status_id", "assigned_to", "priority", "due_date"];
protected $casts = ["due_date" => "datetime"];
public function status(): BelongsTo {
return $this->belongsTo(TaskStatus::class, "status_id");
}
public function assignee(): BelongsTo {
return $this->belongsTo(User::class, "assigned_to");
}
}
<?php
namespace App\Models;
Решение
1. Миграции
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration {
public function up(): void {
// Таблица обращений
Schema::create("inquiries", function (Blueprint $table) {
$table->id();
$table->string("name", 255);
$table->string("email", 255);
$table->string("phone", 20);
$table->text("message");
$table->enum("status", ["new", "in_progress", "completed"])->default("new");
$table->ipAddress("ip_address")->nullable();
$table->timestamps();
$table->index("status");
$table->index("created_at");
$table->index("email");
});
FizzBuzz: Полное решение с расширяемостью
Решение 1: Классический if-else
function fizzBuzz(int $number): string
{
if ($number % 15 === 0) {
return 'FizzBuzz';
}
if ($number % 3 === 0) {
return 'Fizz';
}
if ($number % 5 === 0) {
return 'Buzz';
}
return (string)$number;
}
function printFizzBuzz(int $limit = 100): void
{
$result = [];
for ($i = 1; $i <= $limit; $i++) {
$result[] = fizzBuzz($i);
}
echo implode(', ', $result);
}
printFizzBuzz(100);
Проблема: Не расширяемо. Если добавить новое правило, нужно переписывать функцию.
Решение 2: Массив правил (рекомендуется)
class Rule
{
public function __construct(
private int $divisor,
private string $output
) {}
public function apply(int $number): ?string
{
return $number % $this->divisor === 0 ? $this->output : null;
}
}
Развернуть строку без strrev(): Полное решение
Анализ задачи
Задача требует реализации функции разворачивания строки без использования встроенной функции strrev(). Ключевой момент - корректная работа с UTF-8 строками, так как просто разворачивание массива символов в UTF-8 может привести к нарушению кодировки многобайтовых символов.
Подход 1: Через цикл с mb_substr
Преимущества:
function reverseString(string $string): string
{
$reversed = '';
$length = mb_strlen($string, 'UTF-8');
for ($i = $length - 1; $i >= 0; $i--) {
$reversed .= mb_substr($string, $i, 1, 'UTF-8');
}
return $reversed;
}
Решение
Основные правила склонения
В русском языке есть три формы склонения для слова "программист":
Реализация
Решение
Рекурсивный подход
Самый простой и интуитивный способ реализации, прямо следующий определению Фибоначчи:
function fibonacciRecursive(int $n): int {
// Базовые случаи
if ($n <= 1) {
return $n;
}
// Рекурсивное вычисление
return fibonacciRecursive($n - 1) + fibonacciRecursive($n - 2);
}
Характеристики рекурсивного подхода:
Для n=7 функция вычислит fibonacciRecursive(6) и fibonacciRecursive(5), а fibonacciRecursive(5) вычислится дважды. Это ведёт к катастрофическому замедлению при больших n.
Итеративный подход
Более эффективная реализация через цикл:
Решение
1. Оптимальное решение (хеш-таблица) - O(n)
<?php
function findDuplicates(array $array): array {
$seen = [];
$duplicates = [];
foreach ($array as $value) {
// Нормализуем значение для сравнения (для объектов используем spl_object_hash)
$key = is_object($value) ? spl_object_hash($value) : json_encode($value);
if (isset($seen[$key])) {
// Если уже видели это значение и еще не добавили в дубликаты
if (!in_array($value, $duplicates, true)) {
$duplicates[] = $value;
}
} else {
$seen[$key] = true;
}
}
return array_values($duplicates);
}
// Примеры
echo json_encode(findDuplicates([1, 2, 3, 2, 4, 3, 5])); // [2, 3]
echo json_encode(findDuplicates(["a", "b", "a", "c", "b"])); // ["a", "b"]
echo json_encode(findDuplicates([1, 2, 3, 4, 5])); // []
Решение
1. Миграции
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
// Категории (иерархия)
return new class extends Migration {
public function up(): void {
Schema::create("categories", function (Blueprint $table) {
$table->id();
$table->string("name", 255);
$table->string("slug", 255)->unique();
$table->text("description")->nullable();
$table->unsignedBigInteger("parent_id")->nullable();
$table->integer("level")->default(1);
$table->timestamps();
$table->foreign("parent_id")->references("id")->on("categories")->nullOnDelete();
$table->index("parent_id");
});
Решение
1. Настройки PHP (php.ini)
; Увеличиваем лимиты для загрузки больших файлов
upload_max_filesize = 5G
post_max_size = 5G
max_execution_time = 0 ; Без ограничений
max_input_time = 0 ; Без ограничений
memory_limit = 512M ; Достаточно для обработки chunks
session.gc_maxlifetime = 86400
2. Конфигурация nginx
server {
listen 80;
server_name example.com;
# Увеличиваем размер тела запроса
client_max_body_size 5G;
client_body_timeout 300s;
client_header_timeout 300s;
# Буферизация для больших upload
client_body_buffer_size 128M;
location ~ \\.php$ {
fastcgi_read_timeout 600s;
fastcgi_send_timeout 600s;
# Другие параметры fastcgi
}
}
3. Миграция для хранения информации о загрузках
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
Решение
1. ProcessPool с pcntl_fork (Unix/Linux)
<?php
class ProcessTask {
private int $pid = -1;
private $callback;
private $result = null;
private ?Exception $exception = null;
public function __construct(callable $callback) {
$this->callback = $callback;
}
public function execute(): void {
$this->pid = pcntl_fork();
if ($this->pid === -1) {
throw new \Exception("Could not fork process");
}
// Дочерний процесс
if ($this->pid === 0) {
try {
$result = call_user_func($this->callback);
echo json_encode(["success" => true, "result" => $result]);
exit(0);
} catch (\Throwable $e) {
echo json_encode([
"success" => false,
"error" => $e->getMessage(),
]);
exit(1);
}
}
}
Импорт большого XML файла в базу данных: Production решение
Архитектура решения
Для импорта 50 ГБ XML файла необходимо использовать потоковую обработку с chunk-based разбиением, чтобы избежать загрузки всего файла в память. Рекомендуемый подход использует Laravel Queue для асинхронной обработки и обеспечения отказоустойчивости.
Выбор библиотеки
XMLReader vs SimpleXML:
XMLReader (рекомендуется):
SimpleXML:
Решение 1: XMLReader со streaming обработкой
// app/Services/XmlImportService.php
namespace App\Services;
use App\Jobs\ProcessXmlChunk;
use App\Models\ImportLog;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
REST API генератор случайных чисел: Полное решение
Архитектура решения
Для реализации требуемого функционала я буду использовать чистую архитектуру с разделением на слои: контроллеры, сервисы и модели. Это обеспечит масштабируемость и тестируемость кода.
Основные компоненты:
Миграция БД
// database/migrations/2024_01_15_create_random_generations_table.php
Schema::create('random_generations', function (Blueprint $table) {
$table->uuid('id')->primary();
$table->integer('min_value');
$table->integer('max_value');
$table->integer('generated_number');
$table->integer('count')->default(1);
$table->json('numbers')->nullable();
$table->ipAddress('ip_address');
$table->timestamps();
$table->index('created_at');
});
Модель
Решение
1. Миграции
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration {
public function up(): void {
// Таблица консультаций
Schema::create("consultations", function (Blueprint $table) {
$table->id();
$table->string("title", 255);
$table->text("description")->nullable();
$table->dateTime("start_at");
$table->dateTime("end_at");
$table->enum("format", ["offline", "online"]);
$table->integer("max_participants");
$table->string("location", 255)->nullable(); // Для очных
$table->string("meeting_link", 500)->nullable(); // Для онлайн
$table->boolean("is_active")->default(true);
$table->timestamps();
$table->index("start_at");
$table->index("is_active");
});
Решение
1. Простое решение (удаление символов)
<?php
function isPalindrome(string $text): bool {
// Преобразуем в нижний регистр
$text = mb_strtolower($text);
// Удаляем все символы кроме букв и цифр
$text = preg_replace('/[^\p{L}\p{N}]/u', '', $text);
// Сравниваем с развернутой строкой
return $text === strrev($text);
}
// Примеры
echo isPalindrome("А роза упала на лапу Азора") ? "true" : "false"; // true
echo isPalindrome("level") ? "true" : "false"; // true
echo isPalindrome("hello") ? "true" : "false"; // false
echo isPalindrome("Was it a car or a cat I saw") ? "true" : "false"; // true
echo isPalindrome("racecar") ? "true" : "false"; // true
Анализ сложности:
Решение
1. Миграции для таблиц
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration {
public function up(): void {
// Таблица зданий
Schema::create("buildings", function (Blueprint $table) {
$table->id();
$table->string("address", 500);
$table->string("city", 100);
$table->string("postal_code", 20)->nullable();
$table->decimal("latitude", 10, 8);
$table->decimal("longitude", 11, 8);
$table->text("description")->nullable();
$table->timestamps();
// Индекс для быстрого поиска по координатам
$table->spatialIndex(["latitude", "longitude"]);
});