<!DOCTYPE html>
<html class="h-100" data-bs-theme="light" data-mantine-color-scheme="light" lang="ru" prefix="og: https://ogp.me/ns#">
<head>
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
<link crossorigin="true" href="https://cdn.hexlet.io" rel="preconnect">
<link href="https://mc.yandex.ru" rel="preconnect">
<meta content="aa2vrdtq64dub8knuf83lwywit311w" name="facebook-domain-verification">
<link href="/favicon.ico" rel="icon" sizes="any">
<link href="/favicon.svg" rel="icon" type="image/svg+xml">
<link href="/apple-touch-icon.png" rel="apple-touch-icon">
<link href="/manifest.webmanifest" rel="manifest">
<script>
//<![CDATA[
window.gon={};gon.ym_counter="25559621";gon.is_bot=true;gon.applications={};gon.current_user={"id":null,"last_viewed_notification_id":null,"email":null,"state":null,"first_name":"","last_name":"","created_at":"2026-02-26 20:27:04 UTC","current_program":null,"current_team":null,"full_name":"","guest":true,"can_use_paid_features":false,"is_hexlet_employee":false,"sanitized_phone_number":"","can_subscribe":true,"can_renew_education":false};gon.token="a7V-xaKppP6oVssTRNNurqDDO9N8e_jZRyyf8SmoM9SEZLXyUNcJnh4V74tI3J7ZYMoWeXRMBnv6zAWle6_Uug";gon.locale="ru";gon.language="ru";gon.theme="light";gon.rails_env="production";gon.mobile=false;gon.google={"analytics_key":"UA-1360700-51","optimize_key":"GTM-5QDVFPF"};gon.captcha={"google_v3_site_key":"6LenGbgZAAAAAM7HbrDbn5JlizCSzPcS767c9vaY","yandex_site_key":"ysc1_Vyob5ZPPUdPBsu0ykt8bVFdzsfpoVjQChLGl2b4g19647a89","verification_failed":null};gon.social_signin=false;gon.typoreporter_google_form_id="1FAIpQLSeibfGq-KvWQ2Fyru-zkFFRVTLBuzXAHAoEyN1p49FtDmNoNA";
//]]>
</script>
<meta charset="utf-8">
<title>Микрофреймворк Slim | Веб-разработка на PHP</title>
<meta name="description" content="Микрофреймворк Slim / Веб-разработка на PHP: Знакомимся с созданием сайтов на фреймворках">
<link rel="canonical" href="https://ru.hexlet.io/courses/php-mvc/lessons/slim/theory_unit">
<meta name="robots" content="noarchive">
<meta property="og:title" content="Микрофреймворк Slim">
<meta property="og:title" content="Веб-разработка на PHP">
<meta property="og:description" content="Микрофреймворк Slim / Веб-разработка на PHP: Знакомимся с созданием сайтов на фреймворках">
<meta property="og:url" content="https://ru.hexlet.io/courses/php-mvc/lessons/slim/theory_unit">
<meta name="csrf-param" content="authenticity_token" />
<meta name="csrf-token" content="d_J60dW_Z96JbAs4T2zwL1jj1f4IundvtXS59CceM5iYI7HmJ8HKvj8vL6BDYwBYmOr4VACNic0IlCOgdRnU9g" />
<script src="/vite/assets/inertia-DfXos102.js" crossorigin="anonymous" type="module"></script><link rel="modulepreload" href="/vite/assets/chunk-DsPFFUou.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/preload-helper-BJ4cLWpC.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/init-BrRXra1y.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/ahoy-DrlRQ-1D.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/analytics-cb8xch9l.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/ErrorFallbackBlock-naDSYSy9.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Surface-DL2bpZA-.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/gon-D3e4yh1x.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/mantine-CGMYrt2Y.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/utils-DRqSHbQE.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/routes-CCH8ilKF.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/extends-C-EagtpE.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/inheritsLoose-BBd-DCVI.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/objectWithoutPropertiesLoose-DRHXDhjp.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/index.esm-DAqKOkZ0.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Button-CGPUux8l.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/CloseButton-D1euiPao.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Group-BX48WcuU.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Loader-BQEY8g6v.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Modal-Cy3HByv7.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/OptionalPortal-1Hza5P2w.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Stack-CtjJzfw4.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Textarea-Ck64llAy.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Box-B5-OOzBf.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/DirectionProvider-Dc9zdUke.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/events-DJQOhap0.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/use-reduced-motion-D2owz4wa.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/use-disclosure-zKtK5W1r.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/use-hotkeys-Cnc_Rwkb.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/random-id-DOQyszCZ.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/notifications.store-C-3AFSMn.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/exports-C_MrNx_T.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/axios-BEvgo0ym.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/dayjs.min-BkKovM-s.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/i18next-BlSq9s7B.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/client-U9M77rxp.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/react-dom-DaLxUz_h.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/useTranslation-Bx1Cdrkz.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/compiler-runtime-6XxiPFnt.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/jsx-runtime-CwjcCKJi.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/react-CkL4ZRHB.js" as="script" crossorigin="anonymous">
<link rel="stylesheet" href="/vite/assets/application-BqhCP46M.js" />
<script src="/vite/assets/application-Df9RExpe.js" crossorigin="anonymous" type="module"></script><link rel="modulepreload" href="/vite/assets/chunk-DsPFFUou.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/autocomplete-VMNbxKGl.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/routes-CCH8ilKF.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/createPopper-C3aM9r1M.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/js.cookie-D1-O8zkX.js" as="script" crossorigin="anonymous"><link rel="stylesheet" href="/vite/assets/application-C8HjmMaq.css" media="screen" />
<script>
window.ym = function(){(ym.a=ym.a||[]).push(arguments)};
window.addEventListener('load', function() {
setTimeout(function() {
ym.l = 1*new Date();
ym(window.gon.ym_counter, "init", {
clickmap: true,
trackLinks: true,
accurateTrackBounce: true,
webvisor: true
});
// Загружаем скрипт
var k = document.createElement('script');
k.async = 1;
k.src = 'https://mc.yandex.ru/metrika/tag.js';
document.head.appendChild(k);
ym(window.gon.ym_counter, 'getClientID', function(clientID) {
window.ymClientId = clientID;
});
}, 1500);
});
</script>
<!-- Google Tag Manager - deferred -->
<script>
// dataLayer stub сразу — пуши работают до загрузки скрипта
window.dataLayer = window.dataLayer || [];
// Сам скрипт — отложенно после load
window.addEventListener('load', function() {
setTimeout(function() {
dataLayer.push({'gtm.start': new Date().getTime(), event: 'gtm.js'});
var j = document.createElement('script');
j.async = true;
j.src = 'https://www.googletagmanager.com/gtm.js?id=GTM-WK88TH';
document.head.appendChild(j);
}, 1500);
});
</script>
<!-- End Google Tag Manager -->
</head>
<body>
<noscript>
<div>
<img alt="" src="https://mc.yandex.ru/watch/25559621" style="position:absolute; left:-9999px;">
</div>
</noscript>
<header class="sticky-top bg-body">
<nav class="navbar navbar-expand-lg">
<div class="container-xxl">
<a class="navbar-brand" href="/"><img alt="Логотип Хекслета" height="24" src="https://ru.hexlet.io/vite/assets/logo_ru_light-BpiEA1LT.svg" width="96">
</a><button aria-controls="collapsable" aria-expanded="false" aria-label="Меню" class="navbar-toggler border-0 mb-0 mt-1" data-bs-target="#collapsable" data-bs-toggle="collapse">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="collapsable">
<ul class="navbar-nav mb-lg-0 mt-lg-1">
<li class="nav-item dropdown">
<button aria-haspopup class="btn nav-link" data-bs-toggle="dropdown" type="button">
Все курсы
<span class="bi bi-chevron-down align-middle ms-1"></span>
</button>
<ul class="dropdown-menu">
<li>
<a class="dropdown-item d-flex py-2" href="/courses"><div class="fw-bold me-auto">Все что есть</div>
<div class="text-muted">117</div>
</a></li>
<li>
<hr class="dropdown-divider">
</li>
<li class="dropdown-item">
<b>Популярные категории</b>
</li>
<li>
<a class="dropdown-item py-2" href="/courses_devops">Курсы по DevOps
</a></li>
<li>
<a class="dropdown-item py-2" href="/courses_data_analytics">Курсы по аналитике данных
</a></li>
<li>
<a class="dropdown-item py-2" href="/courses_programming">Курсы по программированию
</a></li>
<li>
<a class="dropdown-item py-2" href="/courses_testing">Курсы по тестированию
</a></li>
<li>
<hr class="dropdown-divider">
</li>
<li class="dropdown-item">
<b>Популярные курсы</b>
</li>
<li>
<a class="dropdown-item py-2" href="/programs/devops-engineer-from-scratch">DevOps-инженер с нуля
</a></li>
<li>
<a class="dropdown-item py-2" href="/programs/go">Go-разработчик
</a></li>
<li>
<a class="dropdown-item py-2" href="/programs/java">Java-разработчик
</a></li>
<li>
<a class="dropdown-item py-2" href="/programs/python">Python-разработчик
</a></li>
<li>
<a class="dropdown-item py-2" href="/programs/qa-auto-engineer-java">Автоматизатор тестирования на Java
</a></li>
<li>
<a class="dropdown-item py-2" href="/programs/data-analytics">Аналитик данных
</a></li>
<li>
<a class="dropdown-item py-2" href="/programs/frontend">Фронтенд-разработчик
</a></li>
</ul>
</li>
<li class="nav-item dropdown">
<button aria-haspopup class="btn nav-link" data-bs-toggle="dropdown" type="button">
О Хекслете
<span class="bi bi-chevron-down align-middle"></span>
</button>
<ul class="dropdown-menu bg-body">
<li>
<a class="dropdown-item py-2" href="/pages/about">О нас
</a></li>
<li>
<a class="dropdown-item py-2" href="/blog">Блог
</a></li>
<li>
<span class="dropdown-item py-2 external-link" data-href="https://special.hexlet.io/hse-research" role="button">Результаты (Исследование)
</span></li>
<li>
<span class="dropdown-item py-2 external-link" data-href="https://career.hexlet.io" role="button">Хекслет Карьера
</span></li>
<li>
<a class="dropdown-item py-2" href="/testimonials">Отзывы студентов
</a></li>
<li>
<span class="dropdown-item py-2 external-link" data-href="https://t.me/hexlet_help_bot" role="button">Поддержка (В ТГ)
</span></li>
<li>
<span class="dropdown-item py-2 external-link" data-href="https://special.hexlet.io/referal-program/?promo_creative=priglasite-druzei&promo_name=referal-program&promo_position=promo_position&promo_start=010724&promo_type=link" role="button">Реферальная программа
</span></li>
<li>
<span class="dropdown-item py-2 external-link" data-href="https://special.hexlet.io/certificate" role="button">Подарочные сертификаты
</span></li>
<li>
<span class="dropdown-item py-2 external-link" data-href="https://hh.ru/employer/4307094" role="button">Вакансии
</span></li>
<li>
<span class="dropdown-item d-flex external-link" rel="noopener noreferrer nofollow" data-href="https://b2b.hexlet.io" data-target="_blank" role="button">Компаниям
</span></li>
<li>
<span class="dropdown-item d-flex external-link" rel="noopener noreferrer nofollow" data-href="https://hexly.ru/" data-target="_blank" role="button">Колледж
</span></li>
<li>
<span class="dropdown-item d-flex external-link" rel="noopener noreferrer nofollow" data-href="https://hexlyschool.ru/" data-target="_blank" role="button">Частная школа
</span></li>
</ul>
</li>
<li><a class="nav-link" href="/subscription/new">Подписка</a></li>
</ul>
<ul class="navbar-nav flex-lg-row align-items-lg-center gap-2 ms-auto">
<li>
<a class="nav-link" aria-label="Переключить тему" href="/theme/switch?new_theme=dark"><span aria-hidden="true" class="bi bi-moon"></span>
</a></li>
<li>
<span data-target="_self" class="nav-link external-link" data-href="/u/new" role="button"><span>Регистрация</span>
</span></li>
<li>
<span data-target="_self" class="nav-link external-link" data-href="https://ru.hexlet.io/session/new" role="button"><span>Вход</span>
</span></li>
</ul>
</div>
</div>
</nav>
</header>
<div class="x-container-xxxl">
</div>
<main class="mb-6 min-vh-100 h-100">
<link rel="preload" as="image" href="https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6Mzk5MiwicHVyIjoiYmxvYl9pZCJ9fQ==--e9d0f30948ea766a7e6bc3e3d56c192344d45fb8/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Programming-cuate%20(1).png"/><link rel="preload" as="image" href="/vite/assets/development-BVihs_d5.png"/><div id="app" data-page="{"component":"web/courses/lessons/theory_unit","props":{"errors":{},"locale":"ru","language":"ru","httpsHost":"https://ru.hexlet.io","host":"ru.hexlet.io","colorScheme":"light","auth":{"user":{"id":null,"last_viewed_notification_id":null,"email":null,"state":null,"first_name":"","last_name":"","created_at":"2026-02-26T20:27:04.553Z","current_program":null,"current_team":null,"full_name":"","guest":true,"can_use_paid_features":false,"is_hexlet_employee":false,"sanitized_phone_number":"","can_subscribe":true,"can_renew_education":false}},"cloudflareTurnstileSiteKey":"0x4AAAAAAA15KmeFXzd2H0Xo","vkIdClientId":"51586979","yandexIdClientId":"88d071f1d3384eb4bd1deb37910235c7","formAuthToken":"AUcHwS03_eRLh9q6pHMiUZBgbCabU1lDM1AQC90pgF7ulsz230lQhP3E_iKofNImUGlBjJNkp-GOsIpfjy5nMA","topics":[{"id":43503,"title":"Если запускать теорию в точности как написано, то slim выдает\n```\nSlim Application Error\nThe application could not run because of the following error:\n\nDetails\nType: TypeError\nCode: 0\nMessage: Return value of Slim\\Handlers\\Strategies\\RequestResponse::__invoke() must implement interface Psr\\Http\\Message\\ResponseInterface, int returned\nFile: /home/fazvil/hexlet-slim-example/vendor/slim/slim/Slim/Handlers/Strategies/RequestResponse.php\nLine: 43\nTrace\n#0 /home/fazvil/hexlet-slim-example/vendor/slim/slim/Slim/Routing/Route.php(381): Slim\\Handlers\\Strategies\\RequestResponse->__invoke()\n#1 /home/fazvil/hexlet-slim-example/vendor/slim/slim/Slim/MiddlewareDispatcher.php(81): Slim\\Routing\\Route->handle()\n#2 /home/fazvil/hexlet-slim-example/vendor/slim/slim/Slim/MiddlewareDispatcher.php(81): Slim\\MiddlewareDispatcher->handle()\n#3 /home/fazvil/hexlet-slim-example/vendor/slim/slim/Slim/Routing/Route.php(341): Slim\\MiddlewareDispatcher->handle()\n#4 /home/fazvil/hexlet-slim-example/vendor/slim/slim/Slim/Routing/RouteRunner.php(84): Slim\\Routing\\Route->run()\n#5 /home/fazvil/hexlet-slim-example/vendor/slim/slim/Slim/Middleware/ErrorMiddleware.php(107): Slim\\Routing\\RouteRunner->handle()\n#6 /home/fazvil/hexlet-slim-example/vendor/slim/slim/Slim/MiddlewareDispatcher.php(140): Slim\\Middleware\\ErrorMiddleware->process()\n#7 /home/fazvil/hexlet-slim-example/vendor/slim/slim/Slim/MiddlewareDispatcher.php(81): class@anonymous->handle()\n#8 /home/fazvil/hexlet-slim-example/vendor/slim/slim/Slim/App.php(215): Slim\\MiddlewareDispatcher->handle()\n#9 /home/fazvil/hexlet-slim-example/vendor/slim/slim/Slim/App.php(199): Slim\\App->handle()\n#10 /home/fazvil/hexlet-slim-example/public/index.php(16): Slim\\App->run()\n#11 {main}\n```\n\nа если поменять строчку \n```\nreturn $response->getBody()->write('Welcome to Slim!');\n```\nзаменить на\n```\nreturn $response->write('Welcome to Slim!');\n```\nкоторый так же указан в комментариях в уроке, то работает.\nОн же не пишет, что какого то компонента мне не хватает.\n","plain_title":"Если запускать теорию в точности как написано, то slim выдает ``` Slim Application Error The application could not run because of the following error: Details Type: TypeError Code: 0 Message: Return value of Slim\\Handlers\\Strategies\\RequestResponse::__invoke() must implement interface Psr\\Http\\Message\\ResponseInterface, int returned File: /home/fazvil/hexlet-slim-example/vendor/slim/slim/Slim/Handlers/Strategies/RequestResponse.php Line: 43 Trace 0 /home/fazvil/hexlet-slim-example/vendor/slim/slim/Slim/Routing/Route.php(381): Slim\\Handlers\\Strategies\\RequestResponse->__invoke() 1 /home/fazvil/hexlet-slim-example/vendor/slim/slim/Slim/MiddlewareDispatcher.php(81): Slim\\Routing\\Route->handle() 2 /home/fazvil/hexlet-slim-example/vendor/slim/slim/Slim/MiddlewareDispatcher.php(81): Slim\\MiddlewareDispatcher->handle() 3 /home/fazvil/hexlet-slim-example/vendor/slim/slim/Slim/Routing/Route.php(341): Slim\\MiddlewareDispatcher->handle() 4 /home/fazvil/hexlet-slim-example/vendor/slim/slim/Slim/Routing/RouteRunner.php(84): Slim\\Routing\\Route->run() 5 /home/fazvil/hexlet-slim-example/vendor/slim/slim/Slim/Middleware/ErrorMiddleware.php(107): Slim\\Routing\\RouteRunner->handle() 6 /home/fazvil/hexlet-slim-example/vendor/slim/slim/Slim/MiddlewareDispatcher.php(140): Slim\\Middleware\\ErrorMiddleware->process() 7 /home/fazvil/hexlet-slim-example/vendor/slim/slim/Slim/MiddlewareDispatcher.php(81): class@anonymous->handle() 8 /home/fazvil/hexlet-slim-example/vendor/slim/slim/Slim/App.php(215): Slim\\MiddlewareDispatcher->handle() 9 /home/fazvil/hexlet-slim-example/vendor/slim/slim/Slim/App.php(199): Slim\\App->handle() 10 /home/fazvil/hexlet-slim-example/public/index.php(16): Slim\\App->run() 11 {main} а если поменять строчку return $response->getBody()->write('Welcome to Slim!'); заменить на return $response->write('Welcome to Slim!'); ``` который так же указан в комментариях в уроке, то работает. Он же не пишет, что какого то компонента мне не хватает. ","creator":{"public_name":"Вильдан Фазлыев","id":252958,"is_tutor":false},"comments":[{"creator":{"public_name":"Вильдан Фазлыев","id":252958,"is_tutor":false},"id":94571,"body":"В упражнении кстати getBody() тоже не работает, убрали что ли.","topic_id":43503},{"creator":{"public_name":"Stanislav Dzisiak","id":212236,"is_tutor":true},"id":94622,"body":"Приветствую, Вильдан!\n\nНа самом деле getBody() работает. Но дело в том, что вызов метода $response->getBody()->writewrite() не возвращает объект ответа, а из обработчика именно его нужно вернуть. Поэтому вот рабочий вариант:\n\n $response->getBody()->write('Welcome to Slim!');\n return $response;\n\nЯ поправил пример в теории. Спасибо, что обратили внимание.","topic_id":43503}],"communitable":{"parent_entity_name":null,"parent_entity_url":null,"entity_name":"Микрофреймворк Slim","entity_url":null,"active":true}},{"id":31442,"title":"Пытаюсь настроить на домашнем компе. ```PHP Fatal error: Uncaught Error: Class 'Slim\\Factory\\AppFactory' not found in /vagrant/hexlet-slim-example/public/index.php:8``` - успешно запустил сервер, обновляю страницу и вот такое получаю в консоли. Зашел в директорию, папки Factory там вообще нет. сделал все по инструкции кроме самой установки Slim. Видимо в этом и проблема. Ругался на способ предложенный в уроке, нашел в интернете ```composer require slim/slim \"3.0\"```. Появилась папка Slim, там файлы разные и composer.json обновился.\nСовсем не знаю, что делать. На ум приходит только заново установить Slim, как тогда снести его целиком? Просто папку удалить? ","plain_title":"Пытаюсь настроить на домашнем компе. PHP Fatal error: Uncaught Error: Class 'Slim\\Factory\\AppFactory' not found in /vagrant/hexlet-slim-example/public/index.php:8 - успешно запустил сервер, обновляю страницу и вот такое получаю в консоли. Зашел в директорию, папки Factory там вообще нет. сделал все по инструкции кроме самой установки Slim. Видимо в этом и проблема. Ругался на способ предложенный в уроке, нашел в интернете composer require slim/slim \"3.0\". Появилась папка Slim, там файлы разные и composer.json обновился. Совсем не знаю, что делать. На ум приходит только заново установить Slim, как тогда снести его целиком? Просто папку удалить? ","creator":{"public_name":"Руслан Куга","id":206931,"is_tutor":false},"comments":[{"creator":{"public_name":"Руслан Куга","id":206931,"is_tutor":false},"id":68327,"body":"проблема была в кривой установке, кривая установка была потому что php был не той версиию","topic_id":31442}],"communitable":{"parent_entity_name":null,"parent_entity_url":null,"entity_name":"Микрофреймворк Slim","entity_url":null,"active":true}},{"id":49807,"title":"Всем привет!:) Несколько вопросиков:\n1. Корневая директория проекта и корень проекта это одно и то же понятие?\n2. Правильно ли утверждать что корень проекта это директория в которой находится composer.json?\n3. Как критично если public(в котором index) находится в корневой директории? \n","plain_title":"Всем привет!:) Несколько вопросиков: 1. Корневая директория проекта и корень проекта это одно и то же понятие? 2. Правильно ли утверждать что корень проекта это директория в которой находится composer.json? 3. Как критично если public(в котором index) находится в корневой директории? ","creator":{"public_name":"Артур Нутфуллин","id":285530,"is_tutor":false},"comments":[{"creator":{"public_name":"Nikolai Gagarinov","id":104929,"is_tutor":true},"id":106782,"body":"Привет, \n1. Да, примерно так и есть.\n2. На самом деле не обязательно.\n3. Зачем вообще стали делать директорию `public/`? Суть в том, что когда мы обращаешься к сайту `example.com`, мы можем получаем доступ к ресурсу. И этот ресурс может быть не только скриптом, на который перенаправляются запросы, но и статика - js, css, картинки. \nЧто будет, Если у нас все будет свалено в кучу? Например пользователь может вбить путь типа `example.com/storage/users/photos/foto_pasporta.jpg`, т.е. забьет путь к файлу в котором могут быть какие-то данные.\nИли просто получит доступ к исходникам. Т.е. если клиент имеет доступ к директории `public/`, то скорей всего о не будет иметь доступ к внутренностям нашего проекта. Ну это один из примеров. Кроме того, в это директории находится точка доступа (в `index.php`), куда ходят наши запросы по сети. Приложение может не только принимать http запросы, но и могут быть консольные утилиты, которые исползуют наше приложение (например мы написали скрипт, который должен работать раз в сутки, например удалять старые файлы).\nhttps://laravel.com/docs/8.x/structure#the-public-directory тут можно почитать про структуру, которая используется в Laravel\n","topic_id":49807}],"communitable":{"parent_entity_name":null,"parent_entity_url":null,"entity_name":"Микрофреймворк Slim","entity_url":null,"active":true}},{"id":32396,"title":"Здравсвтуйте, не могу понять, что упустил в теории и в следствии этого возможно не так понимаю суть задания? Для решения использую собственно тот же код который приведет в теории, вывод получается таким: user-ab43150a2e97e2b6 Лишняя строка пустая при выводе берется откуда-то.","plain_title":"Здравсвтуйте, не могу понять, что упустил в теории и в следствии этого возможно не так понимаю суть задания? Для решения использую собственно тот же код который приведет в теории, вывод получается таким: user-ab43150a2e97e2b6 Лишняя строка пустая при выводе берется откуда-то. ","creator":{"public_name":"Константин Наумович","id":115201,"is_tutor":false},"comments":[{"creator":{"public_name":"Константин Наумович","id":115201,"is_tutor":false},"id":70550,"body":"Я изначально вместо ссылки в вопросе не то вставил, вот ссылка на код ревью: https://ru.hexlet.io/code_reviews/152580","topic_id":32396},{"creator":{"public_name":"Kirill Mokevnin","id":1,"is_tutor":false},"id":70393,"body":"А можно показать код ревью?","topic_id":32396},{"creator":{"public_name":"Константин Наумович","id":115201,"is_tutor":false},"id":70646,"body":":) Выдать Кириллу миллион долларов мелкими купюрами! Спасибо Кирилл в очередной раз.","topic_id":32396},{"creator":{"public_name":"Kirill Mokevnin","id":1,"is_tutor":false},"id":70568,"body":"Вопрос на миллион долларов. Откуда у вас в коде появился `?>` ?) В стандарте кодирования PSR, закрывающий тег должен отсутствовать. И сделано это именно из-за того эффекта, который вы наблюдаете. В вывод попадают левые переводы строк.","topic_id":32396}],"communitable":{"parent_entity_name":null,"parent_entity_url":null,"entity_name":"Микрофреймворк Slim","entity_url":null,"active":true}},{"id":31700,"title":"Запускаю установку slim как написано в лекции, вот такой результат.\n\n```\n composer require slim/slim slim/psr7 slim/http\nDo not run Composer as root/super user! See https://getcomposer.org/root for details\nUsing version ^4.2 for slim/slim\nUsing version ^0.5.0 for slim/psr7\nUsing version ^0.8.0 for slim/http\n./composer.json has been created\nLoading composer repositories with package information\nUpdating dependencies (including require-dev)\nYour requirements could not be resolved to an installable set of packages.\n\n Problem 1\n - Installation request for slim/http ^0.8.0 -> satisfiable by slim/http[0.8].\n - slim/http 0.8 requires ext-simplexml * -> the requested PHP extension simplexml is missing from your system.\n\n To enable extensions, verify that they are enabled in your .ini files:\n - /etc/php/7.2/cli/php.ini\n - /etc/php/7.2/cli/conf.d/10-opcache.ini\n - /etc/php/7.2/cli/conf.d/10-pdo.ini\n - /etc/php/7.2/cli/conf.d/20-calendar.ini\n - /etc/php/7.2/cli/conf.d/20-ctype.ini\n - /etc/php/7.2/cli/conf.d/20-exif.ini\n - /etc/php/7.2/cli/conf.d/20-fileinfo.ini\n - /etc/php/7.2/cli/conf.d/20-ftp.ini\n - /etc/php/7.2/cli/conf.d/20-gettext.ini\n - /etc/php/7.2/cli/conf.d/20-iconv.ini\n - /etc/php/7.2/cli/conf.d/20-json.ini\n - /etc/php/7.2/cli/conf.d/20-phar.ini\n - /etc/php/7.2/cli/conf.d/20-posix.ini\n - /etc/php/7.2/cli/conf.d/20-readline.ini\n - /etc/php/7.2/cli/conf.d/20-shmop.ini\n - /etc/php/7.2/cli/conf.d/20-sockets.ini\n - /etc/php/7.2/cli/conf.d/20-sysvmsg.ini\n - /etc/php/7.2/cli/conf.d/20-sysvsem.ini\n - /etc/php/7.2/cli/conf.d/20-sysvshm.ini\n - /etc/php/7.2/cli/conf.d/20-tokenizer.ini\n You can also run `php --ini` inside terminal to see which files are used by PHP in CLI mode.\n\nInstallation failed, deleting ./composer.json.\n```\n\nЧто посоветуете? До этого создал репозиторий внутри hexlet-slim-example и добавил его на GitHub. Создал файл .gitignore и поместил туда директорию vendor.","plain_title":"Запускаю установку slim как написано в лекции, вот такой результат. composer require slim/slim slim/psr7 slim/http Do not run Composer as root/super user! See https://getcomposer.org/root for details Using version ^4.2 for slim/slim Using version ^0.5.0 for slim/psr7 Using version ^0.8.0 for slim/http ./composer.json has been created Loading composer repositories with package information Updating dependencies (including require-dev) Your requirements could not be resolved to an installable set of packages. Problem 1 - Installation request for slim/http ^0.8.0 -> satisfiable by slim/http[0.8]. - slim/http 0.8 requires ext-simplexml * -> the requested PHP extension simplexml is missing from your system. To enable extensions, verify that they are enabled in your .ini files: - /etc/php/7.2/cli/php.ini - /etc/php/7.2/cli/conf.d/10-opcache.ini - /etc/php/7.2/cli/conf.d/10-pdo.ini - /etc/php/7.2/cli/conf.d/20-calendar.ini - /etc/php/7.2/cli/conf.d/20-ctype.ini - /etc/php/7.2/cli/conf.d/20-exif.ini - /etc/php/7.2/cli/conf.d/20-fileinfo.ini - /etc/php/7.2/cli/conf.d/20-ftp.ini - /etc/php/7.2/cli/conf.d/20-gettext.ini - /etc/php/7.2/cli/conf.d/20-iconv.ini - /etc/php/7.2/cli/conf.d/20-json.ini - /etc/php/7.2/cli/conf.d/20-phar.ini - /etc/php/7.2/cli/conf.d/20-posix.ini - /etc/php/7.2/cli/conf.d/20-readline.ini - /etc/php/7.2/cli/conf.d/20-shmop.ini - /etc/php/7.2/cli/conf.d/20-sockets.ini - /etc/php/7.2/cli/conf.d/20-sysvmsg.ini - /etc/php/7.2/cli/conf.d/20-sysvsem.ini - /etc/php/7.2/cli/conf.d/20-sysvshm.ini - /etc/php/7.2/cli/conf.d/20-tokenizer.ini You can also run `php --ini` inside terminal to see which files are used by PHP in CLI mode. Installation failed, deleting ./composer.json. ","creator":{"public_name":"Денис Потехин","id":239601,"is_tutor":false},"comments":[{"creator":{"public_name":"Kirill Mokevnin","id":1,"is_tutor":false},"id":69042,"body":"> Так я ставил php, так как здесь в курсах по PHP ранее писали)\n\nЭто программирование. Тут не работает простое следование инструкциям. Настройка зависит от операционной системы, ее конфигурации, версии php. В таких условиях невозможно написать один универсальный гайд по тому как все установить так чтобы оно работало. Именно поэтому в сети десятки и наверное сотни тысячи инструкций по тому как ставить PHP.\n\nВ таких условиях важнее способность анализировать то что пишет система, дальше гуглить и экспериментировать. Так и происходит в реальной жизни.\n\n> Failed to download ralouphie/getallheaders from dist: The zip extension and unzip command are both missing, skipping.\n\nВот здесь написано что у вас нет zip расширения. Его нужно поставить (примерно так же как и xml). Затем пробуйте снова, анализируйте ошибки, если они будут и так до тех пор пока не получится.\n\np.s. Настройка инфраструктуры, это важная и не самая простая часть процесса подготовки окружения для разработки. Ее не получится проскочить на раз два, программисты тратят кучу времени на то чтобы заставить все работать. Именно поэтому во всех наших вебинарах и статьях мы делаем такой большой упор на изучение операционных систем.","topic_id":31700},{"creator":{"public_name":"Денис Потехин","id":239601,"is_tutor":false},"id":68915,"body":"Переустановил make, после этого тоже самое, что у и отписавшегося внизу темы:\n\nmake start пишет:\n\nmake: Nothing to be done for 'start'\nphp -S localhost:8000 -t public public/index.php Успешно выполняется из консоли\n\nПри этом проверил файл Makefile там точно у меня один Tab, а не пробелы..\n**Денис Потехин**, ","topic_id":31700},{"creator":{"public_name":"Kirill Mokevnin","id":1,"is_tutor":false},"id":68890,"body":"> - slim/http 0.8 requires ext-simplexml * -> the requested PHP extension simplexml is missing from your system\n\nТут не в слим дело, а в том что php должен быть установлен с расширением `ext-simplexml`. Как его ставить – зависит от операционной системы. Надо гуглить примерно так: _ubuntu php install ext-simplexml_","topic_id":31700},{"creator":{"public_name":"Денис Потехин","id":239601,"is_tutor":false},"id":68912,"body":"Поставил sudo apt-get install php-xml\nПосле этого ставится но странно)\n\n```\nroot@DESKTOP-HQ23OBJ:~/hexlet-slim-example# composer require slim/slim slim/psr7 slim/http\nDo not run Composer as root/super user! See https://getcomposer.org/root for details\nUsing version ^4.2 for slim/slim\nUsing version ^0.5.0 for slim/psr7\nUsing version ^0.8.0 for slim/http\n./composer.json has been created\nLoading composer repositories with package information\nUpdating dependencies (including require-dev)\nPackage operations: 11 installs, 0 updates, 0 removals\n Failed to download psr/http-message from dist: The zip extension and unzip command are both missing, skipping.\nYour command-line PHP is using multiple ini files. Run `php --ini` to show them.\n Now trying to download from source\n - Installing psr/http-message (1.0.1): Cloning f6561bf28d from cache\n Failed to download psr/http-server-handler from dist: The zip extension and unzip command are both missing, skipping.\nYour command-line PHP is using multiple ini files. Run `php --ini` to show them.\n Now trying to download from source\n - Installing psr/http-server-handler (1.0.1): Cloning aff2f80e33 from cache\n Failed to download psr/http-server-middleware from dist: The zip extension and unzip command are both missing, skipping.\nYour command-line PHP is using multiple ini files. Run `php --ini` to show them.\n Now trying to download from source\n - Installing psr/http-server-middleware (1.0.1): Cloning 2296f45510 from cache\n Failed to download psr/http-factory from dist: The zip extension and unzip command are both missing, skipping.\nYour command-line PHP is using multiple ini files. Run `php --ini` to show them.\n Now trying to download from source\n - Installing psr/http-factory (1.0.1): Cloning 12ac7fcd07 from cache\n Failed to download psr/container from dist: The zip extension and unzip command are both missing, skipping.\nYour command-line PHP is using multiple ini files. Run `php --ini` to show them.\n Now trying to download from source\n - Installing psr/container (1.0.0): Cloning b7ce3b1764 from cache\n Failed to download nikic/fast-route from dist: The zip extension and unzip command are both missing, skipping.\nYour command-line PHP is using multiple ini files. Run `php --ini` to show them.\n Now trying to download from source\n - Installing nikic/fast-route (v1.3.0): Cloning 181d480e08 from cache\n Failed to download slim/slim from dist: The zip extension and unzip command are both missing, skipping.\nYour command-line PHP is using multiple ini files. Run `php --ini` to show them.\n Now trying to download from source\n - Installing slim/slim (4.2.0): Cloning 378abc6f8f from cache\n Failed to download ralouphie/getallheaders from dist: The zip extension and unzip command are both missing, skipping.\nYour command-line PHP is using multiple ini files. Run `php --ini` to show them.\n Now trying to download from source\n - Installing ralouphie/getallheaders (3.0.3): Cloning 120b605dfe from cache\n Failed to download fig/http-message-util from dist: The zip extension and unzip command are both missing, skipping.\nYour command-line PHP is using multiple ini files. Run `php --ini` to show them.\n Now trying to download from source\n - Installing fig/http-message-util (1.1.3): Cloning 35b1940437 from cache\n Failed to download slim/psr7 from dist: The zip extension and unzip command are both missing, skipping.\nYour command-line PHP is using multiple ini files. Run `php --ini` to show them.\n Now trying to download from source\n - Installing slim/psr7 (0.5.0): Cloning 99ad31f503 from cache\n Failed to download slim/http from dist: The zip extension and unzip command are both missing, skipping.\nYour command-line PHP is using multiple ini files. Run `php --ini` to show them.\n Now trying to download from source\n - Installing slim/http (0.8): Cloning a614882c34 from cache\nWriting lock file\nGenerating autoload files\n```\n\nПодозреваю, что эта кривая установка)\nТак и есть?\n\n\n**Kirill Mokevnin**, ","topic_id":31700},{"creator":{"public_name":"Денис Потехин","id":239601,"is_tutor":false},"id":68911,"body":"Так я ставил php, так как здесь в курсах по PHP ранее писали) \nСпасибо за направление поиска! Еще такой вопрос, нужно снести уже установленную версию или установка новой решает все проблемы?\n**Kirill Mokevnin**, ","topic_id":31700}],"communitable":{"parent_entity_name":null,"parent_entity_url":null,"entity_name":"Микрофреймворк Slim","entity_url":null,"active":true}},{"id":41364,"title":"Всем привет!\nПодскажите, плз - кто сталкивался с тем, что команда\n```\ncomposer require slim/slim slim/psr7 slim/http\n```\nотвечает\n```\nPackage slim/psr7 at version has a PHP requirement incompatible with your PHP version (7.0.33)\n```\nНе понимаю. php у меня стоит версии 7.2 (php -v):\n```\nPHP 7.2.29-1+ubuntu18.04.1+deb.sury.org+1 (cli) (built: Mar 20 2020 13:54:39) ( NTS )\nCopyright (c) 1997-2018 The PHP Group\nZend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies\n with Zend OPcache v7.2.29-1+ubuntu18.04.1+deb.sury.org+1, Copyright (c) 1999-2018, by Zend Technologies\n```\nДелал полное удаление через \"sudo apt-get purge php7.*\" и установку снова версии 7.2 и версии 7.0.33 - результат один :с","plain_title":"Всем привет! Подскажите, плз - кто сталкивался с тем, что команда composer require slim/slim slim/psr7 slim/http отвечает Package slim/psr7 at version has a PHP requirement incompatible with your PHP version (7.0.33) Не понимаю. php у меня стоит версии 7.2 (php -v): PHP 7.2.29-1+ubuntu18.04.1+deb.sury.org+1 (cli) (built: Mar 20 2020 13:54:39) ( NTS ) Copyright (c) 1997-2018 The PHP Group Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies with Zend OPcache v7.2.29-1+ubuntu18.04.1+deb.sury.org+1, Copyright (c) 1999-2018, by Zend Technologies Делал полное удаление через \"sudo apt-get purge php7.*\" и установку снова версии 7.2 и версии 7.0.33 - результат один :с ","creator":{"public_name":"Андрей Барсуков","id":251327,"is_tutor":false},"comments":[{"creator":{"public_name":"Андрей Барсуков","id":251327,"is_tutor":false},"id":90138,"body":"Отвечаю на свой же вопрос. \nДело было в версии самого composer. Я установил последнюю версию в проект и теперь всё ок.\nИ да, также понадобилась установка php7.2-simplexml","topic_id":41364},{"creator":{"public_name":"Stanislav Dzisiak","id":212236,"is_tutor":true},"id":90298,"body":"Приветствую, Андрей!\n\nОтлично, что у вас получилось разобраться!","topic_id":41364}],"communitable":{"parent_entity_name":null,"parent_entity_url":null,"entity_name":"Микрофреймворк Slim","entity_url":null,"active":true}},{"id":17487,"title":"Можно сделать проверку на запуск Слима? Потому что можно просто без него респонс вернуть и упражнение зачтется.","plain_title":"Можно сделать проверку на запуск Слима? Потому что можно просто без него респонс вернуть и упражнение зачтется. ","creator":{"public_name":"Максим Торбург","id":64077,"is_tutor":false},"comments":[{"creator":{"public_name":"Kirill Mokevnin","id":1,"is_tutor":false},"id":36971,"body":"Ну это надо прямо специально забивать на задание чтобы так получилось)","topic_id":17487}],"communitable":{"parent_entity_name":null,"parent_entity_url":null,"entity_name":"Микрофреймворк Slim","entity_url":null,"active":true}},{"id":19253,"title":"make start пишет:\n\n make: Nothing to be done for 'start'\n\nphp -S localhost:8000 -t public public/index.php Успешно выполняется из консоли\n\n","plain_title":"make start пишет: make: Nothing to be done for 'start' php -S localhost:8000 -t public public/index.php Успешно выполняется из консоли ","creator":{"public_name":"Александр Кудряшов","id":167203,"is_tutor":false},"comments":[{"creator":{"public_name":"Александр О.","id":61806,"is_tutor":false},"id":40700,"body":"> make start пишет:\n\nСкорее всего вы неправильно сформатировали файл Makefile, там должен быть отступ в один таб, а не через пробелы","topic_id":19253},{"creator":{"public_name":"Evgen Guba","id":232968,"is_tutor":false},"id":67304,"body":"Обратите внимание, что если работаете через PHPStorm, то он по умолчанию заменяет Tab на 4-ре пробела","topic_id":19253},{"creator":{"public_name":"Ruslan G","id":198436,"is_tutor":false},"id":69649,"body":"Аналогично в Visual Studio, вместо табуляции 4 пробела. \nДля устранения в настройках:\n\n```\n\"editor.detectIndentation\": false.\n```\n\nhttps://stackoverflow.com/questions/29972396/how-to-customize-the-tab-to-space-conversion-factor","topic_id":19253}],"communitable":{"parent_entity_name":null,"parent_entity_url":null,"entity_name":"Микрофреймворк Slim","entity_url":null,"active":true}},{"id":30836,"title":"Я так понял, так задумано, что бы задание не работало копипастом из теории, и заставляло заниматься танцами с бубном?))","plain_title":"Я так понял, так задумано, что бы задание не работало копипастом из теории, и заставляло заниматься танцами с бубном?)) ","creator":{"public_name":"Kirill Kikimov","id":79345,"is_tutor":false},"comments":[{"creator":{"public_name":"Kirill Mokevnin","id":1,"is_tutor":false},"id":66889,"body":"> а по факту походу v3.\n\nЭто зависит от того как устанавливался слим. Если устанавливать его с нуля как показано в теории, то должен поставиться v4.","topic_id":30836},{"creator":{"public_name":"Kirill Kikimov","id":79345,"is_tutor":false},"id":66890,"body":"таак. мы же говорим про практику в среде хекслета. Там composer install не работает же, у пользователя прав нет на vendor да и на все остальное что с компаузиром связанно.\nТак что, тут наши полномочия всё....","topic_id":30836},{"creator":{"public_name":"Kirill Mokevnin","id":1,"is_tutor":false},"id":66895,"body":"Видимо не успело собраться. Вот щас собралось)","topic_id":30836},{"creator":{"public_name":"Kirill Kikimov","id":79345,"is_tutor":false},"id":66892,"body":"**Kirill Mokevnin**, ну я же не совсем поехавший xD\nps дальше к стати то же все на V3","topic_id":30836},{"creator":{"public_name":"Kirill Mokevnin","id":1,"is_tutor":false},"id":66887,"body":"Slim на днях выпустил новую версию фреймворка и я по ходу дела вношу правки. Что там не сработало?","topic_id":30836},{"creator":{"public_name":"Kirill Mokevnin","id":1,"is_tutor":false},"id":66893,"body":"Попробуй сбросить прогресс","topic_id":30836},{"creator":{"public_name":"Kirill Kikimov","id":79345,"is_tutor":false},"id":66896,"body":"Работает.\nКак заботливо было разместить use в заготовке =)","topic_id":30836},{"creator":{"public_name":"Kirill Kikimov","id":79345,"is_tutor":false},"id":66888,"body":" теория под v4 а по факту походу v3.","topic_id":30836},{"creator":{"public_name":"Kirill Mokevnin","id":1,"is_tutor":false},"id":66891,"body":"аа, я думал речь про локальный сетап. Тогда щас поправлю.","topic_id":30836},{"creator":{"public_name":"Kirill Kikimov","id":79345,"is_tutor":false},"id":66894,"body":"**Kirill Mokevnin**, Fatal error: Uncaught Error: Class 'Slim\\Factory\\AppFactory' not found in /usr/src/app/public/index.php on line 10","topic_id":30836}],"communitable":{"parent_entity_name":null,"parent_entity_url":null,"entity_name":"Микрофреймворк Slim","entity_url":null,"active":true}},{"id":25868,"title":"У меня почему-то после команды make start пишет: \"bash: make: command not found\". Погуглил, и если верно понял, то на винде для этой команды частенько требуется устанавливать дополнительный софт.","plain_title":"У меня почему-то после команды make start пишет: \"bash: make: command not found\". Погуглил, и если верно понял, то на винде для этой команды частенько требуется устанавливать дополнительный софт. ","creator":{"public_name":"","id":115467,"is_tutor":false},"comments":[{"creator":{"public_name":"Kirill Mokevnin","id":1,"is_tutor":false},"id":55400,"body":"Конечно, мы с самого начала говорим что нужно работать на ubuntu, либо настраивать windows по нашим гайдам: https://guides.hexlet.io/development-on-windows/","topic_id":25868}],"communitable":{"parent_entity_name":null,"parent_entity_url":null,"entity_name":"Микрофреймворк Slim","entity_url":null,"active":true}}],"lesson":{"exercise":{"id":755,"slug":"php_mvc_slim_exercise","name":null,"state":"active","kind":"exercise","language":"php","locale":"ru","has_web_view":true,"has_test_view":false,"reviewable":true,"readme":"## public/index.php\n\nРеализуйте Slim приложение, в котором по адресу */* отдается строчка **Welcome to Hexlet!**\n","prepared_readme":"## public/index.php\n\nРеализуйте Slim приложение, в котором по адресу */* отдается строчка **Welcome to Hexlet!**\n","has_solution":true,"entity_name":"Микрофреймворк Slim"},"units":[{"id":2426,"name":"theory","url":"/courses/php-mvc/lessons/slim/theory_unit"},{"id":2617,"name":"quiz","url":"/courses/php-mvc/lessons/slim/quiz_unit"},{"id":2448,"name":"exercise","url":"/courses/php-mvc/lessons/slim/exercise_unit"}],"links":[{"id":428355,"name":"Утилита Make","url":"https://www.youtube.com/watch?v=pK9mF5aK05Q"},{"id":428356,"name":"Микрофреймворк Slim","url":"https://www.slimframework.com/"}],"ordered_units":[{"id":2426,"name":"theory","url":"/courses/php-mvc/lessons/slim/theory_unit"},{"id":2617,"name":"quiz","url":"/courses/php-mvc/lessons/slim/quiz_unit"},{"id":2448,"name":"exercise","url":"/courses/php-mvc/lessons/slim/exercise_unit"}],"id":1162,"slug":"slim","state":"approved","name":"Микрофреймворк Slim","course_order":100,"goal":"Знакомимся с созданием сайтов на фреймворках","self_study":"Выполните все шаги из этого урока на своем компьютере. Придумайте проекту имя. Запушьте его на GitHub. Проект нам понадобится в дальнейших уроках.\n","theory_video_provider":null,"theory_video_uid":null,"theory":"Цикл запрос-обработка-ответ включает множество элементов, которые идентичны для всех сайтов. Поэтому возникли фреймворки — специализированные библиотеки, которые определяют структуру программы. В этом их отличие от обычных библиотек.\n\nБлагодаря фреймворкам можно сосредоточиться на логике сайта, а не на продумывании базовой архитектуры или кодировании вспомогательных инструментов.\n\nВеб-фреймворки подразделяются на две большие группы: фреймворки и микрофреймворки.\n\nМикрофреймворки устроены проще и содержат только минимально необходимую обвязку для комфортной работы в архитектуре HTTP — запрос-ответ. Они подходят для обучения, потому что просты в эксплуатации и не отвлекают от главного.\n\n## Slim\n\nСоздадим подходящую структуру директорий в своей домашней директории:\n\n```\n.\n├── hexlet-slim-example\n│ └── public\n```\n\nДалее создадим репозиторий внутри *hexlet-slim-example* и добавим его на [GitHub](https://github.com). Не забудьте создать файл *.gitignore* и поместить туда директорию *vendor*. *hexlet-slim-example* теперь называется корневой директорией проекта (root directory).\n\nЗатем идем в корневую директорию проекта и устанавливаем Slim и его зависимости:\n\n```bash\ncomposer require slim/slim slim/psr7 slim/http slim/php-view php-di/php-di\n```\n\nДобавляем файл *hexlet-slim-example/public/index.php* со следующим содержимым:\n\n```php\n<?php\n\n// Подключение автозагрузки через composer\nrequire __DIR__ . '/../vendor/autoload.php';\n\nuse Slim\\Factory\\AppFactory;\n\n$app = AppFactory::create();\n$app->addErrorMiddleware(true, true, true);\n\n$app->get('/', function ($request, $response) {\n $response->getBody()->write('Welcome to Slim!');\n return $response;\n // Благодаря пакету slim/http этот же код можно записать короче\n // return $response->write('Welcome to Slim!');\n});\n$app->run();\n```\n\nСоздадим файл *Makefile* в корне проекта и добавим туда задачу `start`:\n\n```make\nstart:\n\tphp -S localhost:8080 -t public public/index.php\n```\n\nТеперь выполним запуск:\n\n```bash\nmake start\n```\n\nВывод должен быть примерно таким:\n\n```bash\n[Wed May 27 17:05:25 2020] PHP 7.4.3 Development Server (http://localhost:8080) started\n```\n\nЭта команда содержит новую для нас опцию `-t`. С ее помощью меняется корневая директория — место, где происходит поиск файла *index.php*. Подобную директорию принято называть *public* и помещать в нее только то, что можно открыть напрямую из браузера. Остальное не должно лежать в этой директории, иначе нас могут взломать.\n\nВ конце открываем в браузере `localhost:8080`. Если все хорошо, то на экране появится надпись *Welcome to Slim!*:\n\n\n"},"lessonMember":null,"courseMember":null,"course":{"start_lesson":{"exercise":null,"units":[{"id":2433,"name":"theory","url":"/courses/php-mvc/lessons/about/theory_unit"}],"links":[{"id":428346,"name":"Что такое протокол HTTPS, и как он защищает вас в интернете","url":"https://guides.hexlet.io/ru/https-yandex-guide/"},{"id":428347,"name":"Как работает DNS","url":"https://guides.hexlet.io/ru/dns/"}],"ordered_units":[{"id":2433,"name":"theory","url":"/courses/php-mvc/lessons/about/theory_unit"}],"id":1169,"slug":"about","state":"approved","name":"Введение","course_order":1,"goal":"Узнаем о курсе, его структуре, задачах и целях","self_study":null,"theory_video_provider":null,"theory_video_uid":null,"theory":"Чтобы перейти от написания скриптов к созданию полноценных сайтов, нужно изучить много новых понятий и инструментов, которые не относятся к языку программирования. Например, нужно знать, как работают операционные системы, как работать с сетями, регистраторами, хостингом и деплоем сайта.\n\nНа собеседованиях веб-программистам часто задают вопрос «Что происходит после того, как в адресной строке браузера набирается сайт www.google.com и нажимается Enter?». Обычно на этот вопрос хотят услышать ключевые понятия, связанные с веб-разработкой:\n\n* Выполнение DNS-запроса для получения IP-адреса домена\n* Соединение с веб-сервером, находящемся по этому адресу на порту 443 (или 80) по TCP\n* Выполнение HTTP-запроса для получения содержимого сайта по указанному домену\n* Получение ответа и рендеринг содержимого во вкладке браузера.\n\nКаждый из этих пунктов подразумевает знание следующих тем:\n\n* Протокол HTTP. Понятие виртуальных хостов. Желательно понимание принципов работы HTTPS\n* Принципы работы DNS\n* Знание TCP/IP. Понятия: порт, маска, подсети. Модель OSI. Сетевые сокеты\n* Веб-сервер. Что это такое, как работает и зачем нужен\n\nПодробный ответ на этот вопрос доступен [здесь](https://github.com/alex/what-happens-when).\n\nТакже на Хекслете есть ответы на некоторые из перечисленных пунктов, но большую часть материала придется взять из сторонних источников. Большинство ответов на указанные темы можно получить в книгах по операционным системам. В наших [рекомендованных книгах](https://ru.hexlet.io/pages/recommended-books) есть все необходимое.\n\nЗнание HTTP можно взять из соответствующего курса. Общее понимание DNS, хостинга, деплоя — из курса [Введение в веб-разработку](https://ru.hexlet.io/courses/intro_to_web_development). Остальное есть в дополнительных ссылках.\n\nТакже рекомендуем посмотреть [публичное собеседование](https://www.youtube.com/watch?v=JERUf-xKU1o&index=6&list=PLo6puixMwuSOa_0EH6X4OXzFAmyQGS3a3), где поднимались эти вопросы.\n\nВ процессе разработки сайта нужно изучать фреймворки, микрофреймворки, роутинг, куки, сессии, безопасность, шаблонизацию и взаимодействие с базой данных. И даже после того, как вы научитесь создавать сайты, обучение нужно продолжать.\n\nЧтобы сайт был доступен пользователям, его нужно развернуть на удаленном сервере. Этот процесс называется «деплой» — процесс разворачивания сайта на хостинге. При этом существует разный тип хостинга: IaaS (AWS), PaaS (Render), Shared Hosting (виртуальный хостинг), VPS/VDS. Также перед этим нужно настроить удаленную машину с помощью инструмента, например, Ansible, что тоже стоит изучить.\n\nДанный курс посвящен разработке сайтов с использованием микрофреймворков. Темы, указанные выше, также включены в курс, но разбираются поверхностно. Поэтому рекомендуем выполнять задачи не только в среде Хекслета, но и локально, параллельно выкатывая код на сервис, подобный [Render](https://www.render.com/).\n"},"id":165,"slug":"php-mvc","challenges_count":3,"name":"Веб-разработка на PHP","allow_indexing":true,"state":"approved","course_state":"finished","pricing_type":"paid","description":"На этом курсе вы познакомитесь с веб-разработкой на PHP. Вы узнаете о MVC, шаблонизации, роутинге и отправке форм. В итоге поймете, как создаются элементы типичных сайтов, например, аутентификация или полный набор операций по работе с сущностью (CRUD). Знания из этого курса пригодятся, если вы решите написать свой сайт на микрофреймворке Slim.","kind":"basic","updated_at":"2026-02-20T10:25:58.282Z","language":"php","duration_cache":95100,"skills":["Создавать с помощью PHP полноценные сайты","Пользоваться встроенным в PHP веб-сервером","Работать с микрофреймворком Slim","Правильно строить архитектуру веб-приложений. Разбираться в MVC"],"keywords":["CGI","slim framework","шаблонизация","отправка форм","MVC","сессии","роутинг"],"lessons_count":28,"cover":"https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MTUyODgsInB1ciI6ImJsb2JfaWQifX0=--ba054c4897951eb2e6cea29301c46f15adb3aeb2/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJwbmciLCJyZXNpemVfdG9fZmlsbCI6WzYwMCw0MDBdfSwicHVyIjoidmFyaWF0aW9uIn19--6067466c2912ca31a17eddee04b8cf2a38c6ad17/image.png"},"recommendedLandings":[{"stack":{"id":2,"slug":"php","title":"PHP-разработчик","audience":"for_beginners","start_type":"weekly","pricing_model":"purchase","priority":"high","kind":"profession","state":"published","stack_state":"finished","order":60,"duration_in_months":10},"id":1,"slug":"php","title":"РНР-разработчик","subtitle":"Изучите PHP и Laravel для разработки и проектирования REST API","subtitle_for_lists":"Изучите PHP и Laravel для разработки и проектирования REST API","locale":"ru","current":true,"duration_in_months_text":"10 месяцев","stack_slug":"php","price_text":"от 5 650 ₽","duration_text":"10 месяцев","cover_list_variant":"https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6Mzk5MiwicHVyIjoiYmxvYl9pZCJ9fQ==--e9d0f30948ea766a7e6bc3e3d56c192344d45fb8/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Programming-cuate%20(1).png"}],"lessonMemberUnit":null,"accessToLearnUnitExists":false,"accessToCourseExists":false},"url":"/courses/php-mvc/lessons/slim/theory_unit","version":"8f286f6358a90a7bef2263b3a6edf5a90a94fa42","encryptHistory":false,"clearHistory":false}"><style data-mantine-styles="true">:root, :host{--mantine-font-family: Arial, sans-serif;--mantine-font-family-headings: Arial, sans-serif;--mantine-heading-font-weight: normal;--mantine-radius-default: 0rem;--mantine-primary-color-filled: var(--mantine-color-indigo-filled);--mantine-primary-color-filled-hover: var(--mantine-color-indigo-filled-hover);--mantine-primary-color-light: var(--mantine-color-indigo-light);--mantine-primary-color-light-hover: var(--mantine-color-indigo-light-hover);--mantine-primary-color-light-color: var(--mantine-color-indigo-light-color);--mantine-spacing-xxl: calc(4rem * var(--mantine-scale));--mantine-font-size-xs: 12px;--mantine-font-size-sm: 14px;--mantine-font-size-md: 16px;--mantine-font-size-lg: clamp(16.0000px, calc(15.2727px + 0.2273vw), 18.0000px);--mantine-font-size-xl: clamp(16.0000px, calc(14.5455px + 0.4545vw), 20.0000px);--mantine-font-size-display-3: clamp(32.0000px, calc(26.1818px + 1.8182vw), 48.0000px);--mantine-font-size-display-2: clamp(36.0000px, calc(25.8182px + 3.1818vw), 64.0000px);--mantine-font-size-display-1: clamp(40.0000px, calc(25.4545px + 4.5455vw), 80.0000px);--mantine-font-size-h1: clamp(28.0000px, calc(23.6364px + 1.3636vw), 40.0000px);--mantine-font-size-h2: clamp(24.0000px, calc(21.0909px + 0.9091vw), 32.0000px);--mantine-font-size-h3: clamp(20.0000px, calc(17.0909px + 0.9091vw), 28.0000px);--mantine-font-size-h4: clamp(16.0000px, calc(13.0909px + 0.9091vw), 24.0000px);--mantine-font-size-h5: clamp(16.0000px, calc(14.5455px + 0.4545vw), 20.0000px);--mantine-font-size-h6: 1rem;--mantine-primary-color-0: var(--mantine-color-indigo-0);--mantine-primary-color-1: var(--mantine-color-indigo-1);--mantine-primary-color-2: var(--mantine-color-indigo-2);--mantine-primary-color-3: var(--mantine-color-indigo-3);--mantine-primary-color-4: var(--mantine-color-indigo-4);--mantine-primary-color-5: var(--mantine-color-indigo-5);--mantine-primary-color-6: var(--mantine-color-indigo-6);--mantine-primary-color-7: var(--mantine-color-indigo-7);--mantine-primary-color-8: var(--mantine-color-indigo-8);--mantine-primary-color-9: var(--mantine-color-indigo-9);--mantine-color-red-0: #ffeaea;--mantine-color-red-1: #fed4d4;--mantine-color-red-2: #f4a7a8;--mantine-color-red-3: #ec7878;--mantine-color-red-4: #e55050;--mantine-color-red-5: #e03131;--mantine-color-red-6: #e02829;--mantine-color-red-7: #c71a1c;--mantine-color-red-8: #b21218;--mantine-color-red-9: #9c0411;--mantine-color-violet-0: #fce9ff;--mantine-color-violet-1: #f1cfff;--mantine-color-violet-2: #e09bff;--mantine-color-violet-3: #d16fff;--mantine-color-violet-4: #be37fe;--mantine-color-violet-5: #b51afe;--mantine-color-violet-6: #b009ff;--mantine-color-violet-7: #9b00e4;--mantine-color-violet-8: #8a00cc;--mantine-color-violet-9: #7800b3;--mantine-color-indigo-0: #edecff;--mantine-color-indigo-1: #d6d5fe;--mantine-color-indigo-2: #aaa9f4;--mantine-color-indigo-3: #7b79eb;--mantine-color-indigo-4: #5451e4;--mantine-color-indigo-5: #3b37e0;--mantine-color-indigo-6: #2d2adf;--mantine-color-indigo-7: #1f1ec7;--mantine-color-indigo-8: #1819b2;--mantine-color-indigo-9: #0c149e;--mantine-color-cyan-0: #dffdff;--mantine-color-cyan-1: #caf5ff;--mantine-color-cyan-2: #99e8ff;--mantine-color-cyan-3: #64daff;--mantine-color-cyan-4: #3ccffe;--mantine-color-cyan-5: #24c8fe;--mantine-color-cyan-6: #00c2ff;--mantine-color-cyan-7: #00ade4;--mantine-color-cyan-8: #009acd;--mantine-color-cyan-9: #0085b5;--mantine-color-green-0: #e9fdec;--mantine-color-green-1: #d7f6dc;--mantine-color-green-2: #b0eab9;--mantine-color-green-3: #86df94;--mantine-color-green-4: #62d574;--mantine-color-green-5: #4ccf5f;--mantine-color-green-6: #3fcc54;--mantine-color-green-7: #2fb344;--mantine-color-green-8: #25a03b;--mantine-color-green-9: #138a2e;--mantine-color-yellow-0: #fff7e2;--mantine-color-yellow-1: #ffeecd;--mantine-color-yellow-2: #ffdc9c;--mantine-color-yellow-3: #ffc966;--mantine-color-yellow-4: #feb93a;--mantine-color-yellow-5: #feae1e;--mantine-color-yellow-6: #ffa90f;--mantine-color-yellow-8: #ca8200;--mantine-color-yellow-9: #af7000;--mantine-h1-font-size: clamp(28.0000px, calc(23.6364px + 1.3636vw), 40.0000px);--mantine-h1-font-weight: normal;--mantine-h2-font-size: clamp(24.0000px, calc(21.0909px + 0.9091vw), 32.0000px);--mantine-h2-font-weight: normal;--mantine-h3-font-size: clamp(20.0000px, calc(17.0909px + 0.9091vw), 28.0000px);--mantine-h3-font-weight: normal;--mantine-h4-font-size: clamp(16.0000px, calc(13.0909px + 0.9091vw), 24.0000px);--mantine-h4-font-weight: normal;--mantine-h5-font-size: clamp(16.0000px, calc(14.5455px + 0.4545vw), 20.0000px);--mantine-h5-font-weight: normal;--mantine-h6-font-size: 1rem;--mantine-h6-font-weight: normal;}
:root[data-mantine-color-scheme="dark"], :host([data-mantine-color-scheme="dark"]){--mantine-color-anchor: var(--mantine-color-text);--mantine-color-dimmed: #495057;--mantine-color-dark-filled: var(--mantine-color-dark-5);--mantine-color-dark-filled-hover: var(--mantine-color-dark-6);--mantine-color-dark-light: rgba(105, 105, 105, 0.15);--mantine-color-dark-light-hover: rgba(105, 105, 105, 0.2);--mantine-color-dark-light-color: var(--mantine-color-dark-0);--mantine-color-dark-outline: var(--mantine-color-dark-1);--mantine-color-dark-outline-hover: rgba(184, 184, 184, 0.05);--mantine-color-gray-filled: var(--mantine-color-gray-5);--mantine-color-gray-filled-hover: var(--mantine-color-gray-6);--mantine-color-gray-light: rgba(222, 226, 230, 0.15);--mantine-color-gray-light-hover: rgba(222, 226, 230, 0.2);--mantine-color-gray-light-color: var(--mantine-color-gray-0);--mantine-color-gray-outline: var(--mantine-color-gray-1);--mantine-color-gray-outline-hover: rgba(241, 243, 245, 0.05);--mantine-color-red-filled: var(--mantine-color-red-5);--mantine-color-red-filled-hover: var(--mantine-color-red-6);--mantine-color-red-light: rgba(236, 120, 120, 0.15);--mantine-color-red-light-hover: rgba(236, 120, 120, 0.2);--mantine-color-red-light-color: var(--mantine-color-red-0);--mantine-color-red-outline: var(--mantine-color-red-1);--mantine-color-red-outline-hover: rgba(254, 212, 212, 0.05);--mantine-color-pink-filled: var(--mantine-color-pink-5);--mantine-color-pink-filled-hover: var(--mantine-color-pink-6);--mantine-color-pink-light: rgba(250, 162, 193, 0.15);--mantine-color-pink-light-hover: rgba(250, 162, 193, 0.2);--mantine-color-pink-light-color: var(--mantine-color-pink-0);--mantine-color-pink-outline: var(--mantine-color-pink-1);--mantine-color-pink-outline-hover: rgba(255, 222, 235, 0.05);--mantine-color-grape-filled: var(--mantine-color-grape-5);--mantine-color-grape-filled-hover: var(--mantine-color-grape-6);--mantine-color-grape-light: rgba(229, 153, 247, 0.15);--mantine-color-grape-light-hover: rgba(229, 153, 247, 0.2);--mantine-color-grape-light-color: var(--mantine-color-grape-0);--mantine-color-grape-outline: var(--mantine-color-grape-1);--mantine-color-grape-outline-hover: rgba(243, 217, 250, 0.05);--mantine-color-violet-filled: var(--mantine-color-violet-5);--mantine-color-violet-filled-hover: var(--mantine-color-violet-6);--mantine-color-violet-light: rgba(209, 111, 255, 0.15);--mantine-color-violet-light-hover: rgba(209, 111, 255, 0.2);--mantine-color-violet-light-color: var(--mantine-color-violet-0);--mantine-color-violet-outline: var(--mantine-color-violet-1);--mantine-color-violet-outline-hover: rgba(241, 207, 255, 0.05);--mantine-color-indigo-filled: var(--mantine-color-indigo-5);--mantine-color-indigo-filled-hover: var(--mantine-color-indigo-6);--mantine-color-indigo-light: rgba(123, 121, 235, 0.15);--mantine-color-indigo-light-hover: rgba(123, 121, 235, 0.2);--mantine-color-indigo-light-color: var(--mantine-color-indigo-0);--mantine-color-indigo-outline: var(--mantine-color-indigo-1);--mantine-color-indigo-outline-hover: rgba(214, 213, 254, 0.05);--mantine-color-blue-filled: var(--mantine-color-blue-5);--mantine-color-blue-filled-hover: var(--mantine-color-blue-6);--mantine-color-blue-light: rgba(116, 192, 252, 0.15);--mantine-color-blue-light-hover: rgba(116, 192, 252, 0.2);--mantine-color-blue-light-color: var(--mantine-color-blue-0);--mantine-color-blue-outline: var(--mantine-color-blue-1);--mantine-color-blue-outline-hover: rgba(208, 235, 255, 0.05);--mantine-color-cyan-filled: var(--mantine-color-cyan-5);--mantine-color-cyan-filled-hover: var(--mantine-color-cyan-6);--mantine-color-cyan-light: rgba(100, 218, 255, 0.15);--mantine-color-cyan-light-hover: rgba(100, 218, 255, 0.2);--mantine-color-cyan-light-color: var(--mantine-color-cyan-0);--mantine-color-cyan-outline: var(--mantine-color-cyan-1);--mantine-color-cyan-outline-hover: rgba(202, 245, 255, 0.05);--mantine-color-teal-filled: var(--mantine-color-teal-5);--mantine-color-teal-filled-hover: var(--mantine-color-teal-6);--mantine-color-teal-light: rgba(99, 230, 190, 0.15);--mantine-color-teal-light-hover: rgba(99, 230, 190, 0.2);--mantine-color-teal-light-color: var(--mantine-color-teal-0);--mantine-color-teal-outline: var(--mantine-color-teal-1);--mantine-color-teal-outline-hover: rgba(195, 250, 232, 0.05);--mantine-color-green-filled: var(--mantine-color-green-5);--mantine-color-green-filled-hover: var(--mantine-color-green-6);--mantine-color-green-light: rgba(134, 223, 148, 0.15);--mantine-color-green-light-hover: rgba(134, 223, 148, 0.2);--mantine-color-green-light-color: var(--mantine-color-green-0);--mantine-color-green-outline: var(--mantine-color-green-1);--mantine-color-green-outline-hover: rgba(215, 246, 220, 0.05);--mantine-color-lime-filled: var(--mantine-color-lime-5);--mantine-color-lime-filled-hover: var(--mantine-color-lime-6);--mantine-color-lime-light: rgba(192, 235, 117, 0.15);--mantine-color-lime-light-hover: rgba(192, 235, 117, 0.2);--mantine-color-lime-light-color: var(--mantine-color-lime-0);--mantine-color-lime-outline: var(--mantine-color-lime-1);--mantine-color-lime-outline-hover: rgba(233, 250, 200, 0.05);--mantine-color-yellow-filled: var(--mantine-color-yellow-5);--mantine-color-yellow-filled-hover: var(--mantine-color-yellow-6);--mantine-color-yellow-light: rgba(255, 201, 102, 0.15);--mantine-color-yellow-light-hover: rgba(255, 201, 102, 0.2);--mantine-color-yellow-light-color: var(--mantine-color-yellow-0);--mantine-color-yellow-outline: var(--mantine-color-yellow-1);--mantine-color-yellow-outline-hover: rgba(255, 238, 205, 0.05);--mantine-color-orange-filled: var(--mantine-color-orange-5);--mantine-color-orange-filled-hover: var(--mantine-color-orange-6);--mantine-color-orange-light: rgba(255, 192, 120, 0.15);--mantine-color-orange-light-hover: rgba(255, 192, 120, 0.2);--mantine-color-orange-light-color: var(--mantine-color-orange-0);--mantine-color-orange-outline: var(--mantine-color-orange-1);--mantine-color-orange-outline-hover: rgba(255, 232, 204, 0.05);--app-cta-gradient: linear-gradient(90deg, var(--mantine-color-blue-9) 0%, var(--mantine-color-cyan-7) 100%);--app-color-surface: #2e2e2e;}
:root[data-mantine-color-scheme="light"], :host([data-mantine-color-scheme="light"]){--mantine-color-anchor: var(--mantine-color-text);--mantine-color-dimmed: #495057;--mantine-color-red-light: rgba(224, 40, 41, 0.1);--mantine-color-red-light-hover: rgba(224, 40, 41, 0.12);--mantine-color-red-outline-hover: rgba(224, 40, 41, 0.05);--mantine-color-violet-light: rgba(176, 9, 255, 0.1);--mantine-color-violet-light-hover: rgba(176, 9, 255, 0.12);--mantine-color-violet-outline-hover: rgba(176, 9, 255, 0.05);--mantine-color-indigo-light: rgba(45, 42, 223, 0.1);--mantine-color-indigo-light-hover: rgba(45, 42, 223, 0.12);--mantine-color-indigo-outline-hover: rgba(45, 42, 223, 0.05);--mantine-color-cyan-light: rgba(0, 194, 255, 0.1);--mantine-color-cyan-light-hover: rgba(0, 194, 255, 0.12);--mantine-color-cyan-outline-hover: rgba(0, 194, 255, 0.05);--mantine-color-green-light: rgba(63, 204, 84, 0.1);--mantine-color-green-light-hover: rgba(63, 204, 84, 0.12);--mantine-color-green-outline-hover: rgba(63, 204, 84, 0.05);--mantine-color-yellow-light: rgba(255, 169, 15, 0.1);--mantine-color-yellow-light-hover: rgba(255, 169, 15, 0.12);--mantine-color-yellow-outline-hover: rgba(255, 169, 15, 0.05);--app-color-surface: #f1f3f5;--app-cta-gradient: linear-gradient(90deg, var(--mantine-color-blue-filled) 0%, var(--mantine-color-cyan-5) 100%);}</style><style data-mantine-styles="classes">@media (max-width: 35.99375em) {.mantine-visible-from-xs {display: none !important;}}@media (min-width: 36em) {.mantine-hidden-from-xs {display: none !important;}}@media (max-width: 47.99375em) {.mantine-visible-from-sm {display: none !important;}}@media (min-width: 48em) {.mantine-hidden-from-sm {display: none !important;}}@media (max-width: 61.99375em) {.mantine-visible-from-md {display: none !important;}}@media (min-width: 62em) {.mantine-hidden-from-md {display: none !important;}}@media (max-width: 74.99375em) {.mantine-visible-from-lg {display: none !important;}}@media (min-width: 75em) {.mantine-hidden-from-lg {display: none !important;}}@media (max-width: 87.99375em) {.mantine-visible-from-xl {display: none !important;}}@media (min-width: 88em) {.mantine-hidden-from-xl {display: none !important;}}</style><div style="position:absolute;top:0rem" class=""></div><div style="max-width:var(--container-size-xl);height:100%;min-height:0rem" class=""><style data-mantine-styles="inline">.__m__-_R_5ub_{--grid-gutter:0rem;}</style><div style="height:100%;min-height:0rem" class="m_410352e9 mantine-Grid-root __m__-_R_5ub_"><div class="m_dee7bd2f mantine-Grid-inner" style="height:100%"><style data-mantine-styles="inline">.__m__-_R_rdub_{--col-flex-grow:auto;--col-flex-basis:91.66666666666667%;--col-max-width:91.66666666666667%;}@media(min-width: 48em){.__m__-_R_rdub_{--col-flex-grow:auto;--col-flex-basis:83.33333333333334%;--col-max-width:83.33333333333334%;}}</style><div style="min-width:0rem;height:100%;min-height:0rem;display:flex" class="m_96bdd299 mantine-Grid-col __m__-_R_rdub_"><style data-mantine-styles="inline">.__m__-_R_6qrdub_{margin-top:0rem;padding-inline:var(--mantine-spacing-xs);width:100%;}@media(min-width: 48em){.__m__-_R_6qrdub_{margin-top:var(--mantine-spacing-xl);width:80%;}}@media(min-width: 62em){.__m__-_R_6qrdub_{padding-inline:var(--mantine-spacing-xl);}}</style><div style="margin-inline:auto;max-width:var(--mantine-breakpoint-xl)" class="__m__-_R_6qrdub_"><div style="color:var(--mantine-color-dimmed)" class="m_4451eb3a mantine-Center-root" data-inline="true"><div style="--ti-size:var(--ti-size-xs);--ti-bg:transparent;--ti-color:var(--mantine-color-indigo-light-color);--ti-bd:calc(0.0625rem * var(--mantine-scale)) solid transparent;margin-inline-end:calc(0.125rem * var(--mantine-scale));color:inherit" class="m_7341320d mantine-ThemeIcon-root" data-variant="transparent" data-size="xs"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-lock "><path d="M5 13a2 2 0 0 1 2 -2h10a2 2 0 0 1 2 2v6a2 2 0 0 1 -2 2h-10a2 2 0 0 1 -2 -2v-6"></path><path d="M11 16a1 1 0 1 0 2 0a1 1 0 0 0 -2 0"></path><path d="M8 11v-4a4 4 0 1 1 8 0v4"></path></svg></div><p style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Веб-разработка на PHP</p></div><h1 style="--title-fw:var(--mantine-h1-font-weight);--title-lh:var(--mantine-h1-line-height);--title-fz:var(--mantine-h1-font-size);margin-bottom:var(--mantine-spacing-xl)" class="m_8a5d1357 mantine-Title-root" data-order="1">Теория: Микрофреймворк Slim</h1><script type="application/ld+json">{"@context":"https://schema.org","@type":"LearningResource","name":"Микрофреймворк Slim","inLanguage":"ru","isPartOf":{"@type":"LearningResource","name":"Веб-разработка на PHP"},"isAccessibleForFree":"False","hasPart":{"@type":"WebPageElement","isAccessibleForFree":"False","cssSelector":".paywalled"}}</script><div class=""><div style="--alert-color:var(--mantine-color-indigo-light-color);margin-bottom:var(--mantine-spacing-lg);font-size:var(--mantine-font-size-lg)" class="m_66836ed3 mantine-Alert-root" id="mantine-_R_remqrdub_" role="alert" aria-describedby="mantine-_R_remqrdub_-body" aria-labelledby="mantine-_R_remqrdub_-title"><div class="m_a5d60502 mantine-Alert-wrapper"><div class="m_667f2a6a mantine-Alert-icon"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-rocket "><path d="M4 13a8 8 0 0 1 7 7a6 6 0 0 0 3 -5a9 9 0 0 0 6 -8a3 3 0 0 0 -3 -3a9 9 0 0 0 -8 6a6 6 0 0 0 -5 3"></path><path d="M7 14a6 6 0 0 0 -3 6a6 6 0 0 0 6 -3"></path><path d="M14 9a1 1 0 1 0 2 0a1 1 0 1 0 -2 0"></path></svg></div><div class="m_667c2793 mantine-Alert-body"><div class="m_6a03f287 mantine-Alert-title"><span id="mantine-_R_remqrdub_-title" class="m_698f4f23 mantine-Alert-label">Полный доступ к материалам</span></div><div id="mantine-_R_remqrdub_-body" class="m_7fa78076 mantine-Alert-message"><div style="--group-gap:var(--mantine-spacing-md);--group-align:center;--group-justify:space-between;--group-wrap:wrap" class="m_4081bf90 mantine-Group-root"><p class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Зарегистрируйтесь и получите доступ к этому и десяткам других курсов</p><a style="--button-height:var(--button-height-xs);--button-padding-x:var(--button-padding-x-xs);--button-fz:var(--mantine-font-size-xs);--button-bg:linear-gradient(45deg, var(--mantine-color-blue-filled) 0%, var(--mantine-color-cyan-filled) 100%);--button-hover:linear-gradient(45deg, var(--mantine-color-blue-filled) 0%, var(--mantine-color-cyan-filled) 100%);--button-color:var(--mantine-color-white);--button-bd:none" class="mantine-focus-auto mantine-active m_77c9d27d mantine-Button-root m_87cf2631 mantine-UnstyledButton-root" data-variant="gradient" data-size="xs" href="/u/new"><span class="m_80f1301b mantine-Button-inner"><span class="m_811560b9 mantine-Button-label">Зарегистрироваться</span></span></a></div></div></div></div></div><div class="paywalled m_d08caa0 mantine-Typography-root"><p>Цикл запрос-обработка-ответ включает множество элементов, которые идентичны для всех сайтов. Поэтому возникли фреймворки — специализированные библиотеки, которые определяют структуру программы. В этом их отличие от обычных библиотек.</p>
<p>Благодаря фреймворкам можно сосредоточиться на логике сайта, а не на продумывании базовой архитектуры или кодировании вспомогательных инструментов.</p>
<p>Веб-фреймворки подразделяются на две большие группы: фреймворки и микрофреймворки.</p>
<p>Микрофреймворки устроены проще и содержат только минимально необходимую обвязку для комфортной работы в архитектуре HTTP — запрос-ответ. Они подходят для обучения, потому что просты в эксплуатации и не отвлекают от главного.</p>
<h2 id="heading-2-1">Slim</h2>
<p>Создадим подходящую структуру директорий в своей домашней директории:</p>
<code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">.
├── hexlet-slim-example
│ └── public</code>
<p>Далее создадим репозиторий внутри <em>hexlet-slim-example</em> и добавим его на <a style="text-decoration:underline" class="mantine-focus-auto m_849cf0da m_b6d8b162 mantine-Text-root mantine-Anchor-root" data-underline="hover" href="https://github.com" rel="noopener noreferrer" target="_blank">GitHub</a>. Не забудьте создать файл <em>.gitignore</em> и поместить туда директорию <em>vendor</em>. <em>hexlet-slim-example</em> теперь называется корневой директорией проекта (root directory).</p>
<p>Затем идем в корневую директорию проекта и устанавливаем Slim и его зависимости:</p>
<div style="margin-bottom:var(--mantine-spacing-lg)" class="m_e597c321 mantine-CodeHighlight-codeHighlight" dir="ltr"><div class="m_be7e9c9c mantine-CodeHighlight-controls"><button style="--ai-bg:transparent;--ai-hover:transparent;--ai-color:inherit;--ai-bd:none" class="mantine-focus-auto mantine-active m_d498bab7 mantine-CodeHighlight-control m_8d3f4000 mantine-ActionIcon-root m_87cf2631 mantine-UnstyledButton-root" data-variant="none" type="button" aria-label="Copy code"><span class="m_8d3afb97 mantine-ActionIcon-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M8 8m0 2a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2z"></path><path d="M16 8v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2"></path></svg></span></button></div><div style="--scrollarea-scrollbar-size:calc(0.25rem * var(--mantine-scale));--sa-corner-width:0px;--sa-corner-height:0px" class="m_f744fd40 mantine-CodeHighlight-scrollarea m_d57069b5 mantine-ScrollArea-root" dir="ltr"><div style="overflow-x:hidden;overflow-y:hidden;overscroll-behavior-inline:none" class="m_c0783ff9 mantine-ScrollArea-viewport" data-scrollbars="xy"><div class="m_b1336c6 mantine-ScrollArea-content"><pre class="m_2c47c4fd mantine-CodeHighlight-pre" style="padding:0"><code class="m_5caae6d3 mantine-CodeHighlight-code">composer require slim/slim slim/psr7 slim/http slim/php-view php-di/php-di</code></pre></div></div></div><button class="mantine-focus-auto m_c9378bc2 mantine-CodeHighlight-showCodeButton m_87cf2631 mantine-UnstyledButton-root" data-hidden="true" type="button">Expand code</button></div>
<p>Добавляем файл <em>hexlet-slim-example/public/index.php</em> со следующим содержимым:</p>
<div style="margin-bottom:var(--mantine-spacing-lg)" class="m_e597c321 mantine-CodeHighlight-codeHighlight" dir="ltr"><div class="m_be7e9c9c mantine-CodeHighlight-controls"><button style="--ai-bg:transparent;--ai-hover:transparent;--ai-color:inherit;--ai-bd:none" class="mantine-focus-auto mantine-active m_d498bab7 mantine-CodeHighlight-control m_8d3f4000 mantine-ActionIcon-root m_87cf2631 mantine-UnstyledButton-root" data-variant="none" type="button" aria-label="Copy code"><span class="m_8d3afb97 mantine-ActionIcon-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M8 8m0 2a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2z"></path><path d="M16 8v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2"></path></svg></span></button></div><div style="--scrollarea-scrollbar-size:calc(0.25rem * var(--mantine-scale));--sa-corner-width:0px;--sa-corner-height:0px" class="m_f744fd40 mantine-CodeHighlight-scrollarea m_d57069b5 mantine-ScrollArea-root" dir="ltr"><div style="overflow-x:hidden;overflow-y:hidden;overscroll-behavior-inline:none" class="m_c0783ff9 mantine-ScrollArea-viewport" data-scrollbars="xy"><div class="m_b1336c6 mantine-ScrollArea-content"><pre class="m_2c47c4fd mantine-CodeHighlight-pre" style="padding:0"><code class="m_5caae6d3 mantine-CodeHighlight-code"><?php
// Подключение автозагрузки через composer
require __DIR__ . '/../vendor/autoload.php';
use Slim\Factory\AppFactory;
$app = AppFactory::create();
$app->addErrorMiddleware(true, true, true);
$app->get('/', function ($request, $response) {
$response->getBody()->write('Welcome to Slim!');
return $response;
// Благодаря пакету slim/http этот же код можно записать короче
// return $response->write('Welcome to Slim!');
});
$app->run();</code></pre></div></div></div><button class="mantine-focus-auto m_c9378bc2 mantine-CodeHighlight-showCodeButton m_87cf2631 mantine-UnstyledButton-root" data-hidden="true" type="button">Expand code</button></div>
<p>Создадим файл <em>Makefile</em> в корне проекта и добавим туда задачу <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">start</code>:</p>
<div style="margin-bottom:var(--mantine-spacing-lg)" class="m_e597c321 mantine-CodeHighlight-codeHighlight" dir="ltr"><div class="m_be7e9c9c mantine-CodeHighlight-controls"><button style="--ai-bg:transparent;--ai-hover:transparent;--ai-color:inherit;--ai-bd:none" class="mantine-focus-auto mantine-active m_d498bab7 mantine-CodeHighlight-control m_8d3f4000 mantine-ActionIcon-root m_87cf2631 mantine-UnstyledButton-root" data-variant="none" type="button" aria-label="Copy code"><span class="m_8d3afb97 mantine-ActionIcon-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M8 8m0 2a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2z"></path><path d="M16 8v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2"></path></svg></span></button></div><div style="--scrollarea-scrollbar-size:calc(0.25rem * var(--mantine-scale));--sa-corner-width:0px;--sa-corner-height:0px" class="m_f744fd40 mantine-CodeHighlight-scrollarea m_d57069b5 mantine-ScrollArea-root" dir="ltr"><div style="overflow-x:hidden;overflow-y:hidden;overscroll-behavior-inline:none" class="m_c0783ff9 mantine-ScrollArea-viewport" data-scrollbars="xy"><div class="m_b1336c6 mantine-ScrollArea-content"><pre class="m_2c47c4fd mantine-CodeHighlight-pre" style="padding:0"><code class="m_5caae6d3 mantine-CodeHighlight-code">start:
php -S localhost:8080 -t public public/index.php</code></pre></div></div></div><button class="mantine-focus-auto m_c9378bc2 mantine-CodeHighlight-showCodeButton m_87cf2631 mantine-UnstyledButton-root" data-hidden="true" type="button">Expand code</button></div>
<p>Теперь выполним запуск:</p>
<div style="margin-bottom:var(--mantine-spacing-lg)" class="m_e597c321 mantine-CodeHighlight-codeHighlight" dir="ltr"><div class="m_be7e9c9c mantine-CodeHighlight-controls"><button style="--ai-bg:transparent;--ai-hover:transparent;--ai-color:inherit;--ai-bd:none" class="mantine-focus-auto mantine-active m_d498bab7 mantine-CodeHighlight-control m_8d3f4000 mantine-ActionIcon-root m_87cf2631 mantine-UnstyledButton-root" data-variant="none" type="button" aria-label="Copy code"><span class="m_8d3afb97 mantine-ActionIcon-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M8 8m0 2a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2z"></path><path d="M16 8v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2"></path></svg></span></button></div><div style="--scrollarea-scrollbar-size:calc(0.25rem * var(--mantine-scale));--sa-corner-width:0px;--sa-corner-height:0px" class="m_f744fd40 mantine-CodeHighlight-scrollarea m_d57069b5 mantine-ScrollArea-root" dir="ltr"><div style="overflow-x:hidden;overflow-y:hidden;overscroll-behavior-inline:none" class="m_c0783ff9 mantine-ScrollArea-viewport" data-scrollbars="xy"><div class="m_b1336c6 mantine-ScrollArea-content"><pre class="m_2c47c4fd mantine-CodeHighlight-pre" style="padding:0"><code class="m_5caae6d3 mantine-CodeHighlight-code">make start</code></pre></div></div></div><button class="mantine-focus-auto m_c9378bc2 mantine-CodeHighlight-showCodeButton m_87cf2631 mantine-UnstyledButton-root" data-hidden="true" type="button">Expand code</button></div>
<p>Вывод должен быть примерно таким:</p>
<div style="margin-bottom:var(--mantine-spacing-lg)" class="m_e597c321 mantine-CodeHighlight-codeHighlight" dir="ltr"><div class="m_be7e9c9c mantine-CodeHighlight-controls"><button style="--ai-bg:transparent;--ai-hover:transparent;--ai-color:inherit;--ai-bd:none" class="mantine-focus-auto mantine-active m_d498bab7 mantine-CodeHighlight-control m_8d3f4000 mantine-ActionIcon-root m_87cf2631 mantine-UnstyledButton-root" data-variant="none" type="button" aria-label="Copy code"><span class="m_8d3afb97 mantine-ActionIcon-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M8 8m0 2a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2z"></path><path d="M16 8v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2"></path></svg></span></button></div><div style="--scrollarea-scrollbar-size:calc(0.25rem * var(--mantine-scale));--sa-corner-width:0px;--sa-corner-height:0px" class="m_f744fd40 mantine-CodeHighlight-scrollarea m_d57069b5 mantine-ScrollArea-root" dir="ltr"><div style="overflow-x:hidden;overflow-y:hidden;overscroll-behavior-inline:none" class="m_c0783ff9 mantine-ScrollArea-viewport" data-scrollbars="xy"><div class="m_b1336c6 mantine-ScrollArea-content"><pre class="m_2c47c4fd mantine-CodeHighlight-pre" style="padding:0"><code class="m_5caae6d3 mantine-CodeHighlight-code">[Wed May 27 17:05:25 2020] PHP 7.4.3 Development Server (http://localhost:8080) started</code></pre></div></div></div><button class="mantine-focus-auto m_c9378bc2 mantine-CodeHighlight-showCodeButton m_87cf2631 mantine-UnstyledButton-root" data-hidden="true" type="button">Expand code</button></div>
<p>Эта команда содержит новую для нас опцию <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">-t</code>. С ее помощью меняется корневая директория — место, где происходит поиск файла <em>index.php</em>. Подобную директорию принято называть <em>public</em> и помещать в нее только то, что можно открыть напрямую из браузера. Остальное не должно лежать в этой директории, иначе нас могут взломать.</p>
<p>В конце открываем в браузере <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">localhost:8080</code>. Если все хорошо, то на экране появится надпись <em>Welcome to Slim!</em>:</p>
<p><img style="--image-object-fit:contain;width:auto" class="m_9e117634 mantine-Image-root" src="/rails/active_storage/blobs/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MTUyOTEsInB1ciI6ImJsb2JfaWQifX0=--43ba0a6127a8ffb75109ea2ba4c2c68f00408ccf/slim-welcome-page.png" alt="Slim welcome page" loading="lazy"/></p></div><div style="margin-block:var(--mantine-spacing-xl)" class=""><h2 style="--title-fw:var(--mantine-h2-font-weight);--title-lh:var(--mantine-h2-line-height);--title-fz:var(--mantine-h2-font-size);margin-bottom:var(--mantine-spacing-md)" class="m_8a5d1357 mantine-Title-root" data-order="2">Рекомендуемые программы</h2><style data-mantine-styles="inline">.__m__-_R_2mremqrdub_{--carousel-slide-gap:var(--mantine-spacing-xs);--carousel-slide-size:70%;}@media(min-width: 36em){.__m__-_R_2mremqrdub_{--carousel-slide-gap:var(--mantine-spacing-xl);--carousel-slide-size:50%;}}</style><div style="--carousel-control-size:calc(2.5rem * var(--mantine-scale));--carousel-controls-offset:var(--mantine-spacing-sm);margin-bottom:var(--mantine-spacing-lg);padding-block:var(--mantine-spacing-sm);background:var(--app-color-surface)" class="m_17884d0f mantine-Carousel-root responsiveClassName" data-orientation="horizontal" data-include-gap-in-size="true"><div class="m_39bc3463 mantine-Carousel-controls" data-orientation="horizontal"><button class="mantine-focus-auto m_64f58e10 mantine-Carousel-control m_87cf2631 mantine-UnstyledButton-root" type="button" data-inactive="true" data-type="previous" tabindex="-1"><svg viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg" style="transform:rotate(90deg);width:calc(1rem * var(--mantine-scale));height:calc(1rem * var(--mantine-scale));display:block"><path d="M3.13523 6.15803C3.3241 5.95657 3.64052 5.94637 3.84197 6.13523L7.5 9.56464L11.158 6.13523C11.3595 5.94637 11.6759 5.95657 11.8648 6.15803C12.0536 6.35949 12.0434 6.67591 11.842 6.86477L7.84197 10.6148C7.64964 10.7951 7.35036 10.7951 7.15803 10.6148L3.15803 6.86477C2.95657 6.67591 2.94637 6.35949 3.13523 6.15803Z" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd"></path></svg></button><button class="mantine-focus-auto m_64f58e10 mantine-Carousel-control m_87cf2631 mantine-UnstyledButton-root" type="button" data-inactive="true" data-type="next" tabindex="-1"><svg viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg" style="transform:rotate(-90deg);width:calc(1rem * var(--mantine-scale));height:calc(1rem * var(--mantine-scale));display:block"><path d="M3.13523 6.15803C3.3241 5.95657 3.64052 5.94637 3.84197 6.13523L7.5 9.56464L11.158 6.13523C11.3595 5.94637 11.6759 5.95657 11.8648 6.15803C12.0536 6.35949 12.0434 6.67591 11.842 6.86477L7.84197 10.6148C7.64964 10.7951 7.35036 10.7951 7.15803 10.6148L3.15803 6.86477C2.95657 6.67591 2.94637 6.35949 3.13523 6.15803Z" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd"></path></svg></button></div><div class="m_a2dae653 mantine-Carousel-viewport" data-type="media"><div class="m_fcd81474 mantine-Carousel-container __m__-_R_2mremqrdub_" data-orientation="horizontal"><div class="m_d98df724 mantine-Carousel-slide" data-orientation="horizontal"><div tabindex="0" style="cursor:pointer;height:100%"><a style="text-decoration:none" class="mantine-focus-auto m_849cf0da m_b6d8b162 mantine-Text-root mantine-Anchor-root" data-underline="hover" href="/programs/php?promo_name=programs_list&promo_position=course&promo_creative=catalog_card&promo_type=card" target="_blank"><div style="height:100%" class="m_e615b15f mantine-Card-root m_1b7284a3 mantine-Paper-root" data-with-border="true"><div style="--group-gap:calc(0.25rem * var(--mantine-scale));--group-align:center;--group-justify:flex-start;--group-wrap:nowrap" class="m_4081bf90 mantine-Group-root"><span style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">10 месяцев</span><span class="mantine-focus-auto m_b6d8b162 mantine-Text-root">·</span><span style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">С нуля</span></div><p style="margin-bottom:var(--mantine-spacing-sm);font-size:var(--mantine-font-size-h5);font-weight:bold" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">РНР-разработчик</p><p class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Изучите PHP и Laravel для разработки и проектирования REST API</p><div style="margin-top:auto" class=""><div class="m_4451eb3a mantine-Center-root"><img style="opacity:0.8;width:70%" class="m_9e117634 mantine-Image-root mantine-visible-from-xs" src="https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6Mzk5MiwicHVyIjoiYmxvYl9pZCJ9fQ==--e9d0f30948ea766a7e6bc3e3d56c192344d45fb8/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Programming-cuate%20(1).png" alt="РНР-разработчик" loading="eager"/></div><div style="--group-gap:var(--mantine-spacing-md);--group-align:end;--group-justify:space-between;--group-wrap:wrap;margin-top:var(--mantine-spacing-xs)" class="m_4081bf90 mantine-Group-root"><p style="font-size:var(--mantine-font-size-xl)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">от 5 650 ₽</p><p style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Посмотреть →</p></div></div></div></a></div></div><div class="m_d98df724 mantine-Carousel-slide" data-orientation="horizontal"><div tabindex="0" style="cursor:pointer;height:100%"><a style="text-decoration:none" class="mantine-focus-auto m_849cf0da m_b6d8b162 mantine-Text-root mantine-Anchor-root" data-underline="hover" href="/courses?promo_name=programs_list&promo_position=course&promo_creative=catalog_card&promo_type=card"><div style="height:100%" class="m_e615b15f mantine-Card-root m_1b7284a3 mantine-Paper-root" data-with-border="true"><h2 style="--title-fw:var(--mantine-h2-font-weight);--title-lh:var(--mantine-h2-line-height);--title-fz:var(--mantine-h2-font-size);margin-bottom:var(--mantine-spacing-md);font-size:var(--mantine-font-size-h3)" class="m_8a5d1357 mantine-Title-root" data-order="2" data-responsive="true">Каталог</h2><p style="margin-bottom:auto" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Полный список доступных курсов по разным направлениям</p><div style="margin-top:auto" class=""><div class="m_4451eb3a mantine-Center-root"><img style="opacity:0.8;width:70%" class="m_9e117634 mantine-Image-root mantine-visible-from-xs" src="/vite/assets/development-BVihs_d5.png" alt="Orientation"/></div></div></div></a></div></div></div></div></div></div></div></div></div><style data-mantine-styles="inline">.__m__-_R_1bdub_{--col-flex-grow:auto;--col-flex-basis:8.333333333333334%;--col-max-width:8.333333333333334%;}@media(min-width: 48em){.__m__-_R_1bdub_{--col-flex-grow:auto;--col-flex-basis:16.666666666666668%;--col-max-width:16.666666666666668%;}}</style><div style="min-width:0rem;height:100%;min-height:0rem" class="m_96bdd299 mantine-Grid-col __m__-_R_1bdub_"><div style="margin-inline:var(--mantine-spacing-xs)" class="mantine-visible-from-sm"><a style="--button-color:var(--mantine-color-white);margin-bottom:var(--mantine-spacing-lg);text-decoration:none" class="mantine-focus-auto m_849cf0da mantine-focus-auto m_77c9d27d mantine-Button-root m_87cf2631 mantine-UnstyledButton-root m_b6d8b162 mantine-Text-root mantine-Anchor-root" data-underline="hover" href="/courses/php-mvc/lessons/slim/finish_unit?unit=theory" data-disabled="true" data-block="true" disabled=""><span class="m_80f1301b mantine-Button-inner"><span class="m_811560b9 mantine-Button-label"><span style="margin-inline-end:var(--mantine-spacing-xs)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Дальше</span>→</span></span></a><a style="padding-inline:0rem" class="mantine-focus-auto m_f0824112 mantine-NavLink-root m_87cf2631 mantine-UnstyledButton-root"><span class="m_690090b5 mantine-NavLink-section" data-position="left"><div style="--ti-size:var(--ti-size-sm);--ti-bg:transparent;--ti-color:var(--mantine-color-indigo-light-color);--ti-bd:calc(0.0625rem * var(--mantine-scale)) solid transparent;color:inherit" class="m_7341320d mantine-ThemeIcon-root" data-variant="transparent" data-size="sm"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-list-numbers "><path d="M11 6h9"></path><path d="M11 12h9"></path><path d="M12 18h8"></path><path d="M4 16a2 2 0 1 1 4 0c0 .591 -.5 1 -1 1.5l-3 2.5h4"></path><path d="M6 10v-6l-2 2"></path></svg></div></span><div class="m_f07af9d2 mantine-NavLink-body"><span class="m_1f6ac4c4 mantine-NavLink-label">Навигация по теме</span><span class="m_57492dcc mantine-NavLink-description">Теория</span></div><span class="m_690090b5 mantine-NavLink-section" data-position="right"></span></a><div style="margin-block:var(--mantine-spacing-lg)" class="m_3eebeb36 mantine-Divider-root" data-orientation="horizontal" role="separator"></div><div style="margin-block:var(--mantine-spacing-lg)" class=""><div style="justify-content:space-between;margin-bottom:calc(0.1875rem * var(--mantine-scale));color:var(--mantine-color-dimmed);font-size:var(--mantine-font-size-xs)" class="m_8bffd616 mantine-Flex-root __m__-_R_qimrbdub_"><p style="font-size:var(--mantine-font-size-xs)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Завершено</p><p style="font-size:var(--mantine-font-size-xs)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">0 / 28</p></div><div style="--progress-size:var(--progress-size-sm)" class="m_db6d6462 mantine-Progress-root" data-size="sm"><div style="--progress-section-size:0%;--progress-section-color:var(--mantine-color-gray-filled)" class="m_2242eb65 mantine-Progress-section" role="progressbar" aria-valuemax="100" aria-valuemin="0" aria-valuenow="0" aria-valuetext="0%"></div></div></div><button style="padding-inline:0rem" class="mantine-focus-auto m_f0824112 mantine-NavLink-root m_87cf2631 mantine-UnstyledButton-root" type="button"><span class="m_690090b5 mantine-NavLink-section" data-position="left"><div style="--ti-size:var(--ti-size-sm);--ti-bg:transparent;--ti-color:var(--mantine-color-indigo-light-color);--ti-bd:calc(0.0625rem * var(--mantine-scale)) solid transparent;color:inherit" class="m_7341320d mantine-ThemeIcon-root" data-variant="transparent" data-size="sm"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-message "><path d="M8 9h8"></path><path d="M8 13h6"></path><path d="M18 4a3 3 0 0 1 3 3v8a3 3 0 0 1 -3 3h-5l-5 3v-3h-2a3 3 0 0 1 -3 -3v-8a3 3 0 0 1 3 -3h12"></path></svg></div></span><div class="m_f07af9d2 mantine-NavLink-body"><span class="m_1f6ac4c4 mantine-NavLink-label">Обсуждения (архив)</span><span class="m_57492dcc mantine-NavLink-description"></span></div></button><div style="--toc-bg:var(--mantine-color-blue-light);--toc-color:var(--mantine-color-blue-light-color);--toc-size:var(--mantine-font-size-sm);--toc-radius:var(--mantine-radius-sm);margin-top:var(--mantine-spacing-xl)" class="m_bcaa9990 mantine-TableOfContents-root" data-variant="light" data-size="sm"></div></div><div class="mantine-hidden-from-sm"><div style="--stack-gap:0rem;--stack-align:stretch;--stack-justify:flex-start" class="m_6d731127 mantine-Stack-root"><a style="--button-color:var(--mantine-color-white);margin-bottom:var(--mantine-spacing-xs);padding:0rem;text-decoration:none" class="mantine-focus-auto m_849cf0da mantine-focus-auto m_77c9d27d mantine-Button-root m_87cf2631 mantine-UnstyledButton-root m_b6d8b162 mantine-Text-root mantine-Anchor-root" data-underline="hover" href="/courses/php-mvc/lessons/slim/finish_unit?unit=theory" data-disabled="true" data-block="true" disabled=""><span class="m_80f1301b mantine-Button-inner"><span class="m_811560b9 mantine-Button-label">→</span></span></a><button style="--ai-size:var(--ai-size-sm);--ai-bg:transparent;--ai-hover:var(--mantine-color-indigo-light-hover);--ai-color:var(--mantine-color-indigo-light-color);--ai-bd:calc(0.0625rem * var(--mantine-scale)) solid transparent;padding-block:var(--mantine-spacing-lg);color:inherit;width:100%" class="mantine-focus-auto m_8d3f4000 mantine-ActionIcon-root m_87cf2631 mantine-UnstyledButton-root" data-variant="subtle" data-size="sm" data-disabled="true" type="button" disabled=""><span class="m_8d3afb97 mantine-ActionIcon-icon"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-list-numbers "><path d="M11 6h9"></path><path d="M11 12h9"></path><path d="M12 18h8"></path><path d="M4 16a2 2 0 1 1 4 0c0 .591 -.5 1 -1 1.5l-3 2.5h4"></path><path d="M6 10v-6l-2 2"></path></svg></span></button><button style="--ai-size:var(--ai-size-sm);--ai-bg:transparent;--ai-hover:var(--mantine-color-indigo-light-hover);--ai-color:var(--mantine-color-indigo-light-color);--ai-bd:calc(0.0625rem * var(--mantine-scale)) solid transparent;padding-block:var(--mantine-spacing-lg);color:inherit;width:100%" class="mantine-focus-auto mantine-active m_8d3f4000 mantine-ActionIcon-root m_87cf2631 mantine-UnstyledButton-root" data-variant="subtle" data-size="sm" type="button"><span class="m_8d3afb97 mantine-ActionIcon-icon"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-message "><path d="M8 9h8"></path><path d="M8 13h6"></path><path d="M18 4a3 3 0 0 1 3 3v8a3 3 0 0 1 -3 3h-5l-5 3v-3h-2a3 3 0 0 1 -3 -3v-8a3 3 0 0 1 3 -3h12"></path></svg></span></button></div></div></div></div></div></div></div>
</main>
<footer class="bg-dark fw-light text-light px-3 py-5">
<div class="row small">
<div class="col-12 col-sm-6 col-md-3">
<div class="h5 mb-3">Хекслет</div>
<ul class="list-unstyled">
<li>
<a class="nav-link link-light py-1 ps-0" href="/pages/about">О нас</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/testimonials">Отзывы</a>
</li>
<li>
<span class="nav-link link-light py-1 ps-0 external-link" data-href="https://b2b.hexlet.io" role="button">Корпоративное обучение</span>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/blog">Блог</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/qna">Вопросы и ответы</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/glossary">Глоссарий</a>
</li>
<li>
<span class="nav-link link-light py-1 ps-0 external-link" data-href="https://help.hexlet.io" data-target="_blank" role="button">Справка</span>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" target="_blank" rel="noopener noreferrer" href="/map">Карта сайта</a>
</li>
</ul>
</div>
<div class="col-12 col-sm-6 col-md-3">
<div class="h5 fw-normal mb-3">Направления</div>
<ul class="list-unstyled">
<li>
<a class="nav-link link-light py-1 ps-0" href="/courses_devops">DevOps
</a></li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/courses_data_analytics">Аналитика
</a></li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/courses_backend_development">Бэкенд
</a></li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/courses_programming">Программирование
</a></li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/courses_testing">Тестирование
</a></li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/courses_front_end_dev">Фронтенд
</a></li>
</ul>
</div>
<div class="col-12 col-sm-6 col-md-3">
<div class="h5">Профессии</div>
<ul class="list-unstyled">
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/devops-engineer-from-scratch">DevOps-инженер с нуля</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/go">Go-разработчик</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/java">Java-разработчик</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/python">Python-разработчик </a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/data-analytics">Аналитик данных</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/qa-engineer">Инженер по ручному тестированию</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/php">РНР-разработчик</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/frontend">Фронтенд-разработчик</a>
</li>
</ul>
</div>
<div class="col-12 col-sm-6 col-md-3">
<div class="h5">Навыки</div>
<ul class="list-unstyled">
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/python-django-developer">Django</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/docker">Docker</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/php-laravel-developer">Laravel</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/postman">Postman</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/js-react-developer">React</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/js-rest-api">REST API в Node.js</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/spring-boot">Spring Boot</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/typescript">Typescript</a>
</li>
</ul>
</div>
</div>
<hr>
<div class="row">
<div class="col-12 col-sm-4 col-md-2">
<div class="fs-4">
<ul class="list-unstyled d-flex">
<li class="me-3">
<a aria-label="Telegram" target="_blank" class="link-light" rel="noopener noreferrer nofollow" href="https://t.me/hexlet_ru"><span class="bi bi-telegram"></span>
</a></li>
<li>
<a aria-label="Youtube" target="_blank" class="link-light" rel="noopener noreferrer nofollow" href="https://www.youtube.com/user/HexletUniversity"><span class="bi bi-youtube"></span>
</a></li>
</ul>
</div>
<div class="mb-2 d-flex flex-column">
<a class="link-light text-decoration-none" rel="nofollow" href="mailto:support@hexlet.io">support@hexlet.io</a>
<a class="link-light text-decoration-none py-2" target="_blank" href="https://t.me/hexlet_help_bot">t.me/hexlet_help_bot</a>
</div>
<ul class="list-unstyled d-flex">
<li class="me-3">
<span class="link-light text-decoration-none opacity-50 x-font-size-18 external-link" rel="nofollow" data-href="https://hexlet.io/locale/switch?new_locale=en" data-target="_self" role="button"><span class="my-auto">EN</span>
</span></li>
<li class="me-3">
<span class="link-light text-decoration-none opacity-50 x-font-size-18 opacity-100 external-link" rel="nofollow" data-href="https://ru.hexlet.io/locale/switch?new_locale=ru" data-target="_self" role="button"><span class="my-auto">RU</span>
</span></li>
<li class="me-3">
<span class="link-light text-decoration-none opacity-50 x-font-size-18 external-link" rel="nofollow" data-href="https://kz.hexlet.io/locale/switch?new_locale=kz" data-target="_self" role="button"><span class="my-auto">KZ</span>
</span></li>
</ul>
</div>
<div class="col-12 col-sm-4 col-md-3">
<ul class="list-unstyled fs-4">
<li class="mb-3">
<a class="link-light text-decoration-none" href="tel:8%20800%20100%2022%2047">8 800 100 22 47</a>
<span class="d-block opacity-50 small">бесплатно по РФ</span>
</li>
<li>
<a class="link-light text-decoration-none" href="tel:%2B7%20495%20085%2021%2062">+7 495 085 21 62</a>
<span class="d-block opacity-50 small">бесплатно по Москве</span>
</li>
</ul>
</div>
<div class="col-12 col-sm-4 col-md-3">
<div class="small mb-3">Образовательные услуги оказываются на основании Л035-01298-77/01989008 от 14.03.2025</div>
<ul class="list-unstyled small">
<li>
<a class="nav-link link-light py-1 ps-0" href="/pages/legal">Правовая информация</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/pages/offer">Оферта</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/pages/license">Лицензия</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/pages/contacts">Контакты</a>
</li>
</ul>
</div>
<div class="col-12 col-sm-12 col-md-4 small">
<div class="mb-2">
<div>ООО «<a href="/" class="text-decoration-none link-light">Хекслет Рус</a>»</div>
<div>108813 г. Москва, вн.тер.г. поселение Московский,</div>
<div>г. Московский, ул. Солнечная, д. 3А, стр. 1, помещ. 20Б/3</div>
<div>ОГРН 1217300010476</div>
<div>ИНН 7325174845</div>
</div>
<hr>
<div>АНО ДПО «<a href="/" class="text-decoration-none link-light">Учебный центр «Хекслет</a>»</div>
<div>119331 г. Москва, вн. тер. г. муниципальный округ</div>
<div>Ломоносовский, пр-кт Вернадского, д. 29</div>
<div>ОГРН 1247700712390</div>
<div>ИНН 7736364948</div>
</div>
</div>
</footer>
<div id="root-assistant-offcanvas"></div>
<script src="/vite/assets/assistant-Bukl1lYy.js" crossorigin="anonymous" type="module"></script><link rel="modulepreload" href="/vite/assets/chunk-DsPFFUou.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/init-BrRXra1y.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/ErrorFallbackBlock-naDSYSy9.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/MarkdownBlock-DbyKWoR_.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/gon-D3e4yh1x.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/mantine-CGMYrt2Y.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/shiki-V011pkdv.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/utils-DRqSHbQE.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/routes-CCH8ilKF.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/lib-XR8Qr8kR.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/dist-GCHh59xr.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Box-B5-OOzBf.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/notifications.store-C-3AFSMn.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/useIsomorphicEffect-HJ6VK0D3.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/lib-KSp6QbZ0.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/axios-BEvgo0ym.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/classnames-l6ipYlLR.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/dayjs.min-BkKovM-s.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/debounce-jMQ_Cf4f.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/i18next-BlSq9s7B.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/client-U9M77rxp.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/react-dom-DaLxUz_h.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/useTranslation-Bx1Cdrkz.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/compiler-runtime-6XxiPFnt.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/jsx-runtime-CwjcCKJi.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/react-CkL4ZRHB.js" as="script" crossorigin="anonymous">
<script defer src="https://static.cloudflareinsights.com/beacon.min.js/v67327c56f0bb4ef8b305cae61679db8f1769101564043" integrity="sha512-rdcWY47ByXd76cbCFzznIcEaCN71jqkWBBqlwhF1SY7KubdLKZiEGeP7AyieKZlGP9hbY/MhGrwXzJC/HulNyg==" data-cf-beacon='{"version":"2024.11.0","token":"d11015b65d11429ea6b4a2ef37dd7e0b","server_timing":{"name":{"cfCacheStatus":true,"cfEdge":true,"cfExtPri":true,"cfL4":true,"cfOrigin":true,"cfSpeedBrain":true},"location_startswith":null}}' crossorigin="anonymous"></script>
</body>
</html>