<!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 18:16:10 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="SAyBFEn3SlWdYenJ5uR-lu_-IQrlktAt2yq5FnAYpVKn3Uoju4nnNSsizVHq647hL_cMoO2lLo9myiNCIh9CPA";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>Автозагрузка | PHP: Настройка окружения</title>
<meta name="description" content="Автозагрузка / PHP: Настройка окружения: Разбираемся, как работает автозагрузка файлов в Composer">
<link rel="canonical" href="https://ru.hexlet.io/courses/php-setup-environment/lessons/composer-autoload/theory_unit">
<meta name="robots" content="noarchive">
<meta property="og:title" content="Автозагрузка">
<meta property="og:title" content="PHP: Настройка окружения">
<meta property="og:description" content="Автозагрузка / PHP: Настройка окружения: Разбираемся, как работает автозагрузка файлов в Composer">
<meta property="og:url" content="https://ru.hexlet.io/courses/php-setup-environment/lessons/composer-autoload/theory_unit">
<meta name="csrf-param" content="authenticity_token" />
<meta name="csrf-token" content="zLj5Tlxvw9JtIFt6VIcWwBTeFui9_-fy6X8YLU5Gy9ojaTJ5rhFusttjf-JYiOa31Nc7QrXIGVBUn4J5HEEstA" />
<script src="/vite/assets/inertia-BIn5nEMk.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-DOv3_-Z_.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-26T18:16:10.202Z","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":"3fx_1Hx5ebV8GeJ6-AWgBzgNitAj6IA-rDmxhomb7CcyLbTjjgfU1cpaxuL0ClBw-ASneivffpwR2SvS25wLSQ","topics":[{"id":49173,"title":"Пытаюсь подключить библиотеку Funct - получаю такую ошибку:\n\nPHP Fatal error: Cannot redeclare Funct\\Collection\\compact()\n\nСудя по стэк трейсу, в стандарте php определена функция с таким названием и в самой библиотеке. А как решается такая коллизия?\n\nШапка файла \n```\n<?php\n\nnamespace Exmpl;\nrequire __DIR__ . '/vendor/autoload.php';\n\nuse PHPUnit\\Framework\\TestCase;\nuse function Funct\\Collection\\flatten;\n\nfunction getChildren($users){\n return array_map(fn($arg) => $arg['children'],flatten($users));\n}\n```\nJSON:\n```\n{\n \"name\": \"php/tests\",\n \"description\": \"\\\"php tests\\\"\",\n \"require\": {\n \"funct/funct\": \"^1.5\"\n },\n \"require-dev\": {\n \"phpunit/phpunit\": \"8\"\n },\n \"autoload\": {\n \"files\": [\n \"vendor/funct/funct/src/Collection.php\",\n \"vendor/funct/funct/src/Strings.php\"\n ]\n }\n}\n```\n","plain_title":"Пытаюсь подключить библиотеку Funct - получа. такую ошибку: PHP Fatal error: Cannot redeclare Funct\\Collection\\compact() Судя по стэк трейсу, в стандарте php определена функция с таким названием и в самой библиотеке. А как решается такая коллизия? Шапка файла ``` <?php namespace Exmpl; require DIR . '/vendor/autoload.php'; use PHPUnit\\Framework\\TestCase; use function Funct\\Collection\\flatten; function getChildren($users){ return array_map(fn($arg) => $arg['children'],flatten($users)); } JSON: { \"name\": \"php/tests\", \"description\": \"\\\"php tests\\\"\", \"require\": { \"funct/funct\": \"^1.5\" }, \"require-dev\": { \"phpunit/phpunit\": \"8\" }, \"autoload\": { \"files\": [ \"vendor/funct/funct/src/Collection.php\", \"vendor/funct/funct/src/Strings.php\" ] } } ``` ","creator":{"public_name":"Sergey","id":46834,"is_tutor":false},"comments":[{"creator":{"public_name":"Roman Ashikov","id":226258,"is_tutor":true},"id":105579,"body":"Приветствую, Сергей!\n\nА разве в документации Funct сказано, что нужно дополнительно вручную подключать файлы, после установки библиотеки?\n\nВзгляните на [composer.json](https://github.com/phpfunct/funct/blob/3f01f3f8f13c9f6b02a43b3ce65da141fdce3e40/composer.json#L15-L26), а затем в свой проект в файл *vendor/composer/autoload_psr4.php* и файл *vendor/composer/autoload_static.php*, там вы увидите, что composer уже добавил в автозагрузку все файлы библиотеки. Так происходит потому, что composer анализирует секцию autoload у подключаемых зависимостей.\n\n PHP Fatal error: Cannot redeclare Funct\\Collection\\compact()\n\nЭта ошибка как раз и возникает из-за того, что второй раз происходит определение уже добавленной в автозагрузку функции `compact()`.","topic_id":49173},{"creator":{"public_name":"Sergey","id":46834,"is_tutor":false},"id":105738,"body":"**Роман Ашиков**, это что получается, если добавил библиотеку в автозагрузку, то никаких явных импортов в файле делать не нужно, всё сделает composer? Я с джавы и в моём понимании на использование библиотек требуется её явный импорт в начале файла. А тут я добавил библиотеку, а явно ничего не прописываю, хотя в предыдущих темах курса эту тему плотно освещали reque_once, reque etc. Или указание require __DIR__ . '/vendor/autoload.php' сделает всю грязную работу? ","topic_id":49173},{"creator":{"public_name":"Roman Ashikov","id":226258,"is_tutor":true},"id":105778,"body":"> получается, если добавил библиотеку в автозагрузку, то никаких явных импортов в файле делать не нужно, всё сделает composer?\n\nИмпорт конкретной функции в файле, где она будет использоваться делается с помощью ключевого слова `use`. Но указание пространства имён не влияет на загрузку этой функции. Мы должны использовать `require` конкретного файла или автозагрузку с помощью composer, чтобы код начал работать.\n\n> в предыдущих темах курса эту тему плотно освещали reque_once, reque etc.\n\nНо [там](https://ru.hexlet.io/courses/php-basics/lessons/require/theory_unit) ведь не было ни слова о автозагрузке. Кроме:\n\n> Как вы увидите в следующих курсах, современный стандарт разработки на PHP полагается на механизм автозагрузки и запрещает использование явного включения файлов.\n\n> Или указание require DIR . '/vendor/autoload.php' сделает всю грязную работу?\n\nДа. Ведь composer анализирует секцию autoload у подключаемых зависимостей, а значит автоматически загружает нужные файлы.","topic_id":49173}],"communitable":{"parent_entity_name":null,"parent_entity_url":null,"entity_name":"Автозагрузка","entity_url":null,"active":true}},{"id":31735,"title":"Все получилось, но не понятно как работает это: \"Запустите проект на выполнение **bin/php-package**\". Я ввел в командной строке **bin/php-package**, у меня **спросили имя**, но вопрос остался, как это сработало? Я наверно где то пропустил, где писали о том, что, что бы запустить проект, надо написать такую команду....","plain_title":"Все получилось, но не понятно как работает это: \"Запустите проект на выполнение bin/php-package\". Я ввел в командной строке bin/php-package, у меня спросили имя, но вопрос остался, как это сработало? Я наверно где то пропустил, где писали о том, что, что бы запустить проект, надо написать такую команду.... ","creator":{"public_name":"Денис Солодухин","id":198418,"is_tutor":false},"comments":[{"creator":{"public_name":"Vadym Kykalo","id":159716,"is_tutor":false},"id":68967,"body":"**Денис Солодухин**, #!/usr/bin/env php сверху в этом файле есть такая запись. это так шебанг , в нем указан путь до вашего интерпретатора php. файл был запущен поскольку этот файл есть исполняемый . https://ru.wikipedia.org/wiki/%D0%A8%D0%B5%D0%B1%D0%B0%D0%BD%D0%B3_(Unix)","topic_id":31735}],"communitable":{"parent_entity_name":null,"parent_entity_url":null,"entity_name":"Автозагрузка","entity_url":null,"active":true}},{"id":31717,"title":"Возвращаясь к вышепройденному ))\n\nКлонируем без проблем, для установки зависимостей сразу после клонирования набираем _composer install_ и...\n\nХа-ха 2 раза, имеем:\n\n```Loading composer repositories with package information\nInstalling dependencies (including require-dev) from lock file\nYour requirements could not be resolved to an installable set of packages.\n\n Problem 1\n - Installation request for codeclimate/php-test-reporter 0.3.x-dev -> satisfiable by codeclimate/php-test-reporter[0.3.x-dev].\n - codeclimate/php-test-reporter 0.3.x-dev requires ext-curl * -> the requested PHP extension curl is missing from your system.\n Problem 2\n - Installation request for codeclimate/php-test-reporter\n... и т.д. + перечень:\n\nTo 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 ... и т.д.\n - /etc/php/7.2/cli/conf.d/20-xsl.ini\n You can also run `php --ini` inside terminal to see which files are used by PHP in CLI mode.\n```\n\"Залечилось\", как верно подметил **Денис Абдрахманов**,\n\n_sudo apt install php-curl_\n\nв корневой клонированного проекта","plain_title":"Возвращаясь к вышепройденному )) Клонируем без проблем, для установки зависимостей сразу после клонирования набираем composer install и... Ха-ха 2 раза, имеем: ```Loading composer repositories with package information Installing dependencies (including require-dev) from lock file Your requirements could not be resolved to an installable set of packages. Problem 1 - Installation request for codeclimate/php-test-reporter 0.3.x-dev -> satisfiable by codeclimate/php-test-reporter[0.3.x-dev]. - codeclimate/php-test-reporter 0.3.x-dev requires ext-curl * -> the requested PHP extension curl is missing from your system. Problem 2 - Installation request for codeclimate/php-test-reporter ... и т.д. + перечень: 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/20-xsl.ini You can also run php --ini inside terminal to see which files are used by PHP in CLI mode. ``` \"Залечилось\", как верно подметил Денис Абдрахманов, sudo apt install php-curl в корневой клонированного проекта ","creator":{"public_name":"Михаил Лось","id":209057,"is_tutor":false},"comments":[{"creator":{"public_name":"Сергей К.","id":5174,"is_tutor":false},"id":68977,"body":"Вижу, что с проблемой вы разобрались, верно?","topic_id":31717},{"creator":{"public_name":"Сергей К.","id":5174,"is_tutor":false},"id":69006,"body":"Отлично!","topic_id":31717},{"creator":{"public_name":"Михаил Лось","id":209057,"is_tutor":false},"id":69005,"body":"**Сергей К.**, Да! Хотя были ещё... \"ветвления\" )). Но, в конце концов, _имя_ у меня спросили. ","topic_id":31717}],"communitable":{"parent_entity_name":null,"parent_entity_url":null,"entity_name":"Автозагрузка","entity_url":null,"active":true}},{"id":46762,"title":"Здравствуйте. Хотел бы спросить по поводу пространства имен. Скажем, у нас есть два файла: №1 и №2. И оба находятся на разных уровнях вложенности относительно друг друга. В обоих файлах прописаны пространства имен. И вот, скажем, в файле №1 прописано использование кода (через пространство имен) из файла №2. Вот я сколько копаюсь во всем этом, все пытаюсь понять и никак не могу, каким образом этот файл №2 будет найден, когда в проекте на разных уровнях вложенности могут быть тысячи файлов, а мы указываем только название=пространство имен. Ведь мы при подгрузке кода через указание пространства имен не указываем путь к файлу №2, в котором это пространство имен прописано, а указываем только название, т.е. пространство имен. Как этот файл №2 тогда будет найден? Программа или нечто (назовем это по-нубски) будет заходить подряд во все файлы и анализировать их содержание, пока не найдет файл, в котором будет нужное пространство имен? ","plain_title":"Здравствуйте. Хотел бы спросить по поводу пространства имен. Скажем, у нас есть два файла: №1 и №2. И оба находятся на разных уровнях вложенности относительно друг друга. В обоих файлах прописаны пространства имен. И вот, скажем, в файле №1 прописано использование кода (через пространство имен) из файла №2. Вот я сколько копаюсь во всем этом, все пытаюсь понять и никак не могу, каким образом этот файл №2 будет найден, когда в проекте на разных уровнях вложенности могут быть тысячи файлов, а мы указываем только название=пространство имен. Ведь мы при подгрузке кода через указание пространства имен не указываем путь к файлу №2, в котором это пространство имен прописано. Как этот файл тогда будет найден? Программа или нечто (назовем это по-нубски) будет заходить подряд во все файлы и анализировать названия пространства имен, пока не найдет файл, в котором будет нужное пространство имен? ","creator":{"public_name":"Sergey d.","id":285141,"is_tutor":false},"comments":[{"creator":{"public_name":"Александр Петров","id":271659,"is_tutor":false},"id":100764,"body":"Так ведь урок так и называется \"Автозагрузка\" ) \nЦитаты из урока: 1) \"Указание пространства имён само по себе никак не влияет на их загрузку\", 2) \"Composer умеет автоматически загружать все необходимые файлы\" и 3) \"В случае с файлами, в которых есть только пространство имён и функции, всё чуть сложнее. Каждый новый файл должен быть прописан внутри composer.json, только тогда он будет загружен\" - и далее подробности того, как это всё работает. В ином случае да, пришлось бы всё прописывать через require, но \"нечто\" под названием Composer упрощает нам жизнь.","topic_id":46762},{"creator":{"public_name":"Sergey d.","id":285141,"is_tutor":false},"id":100892,"body":"**Роман Ашиков**, здравствуйте. Дело в том, что я прочитал неоднократно этот урок, но ясности из комментария все-таки не добавилось, поэтому и не отметил как решение ) Буду гуглить, наверняка, понимание придет )","topic_id":46762},{"creator":{"public_name":"Roman Ashikov","id":226258,"is_tutor":true},"id":101014,"body":"Давайте я попробую объяснить. Файлы для автозагрузки прописываются в _composer.json_. После этого запускается команда _composer dump-autoload_, которая генерирует нужный код в директории _vendor_ в файле _autoload.php_. Попробуйте проанализировать его содержимое. После того, как код сгенерирован мы можем в начале файла с нашим кодом просто прописать\n\n require __DIR__ . '/../vendor/autoload.php';\n\nС этого момента начинают работать возможности автозагрузки самого PHP. При запуске скрипта он подгружает _autoload.php_ в котором уже сказано, что еще нужно загрузить. А когда все необходимые файлы загружены, не составляет труда \"разрулить\" неймспейсы. Они же уникальны и php знает какой из них какому файлу соответствует.","topic_id":46762},{"creator":{"public_name":"Roman Ashikov","id":226258,"is_tutor":true},"id":100809,"body":"Добрый день!\n\nАлександр верно ответил на ваш вопрос. Загрузкой файлов занимается composer. Если вам помог ответ Александра, можно нажать на кнопку \"Отметить как решение\" и поблагодарить его.","topic_id":46762}],"communitable":{"parent_entity_name":null,"parent_entity_url":null,"entity_name":"Автозагрузка","entity_url":null,"active":true}},{"id":20206,"title":"После ввода имени выдает ошибку:\n```\nwhat is your name?: n\nPHP Fatal error: Uncaught Error: Class 'Php\\Package\\User' not found in /home/nurgeldy/PHPproject/php-package/bin/php-package:16\nStack trace:\n#0 {main}\n thrown in /home/nurgeldy/PHPproject/php-package/bin/php-package on line 16\n```\nтак и должно быть на этом этапе или в `composer.json` нужно вручную вписать секцию `autoload`, указав файл?","plain_title":"После ввода имени выдает ошибку: ``` what is your name?: n PHP Fatal error: Uncaught Error: Class 'Php\\Package\\User' not found in /home/nurgeldy/PHPproject/php-package/bin/php-package:16 Stack trace: 0 {main} thrown in /home/nurgeldy/PHPproject/php-package/bin/php-package on line 16 `` так и должно быть на этом этапе или вcomposer.jsonнужно вручную вписать секциюautoload`, указав файл? ","creator":{"public_name":"Нургельды Дюсенов","id":59426,"is_tutor":false},"comments":[{"creator":{"public_name":"Нургельды Дюсенов","id":59426,"is_tutor":false},"id":42726,"body":"ок. Попробую все заново. А то ни одну самостоятельную работу из этого курса не получается выполнить - везде какие то ошибки выходят.","topic_id":20206},{"creator":{"public_name":"Нургельды Дюсенов","id":59426,"is_tutor":false},"id":42714,"body":"Клонировал пакет, установил зависимости. Вроде больше ничего и не делал.\n\nДо этого мудрил с файлом .bashrc, так как несколько раз ставил composer в разные папки, он все не хотел толком работать и я уже было подзапутался немного в своих действиях. Прописал в .bashrc экспорт переменной с путем к композеру. После этого запуск bin/php-package вывел строку с запросом имени.","topic_id":20206},{"creator":{"public_name":"Kirill Mokevnin","id":1,"is_tutor":false},"id":42708,"body":"А вы с нуля делали init или в папке уже что-то было?","topic_id":20206},{"creator":{"public_name":"Kirill Mokevnin","id":1,"is_tutor":false},"id":42717,"body":"> Прописал в .bashrc экспорт переменной с путем к композеру.\n\nЭто неправильный подход, в документации (и у нас в курсе) указано как его установить в одну из директорий находящихся в PATH.","topic_id":20206},{"creator":{"public_name":"Kirill Mokevnin","id":1,"is_tutor":false},"id":42728,"body":"Настройка окружения это так, но надо пробовать и доделывать, именно здесь качается экспириенс.","topic_id":20206},{"creator":{"public_name":"Kirill Mokevnin","id":1,"is_tutor":false},"id":42757,"body":"Видеть бы ошибки)","topic_id":20206},{"creator":{"public_name":"Нургельды Дюсенов","id":59426,"is_tutor":false},"id":42773,"body":"Получилось пройти этот этап!)","topic_id":20206},{"creator":{"public_name":"Нургельды Дюсенов","id":59426,"is_tutor":false},"id":42768,"body":"ну там нотификации, что нет необходимых пакетов. Среди которых dom и еще 6 названий. Прочитал, что dom можно активировать в файле php.ini. Дописал строчку extension=dom.so - не помогло. Решил ставить все по очереди из списка нотификаций. Поставил dom и почти все получилось!) Требовался только PHPunit (хотя я раньше его ставил, но видимо криво).\nЧерез composer ставлю phpunit - начинает требовать mbstring. Вот, ставлю сейчас его. \nВ интернете сейчас через 2G, поэтому все еще грузится.","topic_id":20206},{"creator":{"public_name":"Нургельды Дюсенов","id":59426,"is_tutor":false},"id":42734,"body":"1) Установил композер в `/usr/local/bin/composer`\nэтот путь есть в списке \n```\n/usr/local/bin/.composer/vendor/bin:/home/nurgeldy/bin:/home/nurgeldy/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin\n```\n2) клонировал php-package\n3) выполняю там composer install\nи снова пошли ошибки: что необходимы дополнительные пакеты(программы), среди которых и PHPUnit, но я его ранее уже устанавливал..","topic_id":20206}],"communitable":{"parent_entity_name":null,"parent_entity_url":null,"entity_name":"Автозагрузка","entity_url":null,"active":true}},{"id":25503,"title":"Добрый день! Так я и не смог запустить Runner.php \nОшибка:\n```\nPHP Fatal error: Cannot redeclare CompTest\\Runner\\run() (previously declared in /home/aynur/workspace/comp-test/src/Runner.php:10) in /home/aynur/workspace/comp-test/src/Runner.php on line 15\n```\n\n[git](https://github.com/GalimAynur/comp-test) Подскажите пожалуйста как решить данную проблему.","plain_title":"Добрый день! Так я и не смог запустить Runner.php Ошибка: PHP Fatal error: Cannot redeclare CompTest\\Runner\\run() (previously declared in /home/aynur/workspace/comp-test/src/Runner.php:10) in /home/aynur/workspace/comp-test/src/Runner.php on line 15 git (https://github.com/GalimAynur/comp-test) Подскажите пожалуйста как решить данную проблему. ","creator":{"public_name":"Aynur Galimov","id":180275,"is_tutor":false},"comments":[{"creator":{"public_name":"Nikolai Gagarinov","id":104929,"is_tutor":true},"id":54705,"body":"Нашёл в чем ошибка - твой файл `Runner.php` подгружается через `autoload.php` \nИ получается, что сперва файл подгружается через композер, а потом еще раз содержимое файла, то есть такая двойная автозагрузка.\nСоветую тебе создать где-нибудь на уровень выше или в другом каталоге файл, который будет выполнять код и содержать автозагрузку. А в `Runner.php` тебе не придётся подгружать файл и ошибка исчезнет.","topic_id":25503},{"creator":{"public_name":"Nikolai Gagarinov","id":104929,"is_tutor":true},"id":54700,"body":"Привет, какие действия совершались?\nОшибка говорит о том, что два раза объявляется функция. Запустил код - всё ок.","topic_id":25503},{"creator":{"public_name":"Aynur Galimov","id":180275,"is_tutor":false},"id":54704,"body":"Привет. \n1) composer dump-autoload\n2) php src/Runner.php и выскакивает ошибка, которая в первом сообщении.\nЯ не могу понять где она ещё объявляется, если только в composer.json я что то напортачил.","topic_id":25503},{"creator":{"public_name":"Aynur Galimov","id":180275,"is_tutor":false},"id":54718,"body":"Спасибо большое! Ваш комментарий помог разобраться с данной темой!","topic_id":25503}],"communitable":{"parent_entity_name":null,"parent_entity_url":null,"entity_name":"Автозагрузка","entity_url":null,"active":true}},{"id":31964,"title":"Во первых, спасибо за уроки. Действительно полезные материалы изложены.\n\nУшел из фронтенда, потому что там (почти) каждый день появляется новая библиотека/фреймворк, и сложно разбираться в этом зоопарке зависимостей.\n\nСейчас запустил composer install, все работает. Но папка весит больше 120мб. Неужели в бекенде точно такая же ситуация ?","plain_title":"Во первых, спасибо за уроки. Действительно полезные материалы изложены. Ушел из фронтенда, потому что там (почти) каждый появляется новая библиотека/фреймворк, и сложно разбираться в этом зоопарке зависимостей. Сейчас запустил composer install, все работает. Но папка весит больше 120мб. Неужели в бекенде точно такая же ситуация ? ","creator":{"public_name":"Ahmad Dusmatov","id":65821,"is_tutor":false},"comments":[{"creator":{"public_name":"Ahmad Dusmatov","id":65821,"is_tutor":false},"id":69487,"body":"**Андрей Миськов**, Спасибо за ответ:) Продолжу изучать.","topic_id":31964},{"creator":{"public_name":"Андрей Миськов","id":103643,"is_tutor":false},"id":69453,"body":"Добрый день, Ахмад!\n\n> Во первых, спасибо за уроки. Действительно полезные материалы изложены.\n\nСпасибо за отзыв, рады слышать :)\n\n> папка весит больше 120мб\n\nИменно в этом репозитории есть несколько увесистых служебных пакетов для тестирования и проверки кода. Если вы установите, например, Laravel (популярный веб-фреймворк), то `vendor` для него будет весить поменьше.\n\nВообще, тут дело не столько в размере зависимостей, сколько в стабильности того, что на них основано.\n\n> Неужели в бекенде точно такая же ситуация?\n\nВопрос едва ли может иметь однозначный ответ, всё довольно субъективно. По сути любой современный фреймворк на любом языке — это курируемый набор сторонних пакетов. Без этого никак. Слишком много всего нужно, грех не пользоваться плодами работы сообщества. С другой стороны, экосистема JS-фронтенда сильно подвержена хайповости и баззвордности. PHP в этом плане гораздо стабильнее и, что ли, взрослее.\n\nЯ сам с фронта и мне гораздо приятнее делать что-то на бэкенде. Рекомендую продолжать изучать PHP, думаю, вам понравится :)","topic_id":31964}],"communitable":{"parent_entity_name":null,"parent_entity_url":null,"entity_name":"Автозагрузка","entity_url":null,"active":true}},{"id":31680,"title":"> Она генерирует необходимый код в папке vendor, реализующий указанную загрузку.\n\nтак мы же недавно добавили папку vendor в .gitignore. Кто тогда будет следить за изменениями этого необходимого кода?","plain_title":"Она генерирует необходимый код в папке vendor, реализующий указанную загрузку. так мы же недавно добавили папку vendor в .gitignore. Кто тогда будет следить за изменениями этого необходимого кода? ","creator":{"public_name":"Александр Петраков","id":125514,"is_tutor":false},"comments":[{"creator":{"public_name":"Александр О.","id":61806,"is_tutor":false},"id":68958,"body":"Добрый день!\n\n> так мы же недавно добавили папку vendor в .gitignore. Кто тогда будет следить за изменениями этого необходимого кода?\n\nИгнорим этот каталог, потому что он автоматически сгенерится (с учётом обновлённой секции `autoload`), если скачать (склонировать) себе репозиторий с гитхаба и выполнить установку зависимостей.","topic_id":31680}],"communitable":{"parent_entity_name":null,"parent_entity_url":null,"entity_name":"Автозагрузка","entity_url":null,"active":true}},{"id":45538,"title":"> Добавьте файл Runner.php в автозагрузку (секция files)\n\nПодскажите, есть ли какая-то команда для composer, чтобы его туда добавить, либо это нужно делать вручную путем правки файла Runner.php? Спасибо","plain_title":"Добавьте файл Runner.php в автозагрузку (секция files) Подскажите, есть ли какая-то команда для composer, чтобы его туда добавить, либо это нужно делать вручную путем правки файла Runner.php? Спасибо ","creator":{"public_name":"Sergey d.","id":285141,"is_tutor":false},"comments":[{"creator":{"public_name":"Roman Ashikov","id":226258,"is_tutor":true},"id":98502,"body":"Приветствую!\n\nСогласно документации на getcomposer.org — [Autoloading](https://getcomposer.org/doc/01-basic-usage.md#autoloading), файлы для автозагрузки прописываются только вручную.\n\n> вручную путем правки файла Runner.php\n\nВносить изменения нужно в _composer.json_, _Runner.php_ мы создали в рамках предыдущего урока.","topic_id":45538}],"communitable":{"parent_entity_name":null,"parent_entity_url":null,"entity_name":"Автозагрузка","entity_url":null,"active":true}},{"id":19472,"title":"Чёт я затупил. Как и что запустить на выполнение: Запустите проект на выполнение bin/php-package","plain_title":"Чёт я затупил. Как и что запустить на выполнение: Запустите проект на выполнение bin/php-package ","creator":{"public_name":"Anatol Meshalkin","id":167557,"is_tutor":false},"comments":[{"creator":{"public_name":"Anatol Meshalkin","id":167557,"is_tutor":false},"id":41213,"body":"Ввожу в терминале $ bin/php-package\nПолучаю такой вывод:\nPHP Warning: require_once(/home/geek/php-package/bin/../vendor/autoload.php): failed to open stream: No such file or directory in /home/geek/php-package/bin/php-package on line 10\nPHP Fatal error: require_once(): Failed opening required '/home/geek/php-package/bin/../vendor/autoload.php' (include_path='.:/usr/share/php') in /home/geek/php-package/bin/php-package on line 10\n\nИ не пойму, - или я неправильно выполняю команду, то есть вообще делаю неправильное действие. То ли я ошибся где-то ранее, и вывод показывает эту ошибку.","topic_id":19472},{"creator":{"public_name":"Александр О.","id":61806,"is_tutor":false},"id":41214,"body":"А вы выполнили перед этим установку зависимостей?","topic_id":19472},{"creator":{"public_name":"Anatol Meshalkin","id":167557,"is_tutor":false},"id":41255,"body":"Разобрался, я устанавливал curl командой: ```sudo apt-get install curl```\n\nА надо было: ```sudo apt-get install php-curl ```\n\nТеперь всё ок.","topic_id":19472},{"creator":{"public_name":"Anatol Meshalkin","id":167557,"is_tutor":false},"id":41231,"body":"Вот вывод теминала:\n```geek@Geek:~/php-package$ composer install\nLoading composer repositories with package information\nInstalling dependencies (including require-dev) from lock file\nYour requirements could not be resolved to an installable set of packages.\n\n Problem 1\n - Installation request for codeclimate/php-test-reporter 0.3.x-dev -> satisfiable by codeclimate/php-test-reporter[0.3.x-dev].\n - codeclimate/php-test-reporter 0.3.x-dev requires ext-curl * -> the requested PHP extension curlis missing from your system.\n Problem 2\n - Installation request for codeclimate/php-test-reporter dev-master -> satisfiable by codeclimate/php-test-reporter[dev-master].\n - codeclimate/php-test-reporter dev-master requires ext-curl * -> the requested PHP extension curl is missing from your system.\n Problem 3\n - Installation request for guzzle/guzzle v3.9.3 -> satisfiable by guzzle/guzzle[v3.9.3].\n - guzzle/guzzle v3.9.3 requires ext-curl * -> the requested PHP extension curl is missing from your system.\n Problem 4\n - guzzle/guzzle v3.9.3 requires ext-curl * -> the requested PHP extension curl is missing from your system.\n - satooshi/php-coveralls v1.1.0 requires guzzle/guzzle ^2.8 || ^3.0 -> satisfiable by guzzle/guzzle[v3.9.3].\n - Installation request for satooshi/php-coveralls v1.1.0 -> satisfiable by satooshi/php-coveralls[v1.1.0]. ```\nПолучается жалуется на curl.\nПроверяю curl:\n```geek@Geek:~/php-package$ curl -V\ncurl 7.58.0 (x86_64-pc-linux-gnu) libcurl/7.58.0 OpenSSL/1.1.0g zlib/1.2.11 libidn2/2.0.4 libpsl/0.19.1 (+libidn2/2.0.4) nghttp2/1.30.0 librtmp/2.3\nRelease-Date: 2018-01-24\nProtocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtmp rtsp smb smbs smtp smtps telnet tftp\nFeatures: AsynchDNS IDN IPv6 Largefile GSS-API Kerberos SPNEGO NTLM NTLM_WB SSL libz TLS-SRP HTTP2 UnixSockets HTTPS-proxy PSL```\nВ чем может быть проблема?","topic_id":19472},{"creator":{"public_name":"Anatol Meshalkin","id":167557,"is_tutor":false},"id":41223,"body":"Да, и сейчас просматривая весь столбик вывода после команды: composer install увидел, что есть какая-то проблема:\n\nLoading composer repositories with package information\nInstalling dependencies (including require-dev) from lock file\nYour requirements could not be resolved to an installable set of packages.\n\n Problem 1\n - Installation request for codeclimate/php-test-reporter 0.3.x-dev -> satisfiable by codeclimate/php-test-reporter[0.3.x-dev].\n - codeclimate/php-test-reporter 0.3.x-dev requires ext-curl * -> the requested PHP extension curl is missing from your system.\n Problem 2\n - Installation request for codeclimate/php-test-reporter dev-master -> satisfiable by codeclimate/php-test-reporter[dev-master].\n - codeclimate/php-test-reporter dev-master requires ext-curl * -> the requested PHP extension curl is missing from your system.\n Problem 3\n - Installation request for guzzle/guzzle v3.9.3 -> satisfiable by guzzle/guzzle[v3.9.3].\n - guzzle/guzzle v3.9.3 requires ext-curl * -> the requested PHP extension curl is missing from your system.\n Problem 4\n - guzzle/guzzle v3.9.3 requires ext-curl * -> the requested PHP extension curl is missing from your system.\n - satooshi/php-coveralls v1.1.0 requires guzzle/guzzle ^2.8 || ^3.0 -> satisfiable by guzzle/guzzle[v3.9.3].\n - Installation request for satooshi/php-coveralls v1.1.0 -> satisfiable by satooshi/php-coveralls[v1.1.0].","topic_id":19472},{"creator":{"public_name":"Anatol Meshalkin","id":167557,"is_tutor":false},"id":41228,"body":"the requested PHP extension curl is missing from your system - проверяю в терминале:\nsudo apt-get install curl\n[sudo] password for geek: \nЧтение списков пакетов… Готово\nПостроение дерева зависимостей \nЧтение информации о состоянии… Готово\nУже установлен пакет curl самой новой версии (7.58.0-2ubuntu3.3).\nСледующие пакеты устанавливались автоматически и больше не требуются:\nТо есть curl установлен, а он на него жалуется, почему-бы это?","topic_id":19472},{"creator":{"public_name":"Anatol Meshalkin","id":167557,"is_tutor":false},"id":41230,"body":"Loading composer repositories with package information Installing dependencies (including require-dev) from lock file Your requirements could not be resolved to an installable set of packages","topic_id":19472},{"creator":{"public_name":"Александр О.","id":61806,"is_tutor":false},"id":41210,"body":"Надо просто выполнить команду (запустить исполняемый файл): `bin/php-package`.","topic_id":19472}],"communitable":{"parent_entity_name":null,"parent_entity_url":null,"entity_name":"Автозагрузка","entity_url":null,"active":true}}],"lesson":{"exercise":null,"units":[{"id":2130,"name":"theory","url":"/courses/php-setup-environment/lessons/composer-autoload/theory_unit"},{"id":2542,"name":"quiz","url":"/courses/php-setup-environment/lessons/composer-autoload/quiz_unit"}],"links":[],"ordered_units":[{"id":2130,"name":"theory","url":"/courses/php-setup-environment/lessons/composer-autoload/theory_unit"},{"id":2542,"name":"quiz","url":"/courses/php-setup-environment/lessons/composer-autoload/quiz_unit"}],"id":1028,"slug":"composer-autoload","state":"approved","name":"Автозагрузка","course_order":470,"goal":"Разбираемся, как работает автозагрузка файлов в Composer","self_study":"1. Добавьте файл _Runner.php_ в автозагрузку в секцию _files_\n1. Измените ранее созданный файл _index.php_ в корне проекта вне директории _src_. Он должен выглядеть так:\n\n ```php\n <?php\n\n require_once __DIR__ . '/vendor/autoload.php';\n\n // Файл не включается напрямую\n // Он загрузится автоматически благодаря автозагрузке\n use Hexlet\\Php\\Runner;\n\n print_r(Runner\\run());\n ```\n\n1. Запустите файл _index.php_ на выполнение из корня проекта:\n\n ```bash\n php index.php\n # ['TAYLOR', 'ABIGAIL', '']\n ```\n","theory_video_provider":null,"theory_video_uid":null,"theory":"## Пространства имен\n\nЛюбой современный PHP-код вызывается с указанием пространства имен. Не важно, о каком коде идет речь — это может быть вызов кода из файла в соседней директории или из установленной зависимости. Это касается любой библиотеки, включая те, которые пишем мы сами. По этой причине нужно как-то выбрать имя пространства имен.\n\nИмя пакета отображается в имени пространства имен таким образом — `Dependency\\Injection`, где дефис заменяется на обратный слеш `\\`, а каждое слово начинается с заглавной буквы.\n\nК сожалению, пространства имен в языке появились не сразу, поэтому PHP позволяет создавать файловую структуру и структуру пространств имен независимо. Кроме того, в разных пакетах есть разные способы именования файлов, формирования самих имен пакетов, организации файлов внутри пакета. По этой причине мы старались использовать в [php-package](https://github.com/hexlet-boilerplates/php-package) самые распространенные практики, которые максимально похожи на то, как все организовано в других языках:\n\n* Пакет именуется в стиле _kebab-case_\n* Каждый пакет может выставлять наружу только одно пространство имен, что снижает риск пересечения с другими пакетами и позволяет легко определить принадлежность пространства имен к пакету. В терминах стандарта PSR-4 такое пространство имен называется _vendor namespace_\n* Пространства имен именуются в стиле [StudlyCaps](https://en.wikipedia.org/wiki/Studly_caps) и напрямую отображаются на файловую систему. Единственное исключение — это корневое пространство имен, которое получается путем трансформации имени пакета\n* Исходный код проекта находится в папке _src_, а тесты — в директории _tests_\n\nЧто касается именования файлов: что бы ни хранилось внутри, придерживайтесь именования в стиле _StudlyCaps_. На практике такие названия выглядят так: `MySuperFile.php`.\n\n## Автозагрузка\n\nВ предыдущем уроке мы создали файл _src/Runner.php_. Мы попытались запустить функции, которые он содержит — например, подключить соответствующий неймспейс в файл _index.php_. В итоге все завершилось с ошибкой.\n\nДело в том, что попытка использовать любой сторонний код или другие файлы, принадлежащие текущему пакету, требует загрузки этих файлов. Указание пространства имен никак не влияет на их загрузку.\n\nПо умолчанию считается, что если вы пытаетесь использовать какой-то код, то он уже загружен, используя `require` или `require_once`. Чисто технически, можно так и делать. Каждый раз, когда нам нужно использовать сторонний код, мы можем сначала делать его подгрузку через `require`. К счастью, этого делать не нужно. Более того, линтер ругается на попытку использовать `require` самостоятельно.\n\nДело в том, что Composer умеет автоматически загружать все необходимые файлы. Эта функциональность частично опирается на возможности автозагрузки самого PHP. Мы еще не проходили классы, но стандарт PSR-4 описывает автозагрузку именно классов. Грубо говоря, если правильно сконфигурировать автозагрузчик, то мы можем просто добавить новый файл с классом, и он загрузится автоматически. В случае с файлами, в которых есть только пространство имен и функции, все чуть сложнее. Каждый новый файл должен быть прописан внутри `composer.json`, только тогда он будет загружен. Вот как это выглядит:\n\n```json\n{\n \"name\": \"hexlet/pairs\",\n \"autoload\": {\n \"files\": [\n \"src/Pairs.php\",\n \"src/Lists.php\"\n ]\n }\n}\n```\n\nВ файл `composer.json` добавляется секция `autoload`. Внутрь этой секции добавляется еще одна секция `files`. Она в свою очередь содержит список файлов, которые надо загрузить. После обновления секции `autoload` нужно обязательно запускать команду `composer dump-autoload`. Она генерирует необходимый код в директории `vendor`, реализующий указанную загрузку. Затем остается только один шаг. Чтобы ваш код начал использовать все, что сделал Composer, необходимо в начале вашего кода прописать следующую строку:\n\n```php\n<?php\n\nrequire_once __DIR__ . '/../vendor/autoload.php';\n```\n\n\n\nКонкретный путь зависит от того, где находится директория `vendor`. При работе с локальным проектом Composer по умолчанию создаст директорию `vendor` в его корне. Но в случае глобальной установки пакета путь к директории `vendor` будет другим. Его можно узнать, выполнив команду в терминале:\n\n```bash\ncomposer global config vendor-dir\n# Changed current directory to /home/user/.config/composer\n# vendor\n```\n\nПосле установки сам пакет, его зависимости и файл `autoload.php` будут созданы именно в этой директории. Путь, который мы указали выше, уже не сработает, потому что при глобальной установке путь к директории `vendor` отличается. Чтобы файл `autoload.php` был найден в любом случае, используют следующую запись:\n\n```php\n<?php\n\n// Путь, который будет использован при глобальной установке пакета\n$autoloadPath1 = __DIR__ . '/../../../autoload.php';\n// Путь для локальной работы с проектом\n$autoloadPath2 = __DIR__ . '/../vendor/autoload.php';\n\nif (file_exists($autoloadPath1)) {\n require_once $autoloadPath1;\n} else {\n require_once $autoloadPath2;\n}\n```\n"},"lessonMember":null,"courseMember":null,"course":{"start_lesson":{"exercise":null,"units":[{"id":2134,"name":"theory","url":"/courses/php-setup-environment/lessons/intro/theory_unit"}],"links":[],"ordered_units":[{"id":2134,"name":"theory","url":"/courses/php-setup-environment/lessons/intro/theory_unit"}],"id":1030,"slug":"intro","state":"approved","name":"Введение","course_order":100,"goal":"Знакомимся с темой, целями и задачами курса","self_study":"1. Создайте репозиторий на GitHub [по этой инструкции](https://www.youtube.com/watch?v=ku3Mg_XCsAo) с именем _hexlet-php_ и файлом _README_\n1. Склонируйте его в домашнюю директорию на своем компьютере\n1. Добавьте в _README.md_ текст «Мой первый проект на Хекслете»\n1. Добавьте все изменения на GitHub\n","theory_video_provider":null,"theory_video_uid":null,"theory":"Хекслет построен так, что все задания выполняются прямо в браузере. Единственное исключение — это проекты, в которых вы отрабатываете навыки работы в настоящем окружении. Такой подход позволяет сосредоточиться на самой задаче, но рождает ложное ощущение понимания происходящего. Изучение программирования во многом связано с настройкой среды, причем для многих людей установка и конфигурирование сложнее, чем написание кода. Чем быстрее вы начнете возиться с кодом у себя на компьютере, тем быстрее пойдет прогресс — вы сможете писать реальные приложения и решать тестовые задания.\n\nКстати, о заданиях. Хекслет поддерживает [список тестовых заданий](https://github.com/Hexlet/ru-test-assignments) от разных компаний. Рекомендуем пользоваться им как ориентиром. Идеально, если еще во время обучения вы реализуете хотя бы одно или два задания у себя на GitHub. Во-первых, вы обретете уверенность и увидите, что уже кое-что можете. Во-вторых, работодатели смогут оценить ваш GitHub-аккаунт и посмотреть на код.\n\nВ этом курсе мы установим и настроим PHP. Кроме того, вы познакомитесь с пакетным менеджером Composer, научитесь подключать сторонние библиотеки и выкладывать свой код в публичный доступ.\n\nПеред началом курса проверьте свою операционную систему:\n\n* Используйте Ubuntu или macOS — они удобнее для разработки\n* Если вы используете Windows, настройте ее по [этой инструкции](https://docs.microsoft.com/ru-ru/windows/wsl/install-win10)\n\n## Окружение\n\nРабота с командной строкой, настройка окружения, установка языка и библиотек, взаимодействие с операционной системой – это значительная часть работы любого программиста на любом языке. От этого зависит эффективность отладки, способность самостоятельно справляться с проблемами и даже качество кода.\n\nКогда программист только приходит на первую работу, поначалу он пытается запустить проект локально у себя на компьютере. Чем больше и сложнее проект, тем больше разных знаний для этого понадобится: начиная от сетей, портов, IP-адресов и виртуализации с помощью Docker и заканчивая сборщиками (webpack). В некоторых компаниях подобная настройка может занимать дни, а в особо запущенных случаях — всю неделю. И это при условии достаточной квалификации программиста.\n\nИзучение экосистемы своего языка — это непрерывный и очень непредсказуемый процесс. Постоянно возникающие непонятные ошибки — это норма. Постоянное часовое гугление — это тоже норма. Через это проходили все, это необходимое зло. Почему такое происходит? В языках программирования все подчиняется определенным правилам. В отличие от них, экосистема — это зоопарк из огромного количества программ, операционных систем и особенностей железа, которые хитро переплетаются друг с другом. Все настолько индивидуально, что практически у каждого программиста своя уникальная ситуация.\n\nИменно поэтому существуют тысячи статей по установке PHP, и постоянно появляются новые. По комментариям к этим статьям можно заметить, что далеко не всем они помогают, пользователи сталкиваются с ошибками на каждом шагу.\n\nСо временем вы во всем разберетесь, и настройка окружения не будет казаться такой страшной. Единственное важное условие – не пытайтесь решать проблемы методом тыка, старайтесь разобраться в их причинах. Только так вы вырастете как разработчик.\n"},"id":157,"slug":"php-setup-environment","challenges_count":0,"name":"PHP: Настройка окружения","allow_indexing":true,"state":"approved","course_state":"finished","pricing_type":"paid","description":"На этом курсе вы изучите процесс настройки окружения для PHP. Вы узнаете о зависимостях и утилите Composer. В итоге научитесь создавать собственный пакет, который можно будет использовать как программу. Знания из этого курса помогут грамотно организовать локальное окружение и использовать хорошие практики по управлению кодом.","kind":"additional","updated_at":"2026-01-20T11:53:40.293Z","language":"php","duration_cache":9780,"skills":["Настраивать локальное окружение для запуска PHP-кода","Устанавливать библиотеки и подключать их в коде","Использовать программы, улучшающие качество кода"],"keywords":["зависимости","composer","автозагрузка"],"lessons_count":9,"cover":"https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6OTAwNSwicHVyIjoiYmxvYl9pZCJ9fQ==--c6a06a94f55a365f3d2c7a093a9f42c76a3ea6d7/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-setup-environment/lessons/composer-autoload/theory_unit","version":"143505ecd123087a8fdfa4acb7147980e9d23d76","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">Теория: Автозагрузка</h1><script type="application/ld+json">{"@context":"https://schema.org","@type":"LearningResource","name":"Автозагрузка","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"><h2 id="heading-2-1">Пространства имен</h2>
<p>Любой современный PHP-код вызывается с указанием пространства имен. Не важно, о каком коде идет речь — это может быть вызов кода из файла в соседней директории или из установленной зависимости. Это касается любой библиотеки, включая те, которые пишем мы сами. По этой причине нужно как-то выбрать имя пространства имен.</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">Dependency\Injection</code>, где дефис заменяется на обратный слеш <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">\</code>, а каждое слово начинается с заглавной буквы.</p>
<p>К сожалению, пространства имен в языке появились не сразу, поэтому PHP позволяет создавать файловую структуру и структуру пространств имен независимо. Кроме того, в разных пакетах есть разные способы именования файлов, формирования самих имен пакетов, организации файлов внутри пакета. По этой причине мы старались использовать в <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/hexlet-boilerplates/php-package" rel="noopener noreferrer" target="_blank">php-package</a> самые распространенные практики, которые максимально похожи на то, как все организовано в других языках:</p>
<ul>
<li>Пакет именуется в стиле <em>kebab-case</em></li>
<li>Каждый пакет может выставлять наружу только одно пространство имен, что снижает риск пересечения с другими пакетами и позволяет легко определить принадлежность пространства имен к пакету. В терминах стандарта PSR-4 такое пространство имен называется <em>vendor namespace</em></li>
<li>Пространства имен именуются в стиле <a style="text-decoration:underline" class="mantine-focus-auto m_849cf0da m_b6d8b162 mantine-Text-root mantine-Anchor-root" data-underline="hover" href="https://en.wikipedia.org/wiki/Studly_caps" rel="noopener noreferrer" target="_blank">StudlyCaps</a> и напрямую отображаются на файловую систему. Единственное исключение — это корневое пространство имен, которое получается путем трансформации имени пакета</li>
<li>Исходный код проекта находится в папке <em>src</em>, а тесты — в директории <em>tests</em></li>
</ul>
<p>Что касается именования файлов: что бы ни хранилось внутри, придерживайтесь именования в стиле <em>StudlyCaps</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">MySuperFile.php</code>.</p>
<h2 id="heading-2-2">Автозагрузка</h2>
<p>В предыдущем уроке мы создали файл <em>src/Runner.php</em>. Мы попытались запустить функции, которые он содержит — например, подключить соответствующий неймспейс в файл <em>index.php</em>. В итоге все завершилось с ошибкой.</p>
<p>Дело в том, что попытка использовать любой сторонний код или другие файлы, принадлежащие текущему пакету, требует загрузки этих файлов. Указание пространства имен никак не влияет на их загрузку.</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">require</code> или <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">require_once</code>. Чисто технически, можно так и делать. Каждый раз, когда нам нужно использовать сторонний код, мы можем сначала делать его подгрузку через <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">require</code>. К счастью, этого делать не нужно. Более того, линтер ругается на попытку использовать <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">require</code> самостоятельно.</p>
<p>Дело в том, что Composer умеет автоматически загружать все необходимые файлы. Эта функциональность частично опирается на возможности автозагрузки самого PHP. Мы еще не проходили классы, но стандарт PSR-4 описывает автозагрузку именно классов. Грубо говоря, если правильно сконфигурировать автозагрузчик, то мы можем просто добавить новый файл с классом, и он загрузится автоматически. В случае с файлами, в которых есть только пространство имен и функции, все чуть сложнее. Каждый новый файл должен быть прописан внутри <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">composer.json</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">{
"name": "hexlet/pairs",
"autoload": {
"files": [
"src/Pairs.php",
"src/Lists.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>В файл <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">composer.json</code> добавляется секция <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">autoload</code>. Внутрь этой секции добавляется еще одна секция <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">files</code>. Она в свою очередь содержит список файлов, которые надо загрузить. После обновления секции <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">autoload</code> нужно обязательно запускать команду <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">composer dump-autoload</code>. Она генерирует необходимый код в директории <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">vendor</code>, реализующий указанную загрузку. Затем остается только один шаг. Чтобы ваш код начал использовать все, что сделал Composer, необходимо в начале вашего кода прописать следующую строку:</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
require_once __DIR__ . '/../vendor/autoload.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><img style="--image-object-fit:contain;width:auto" class="m_9e117634 mantine-Image-root" src="/rails/active_storage/blobs/proxy/eyJfcmFpbHMiOnsiZGF0YSI6OTAxNCwicHVyIjoiYmxvYl9pZCJ9fQ==--9ff5527db8ffce5d8c7cbcf0c525925fddad2ebd/autoload.png" alt="Автозагрузка" loading="lazy"/></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">vendor</code>. При работе с локальным проектом Composer по умолчанию создаст директорию <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">vendor</code> в его корне. Но в случае глобальной установки пакета путь к директории <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">vendor</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">composer global config vendor-dir
# Changed current directory to /home/user/.config/composer
# vendor</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">autoload.php</code> будут созданы именно в этой директории. Путь, который мы указали выше, уже не сработает, потому что при глобальной установке путь к директории <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">vendor</code> отличается. Чтобы файл <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">autoload.php</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"><?php
// Путь, который будет использован при глобальной установке пакета
$autoloadPath1 = __DIR__ . '/../../../autoload.php';
// Путь для локальной работы с проектом
$autoloadPath2 = __DIR__ . '/../vendor/autoload.php';
if (file_exists($autoloadPath1)) {
require_once $autoloadPath1;
} else {
require_once $autoloadPath2;
}</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></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-setup-environment/lessons/composer-autoload/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 / 9</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-setup-environment/lessons/composer-autoload/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-D8AK0-_C.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-DOv3_-Z_.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>