{"id":345674,"date":"2023-02-20T03:00:25","date_gmt":"2023-02-20T03:00:25","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=345674"},"modified":"-0001-11-30T00:00:00","modified_gmt":"2023-02-20T03:00:25","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=345674","title":{"rendered":"<span>CMS, CMF \u2026 CMG (Content management generator)<\/span>"},"content":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-1\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0438\u0434\u0435\u044f <strong>CMG<\/strong> (Content management generator) \u2014 \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0432 Runtime \u0442\u043e, \u0447\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 \u0432\u0438\u0434\u0435 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e PHP \u043a\u043e\u0434\u0430.<br \/>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/fd\/ff\/ck\/fdffck9jbx07xfqneofhmdbblzu.png\" data-src=\"https:\/\/habrastorage.org\/webt\/fd\/ff\/ck\/fdffck9jbx07xfqneofhmdbblzu.png\"\/><\/p>\n<p><a name=\"habracut\"><\/a>  <\/p>\n<h2 id=\"vvedenie\">\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435<\/h2>\n<p>  <\/p>\n<p>\u041a\u0430\u0436\u0434\u044b\u0439 \u0441\u0430\u0439\u0442 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u0437 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432: <\/p>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041c\u0430\u0440\u0448\u0440\u0443\u0442\u044b<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<p>\u0421\u043b\u0443\u0436\u0430\u0442 \u0434\u043b\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0441\u043a\u0440\u0438\u043f\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0433\u043e \u0430\u0434\u0440\u0435\u0441\u0430. \u0422\u0435\u043a\u0443\u0449\u0438\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043a \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0446\u0438\u0438 \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u043e\u0439: <\/p>\n<p>  <\/p>\n<ol>\n<li>\u0417\u0430\u0434\u0430\u044e\u0442\u0441\u044f \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u043e\u0432 \u0432 \u0444\u0430\u0439\u043b\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a.<\/li>\n<li>\u0412\u0441\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u043f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0432 \u0444\u0430\u0439\u043b index.php \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0444\u0430\u0439\u043b\u0430 <a href=\"https:\/\/ru.wikipedia.org\/wiki\/.htaccess\" rel=\"nofollow noopener noreferrer\">.htaccess<\/a><br \/> \n<pre><code class=\"plaintext\"># Send Requests To Front Controller... RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^ index.php [L]<\/code><\/pre>\n<\/li>\n<li>\u0421\u043a\u0440\u0438\u043f\u0442 \u0447\u0438\u0442\u0430\u0435\u0442 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u043d\u0443\u0436\u043d\u044b\u0439 \u043c\u0430\u0440\u0448\u0440\u0443\u0442<\/li>\n<\/ol>\n<p>  <\/p>\n<p>\u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0432\u044b\u0437\u043e\u0432 \u0441\u043a\u0440\u0438\u043f\u0442\u0430 index.php \u044f\u0432\u043d\u043e \u043b\u0438\u0448\u043d\u0438\u0439, \u0442\u0430\u043a \u043a\u0430\u043a \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0446\u0438\u044f \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430 \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0432 \u0444\u0430\u0439\u043b\u0435 .htaccess<\/p>\n<\/div><\/div>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u0421\u0435\u0440\u0432\u0438\u0441\u044b<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<p>\u0421\u043b\u0443\u0436\u0430\u0442 \u0434\u043b\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0442\u0440\u0435\u0431\u0443\u0435\u043c\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439: \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u0411\u0414, \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u041a\u0415\u0428\u0435\u043c, \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u0448\u0430\u0431\u043b\u043e\u043d\u0438\u0437\u0430\u0442\u043e\u0440\u043e\u043c. \u0424\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0441\u0435\u0440\u0432\u0438\u0441 \u2014 \u044d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0435\u0442 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430 \u0434\u043b\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u0441\u0430\u0439\u0442\u0430. \u0414\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <a href=\"https:\/\/www.php.net\/manual\/ru\/book.reflection.php\" rel=\"nofollow noopener noreferrer\">Reflection API<\/a>. \u0422.\u0435. \u043f\u0440\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0435 \u043a\u0430\u043a\u043e\u0433\u043e-\u0442\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u043f\u0438\u0441\u043e\u043a \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u0435\u0433\u043e \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0430 \u0438 \u0435\u0441\u043b\u0438 \u0442\u0430\u043c \u0443\u043a\u0430\u0437\u0430\u043d\u044b \u0434\u0440\u0443\u0433\u0438\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u044b, \u0442\u043e \u043e\u043d\u0438 \u0442\u0443\u0442 \u0436\u0435 \u0441\u043e\u0437\u0434\u0430\u044e\u0442\u0441\u044f \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442\u0441\u044f \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430. \u0421\u0435\u0440\u0432\u0438\u0441 \u0437\u0430\u0434\u0430\u0451\u0442\u0441\u044f \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u043c \u0434\u043b\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0432 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u0445. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c\u0441\u044f \u043f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 (\u0440\u0430\u0437\u0432\u0435 \u0447\u0442\u043e \u0431\u0443\u0434\u0443\u0442 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u044b \u043d\u043e\u0432\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441).<\/p>\n<p>  <\/p>\n<p>\u041d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 <a href=\"https:\/\/www.php.net\/manual\/ru\/book.reflection.php\" rel=\"nofollow noopener noreferrer\">Reflection API<\/a> \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043a\u043e\u0434 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432. \u0412 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0435\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0432 Runtime \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u043e\u0432, \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0441\u0434\u0435\u043b\u0430\u043d\u043e \u043f\u0440\u0438 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432.<\/p>\n<\/div><\/div>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041f\u043e\u0441\u0440\u0435\u0434\u043d\u0438\u043a\u0438<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<p>\u041f\u043e\u0441\u0440\u0435\u0434\u043d\u0438\u043a\u0438 \u0441\u043b\u0443\u0436\u0430\u0442 \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0434\u043e \u0442\u043e\u0433\u043e \u043a\u0430\u043a \u043e\u043d \u043f\u0440\u0438\u0434\u0451\u0442 \u0432 \u0441\u043a\u0440\u0438\u043f\u0442 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u043f\u043e\u0441\u043b\u0435 \u0435\u0451 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 <a href=\"https:\/\/www.php.net\/manual\/ru\/book.reflection.php\" rel=\"nofollow noopener noreferrer\">Reflection API<\/a> \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c\u0438.<br \/>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/3j\/f1\/s9\/3jf1s9x4-vrlact6qz4illqu-iq.png\" data-src=\"https:\/\/habrastorage.org\/webt\/3j\/f1\/s9\/3jf1s9x4-vrlact6qz4illqu-iq.png\"\/><br \/>  \u041c\u043e\u0436\u043d\u043e \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c php-\u043a\u043e\u0434 \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0431\u0443\u0434\u0443\u0442 \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u043d\u044b \u0432\u044b\u0437\u043e\u0432\u044b \u0432\u0441\u0435\u0445 \u043f\u043e\u0441\u0440\u0435\u0434\u043d\u0438\u043a\u043e\u0432 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0432\u044b\u0437\u043e\u0432 \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0441\u043a\u0440\u0438\u043f\u0442\u0430 \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b.<\/p>\n<\/div><\/div>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u044b<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<p>\u0421\u043b\u0443\u0436\u0430\u0442 \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b. \u0414\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <a href=\"https:\/\/www.php.net\/manual\/ru\/book.reflection.php\" rel=\"nofollow noopener noreferrer\">Reflection API<\/a>. \u0422.\u0435. \u043f\u0440\u0438 \u0432\u044b\u0437\u043e\u0432\u0435 \u043a\u0430\u043a\u043e\u0433\u043e-\u0442\u043e \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u043f\u0438\u0441\u043e\u043a \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u0435\u0433\u043e \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0430 \u0438 \u0435\u0441\u043b\u0438 \u0442\u0430\u043c \u0443\u043a\u0430\u0437\u0430\u043d\u044b \u0441\u0435\u0440\u0432\u0438\u0441\u044b, \u0442\u043e \u043e\u043d\u0438 \u0442\u0443\u0442 \u0436\u0435 \u0441\u043e\u0437\u0434\u0430\u044e\u0442\u0441\u044f \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442\u0441\u044f \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430.<\/p>\n<p>  <\/p>\n<p>\u041d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 <a href=\"https:\/\/www.php.net\/manual\/ru\/book.reflection.php\" rel=\"nofollow noopener noreferrer\">Reflection API<\/a> \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043a\u043e\u0434 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u043e\u0432. \u0412 \u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043d\u0435\u0442 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u0432 Runtime \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0442\u044c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u043e\u0432, \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0441\u0434\u0435\u043b\u0430\u043d\u043e \u043f\u0440\u0438 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430.<\/p>\n<\/div><\/div>\n<p>  <\/p>\n<p>\u041a\u0430\u043a \u0432\u0438\u0434\u043d\u043e \u0438\u0437 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 \u0421\u0435\u0440\u0432\u0438\u0441\u0430\u043c\u0438, \u041f\u043e\u0441\u0440\u0435\u0434\u043d\u0438\u043a\u0430\u043c\u0438 \u0438 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430\u043c\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <a href=\"https:\/\/www.php.net\/manual\/ru\/book.reflection.php\" rel=\"nofollow noopener noreferrer\">Reflection API<\/a>, \u0430 \u0437\u043d\u0430\u0447\u0438\u0442, \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0432 \u043a\u043e\u0434 \u0441\u0430\u0439\u0442\u0430, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0432\u044b\u0437\u043e\u0432\u044b \u044d\u0442\u043e\u0433\u043e API. \u041c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0446\u0438\u044e \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438 \u0438\u0437 \u043a\u043e\u0434\u0430 PHP \u0432 \u0444\u0430\u0439\u043b <a href=\"https:\/\/ru.wikipedia.org\/wiki\/.htaccess\" rel=\"nofollow noopener noreferrer\">.htaccess<\/a>.<\/p>\n<p>  <\/p>\n<h2 id=\"shema-raboty\">\u0421\u0445\u0435\u043c\u0430 \u0440\u0430\u0431\u043e\u0442\u044b<\/h2>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u043e\u0432\u043e\u0439 \u0431\u0430\u0437\u044b \u0441\u0430\u0439\u0442\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0437\u043d\u0430\u0442\u044c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430. \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0441\u0430\u0439\u0442\u0430 \u0437\u0430\u0434\u0430\u044e\u0442\u0441\u044f \u0432 \u0432\u0438\u0434\u0435 \u0434\u0435\u0440\u0435\u0432\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a, \u0433\u0434\u0435 \u043a\u0430\u0436\u0434\u044b\u0439 \u043b\u0438\u0441\u0442 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0434\u043d\u0438\u043c \u0438\u0437 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u0442\u0438\u043f\u043e\u0432:<\/p>\n<p>  <\/p>\n<ul>\n<li><strong>\u0421\u0430\u0439\u0442<\/strong> \u2014 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439 \u0443\u0437\u0435\u043b. \u0422\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d.<\/li>\n<li><strong>\u0414\u043e\u043c\u0435\u043d<\/strong> \u2014 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0438\u043c\u044f \u0445\u043e\u0441\u0442\u0430 \u0434\u043e\u043c\u0435\u043d\u0430<\/li>\n<li><strong>\u041f\u0443\u0442\u044c<\/strong> \u2014 \u0447\u0430\u0441\u0442\u044c \u043c\u0430\u0441\u043a\u0438 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430<\/li>\n<li><strong>\u041c\u0430\u0440\u0448\u0440\u0443\u0442<\/strong> \u2014 \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0441\u0430\u043c \u043c\u0430\u0440\u0448\u0440\u0443\u0442.<br \/>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/ms\/ad\/67\/msad67558up_y-llnte8dkxvt_e.png\" data-src=\"https:\/\/habrastorage.org\/webt\/ms\/ad\/67\/msad67558up_y-llnte8dkxvt_e.png\"\/><br \/>  \u0412\u044b\u0448\u0435 \u043d\u0430 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0435 \u0432 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u0445 \u0437\u0430\u0434\u0430\u043d\u044b \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0434\u043e\u043c\u0435\u043d\u044b \u0438 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u044b:<\/li>\n<li>host1.ru\/<\/li>\n<li>host1.ru\/favicon.ico<\/li>\n<li>host2.ru\/<\/li>\n<li>host2.ru\/forum<\/li>\n<li>host2.ru\/forum\/edit<\/li>\n<li>host2.ru\/forum\/view\/$id<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u041a\u0430\u0436\u0434\u044b\u0439 \u0443\u0437\u0435\u043b \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 (\u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c) \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b:<\/p>\n<p>  <\/p>\n<ul>\n<li><strong>\u0421\u043f\u0438\u0441\u043e\u043a \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432<\/strong> \u2014 \u043e\u0431\u0449\u0438\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u0434\u043b\u044f \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430 \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u0442\u0441\u044f, \u043d\u0430\u0447\u0438\u043d\u0430\u044f \u0441 \u043b\u0438\u0441\u0442\u0430 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430. \u041a\u0430\u0436\u0434\u044b\u0439 \u0441\u0435\u0440\u0432\u0438\u0441 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u0440\u0430\u0437. \u0422.\u0435. \u0435\u0441\u043b\u0438 \u0434\u043b\u044f \u043e\u0434\u043d\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0431\u0443\u0434\u0435\u0442 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d \u043a\u043b\u0430\u0441\u0441 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0432 \u0443\u0437\u043b\u0435 <strong>\u0421\u0430\u0439\u0442<\/strong> \u0438 <strong>\u0414\u043e\u043c\u0435\u043d<\/strong>, \u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u0437\u044f\u0442 \u0442\u043e\u0442 \u043a\u043b\u0430\u0441\u0441, \u0447\u0442\u043e \u0443\u043a\u0430\u0437\u0430\u043d \u0432 <strong>\u0414\u043e\u043c\u0435\u043d\u0435<\/strong>, \u0442\u0430\u043a \u043a\u0430\u043a \u043e\u043d \u0431\u043b\u0438\u0436\u0435 \u043a \u043b\u0438\u0441\u0442\u0443 <strong>\u041c\u0430\u0440\u0448\u0440\u0443\u0442<\/strong>.<\/li>\n<li><strong>\u041f\u043e\u0441\u0440\u0435\u0434\u043d\u0438\u043a\u0438<\/strong> \u2014 \u043f\u043e\u0441\u0440\u0435\u0434\u043d\u0438\u043a\u0438 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u044e\u0442\u0441\u044f \u0432 \u043e\u0434\u043d\u0443 \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u043d\u0430\u0447\u0438\u043d\u0430\u044f \u043e\u0442 <strong>\u0421\u0430\u0439\u0442\u0430<\/strong>. \u041c\u043e\u0436\u043d\u043e \u0437\u0430\u0434\u0430\u0442\u044c \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u044b \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043f\u043e\u0441\u0440\u0435\u0434\u043d\u0438\u043a\u0430 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435, \u0435\u0441\u043b\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0447\u0442\u043e\u0431\u044b \u043e\u043d\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u043b\u0438\u0441\u044c \u0432 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0439 \u043f\u043e\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438.<\/li>\n<li><strong>\u041a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440<\/strong> \u2014 \u043a\u043b\u0430\u0441\u0441 \u0438 \u043c\u0435\u0442\u043e\u0434 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430 \u0437\u0430\u0434\u0430\u0451\u0442\u0441\u044f \u0432 <strong>\u041c\u0430\u0440\u0448\u0440\u0443\u0442\u0435<\/strong><\/li>\n<li><strong>\u0422\u0438\u043f \u0437\u0430\u043f\u0440\u043e\u0441\u0430<\/strong> (GET, POST, HEAD \u0438\u043b\u0438 \u0438\u0445 \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0446\u0438\u044f). \u0422\u0438\u043f \u0431\u0435\u0440\u0435\u0442\u0441\u044f \u0438\u0437 \u0442\u043e\u0433\u043e \u043b\u0438\u0441\u0442\u0430, \u0447\u0442\u043e \u0431\u043b\u0438\u0436\u0435 \u043a <strong>\u041c\u0430\u0440\u0448\u0440\u0443\u0442\u0443<\/strong> \u0438 \u0435\u0441\u043b\u0438 \u043e\u043d \u0443\u043a\u0430\u0437\u0430\u043d. \u0415\u0441\u043b\u0438 \u043d\u0435 \u0443\u043a\u0430\u0437\u0430\u043d, \u0442\u043e \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 = GET.<\/li>\n<\/ul>\n<p>  <\/p>\n<p>\u0422\u0430\u043a\u0436\u0435 \u0432 \u043a\u0430\u0436\u0434\u044b\u0439 \u043b\u0438\u0441\u0442 \u0434\u0435\u0440\u0435\u0432\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c <strong>\u0413\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440<\/strong>. \u0413\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u043d\u0430\u0441\u043b\u0435\u0434\u0443\u0435\u0442\u0441\u044f \u043e\u0442 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430 \u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 <strong>onGenerate<\/strong> \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c. \u0412 \u044d\u0442\u043e\u043c \u043c\u0435\u0442\u043e\u0434\u0435 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0437\u0430\u0434\u0430\u0442\u044c \u0441\u0432\u043e\u0439 \u043a\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u0434\u0435\u0440\u0435\u0432\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a. \u0422.\u0435. \u0432 \u043c\u0435\u0442\u043e\u0434\u0435 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u0432\u043e\u0438 \u0443\u0437\u043b\u044b \u0432 \u0434\u0435\u0440\u0435\u0432\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a. \u042d\u0442\u0438 \u043d\u043e\u0432\u044b\u0435 \u0443\u0437\u043b\u044b \u0431\u0443\u0434\u0443\u0442 \u0443\u0447\u0442\u0435\u043d\u044b \u043f\u0440\u0438 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u043e\u0432\u043e\u0439 \u0431\u0430\u0437\u044b \u0441\u0430\u0439\u0442\u0430.<br \/>  \u0422.\u0435. \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0441\u0432\u043e\u0438 \u043c\u043e\u0434\u0443\u043b\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c.<\/p>\n<p>  <\/p>\n<h2 id=\"primery\">\u041f\u0440\u0438\u043c\u0435\u0440\u044b<\/h2>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u0442\u0435\u0445 \u043a\u0442\u043e \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043f\u043e\u043d\u044f\u043b, \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u0441 \u043a\u043e\u0434\u043e\u043c.<\/p>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041f\u0440\u043e\u0441\u0442\u043e\u0439 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u0431\u0435\u0437 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u0432 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0435<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<p>\u0421\u0430\u0439\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043e\u0434\u0438\u043d \u043c\u0430\u0440\u0448\u0440\u0443\u0442 <strong>s-cmg1.ru\/test<\/strong><br \/>  \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0438 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0441\u0430\u0439\u0442. \u0417\u0430\u043f\u0440\u043e\u0441 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 \u0432 \u0444\u0430\u0439\u043b <strong>.htaccess<\/strong> \u0438 \u043f\u043e\u0441\u043b\u0435 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043a\u043e\u0434 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u0430, \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u043e\u0442\u0432\u0435\u0442\u0430 \u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0442\u0440\u0435\u0439\u0442 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b. \u0422\u0440\u0435\u0439\u0442 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440.<\/p>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"php\">class SiteExample1 extends SiteGenerator {     \/\/ \u041a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440     public function __construct()     {         parent::__construct();         \/\/ \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0434\u043e\u043c\u0435\u043d         $this->addDomain('s-cmg1.ru', function (DomainGenerator $domain) {             \/\/ \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u0443\u0442\u044c             $domain->addPath('test', null, function (PathGenerator $path) {                 \/\/ \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043c\u0430\u0440\u0448\u0440\u0443\u0442                 $path->addRoute(new RouteGeneratorController(TestController::class));             });         });     } }<\/code><\/pre>\n<\/div><\/div>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u0424\u0430\u0439\u043b .htaccess<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"plaintext\">    #-- s-cmg1.ru\/test     RewriteCond %{HTTP_HOST} s-cmg1.ru     RewriteCond %{REQUEST_METHOD} GET     RewriteRule ^test$ \/@\/s-cmg1.ru\/f684f00a.php [L]<\/code><\/pre>\n<\/div><\/div>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041a\u043e\u0434 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u0430, \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u043e\u0442\u0432\u0435\u0442\u0430 \u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<p>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0438 \u0435\u0433\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432 \u043c\u0435\u0442\u043e\u0434\u0435 <strong>run<\/strong>. \u0422\u0430\u043a\u0436\u0435 \u0434\u0430\u043d\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043c\u0435\u0442\u043e\u0434\u044b \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432, \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0445 \u0434\u043b\u044f \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430.<\/p>\n<p>  <\/p>\n<pre><code class=\"php\">\/\/ \u041f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430 class AppRoute {     \/\/ \u0422\u0440\u0435\u0439\u0442 \u0441 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 onRequest \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u043e\u0442\u0432\u0435\u0442     use \\Shasoft\\SamoyedCMG\\AppRouteOnRequest;     \/\/ \u0421\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0435 \u0421\u0435\u0440\u0432\u0438\u0441 => \u0418\u043c\u044f \u043a\u043b\u0430\u0441\u0441\u0430     protected static array $serviceName2Classname = [         \"Shasoft\\\\SamoyedCMG\\\\Service\\\\IRequest\" => \"Shasoft_SamoyedCMG_Service_Request\",         \"Shasoft\\\\SamoyedCMG\\\\Service\\\\IService\" => \"Shasoft_SamoyedCMG_Service_Request\",         IRoute::class => \"Shasoft_SamoyedCMG_Route\"     ];     \/\/ \u0421\u043f\u0438\u0441\u043e\u043a \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432     protected static array $instances = [];     \/\/ \u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u0435\u0440\u0432\u0438\u0441 (\u0438\u043b\u0438 false \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0435\u0433\u043e \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u044f)     static public function getServiceSafe(string $serviceName): IService|false     {         \/\/ \u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0441\u0435\u0440\u0432\u0438\u0441\u0430\/\u0438\u043c\u044f \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 => \u0438\u043c\u044f \u043a\u043b\u0430\u0441\u0441\u0430         if (array_key_exists($serviceName, self::$serviceName2Classname)) {             \/\/ \u0418\u043c\u044f \u043c\u0435\u0442\u043e\u0434\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f             $methodName = self::$serviceName2Classname[$serviceName];             \/\/ \u0410 \u043c\u043e\u0436\u0435\u0442 \u0441\u0435\u0440\u0432\u0438\u0441 \u0443\u0436\u0435 \u0441\u043e\u0437\u0434\u0430\u043d?             if (array_key_exists($methodName, self::$instances)) {                 \/\/ \u0412\u0435\u0440\u043d\u0443\u0442\u044c \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0439 \u0440\u0430\u043d\u0435\u0435 \u0441\u0435\u0440\u0432\u0438\u0441                 return self::$instances[$methodName];             } else {                 \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f                 if (method_exists(__CLASS__, $methodName)) {                     \/\/ \u0412\u044b\u0437\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434 \u043f\u043e \u0438\u043c\u0435\u043d\u0438 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u0430                     $ret = self::$methodName();                     \/\/ \u0417\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0435\u0440\u0432\u0438\u0441 \u0432 \u041a\u0415\u0428                     self::$instances[$methodName] = $ret;                     \/\/ \u0412\u0435\u0440\u043d\u0443\u0442\u044c \u0441\u0435\u0440\u0432\u0438\u0441                     return $ret;                 }             }         }         \/\/ \u0418\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435         return false;     }     \/\/ \u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u0435\u0440\u0432\u0438\u0441     static public function getService(string $serviceName): IService     {         $ret = self::getServiceSafe($serviceName);         \/\/ \u0415\u0441\u043b\u0438 \u0441\u0435\u0440\u0432\u0438\u0441 \u043d\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d         if ($ret === false) {             \/\/ \u0418\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435             throw new \\Exception(\"\u0421\u0435\u0440\u0432\u0438\u0441\u0430 \" . $serviceName . \" \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442!\");         }         return $ret;     }     \/\/ \u0421\u0435\u0440\u0432\u0438\u0441 \u0441 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0435\u0439 \u043e \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0435     static protected function Shasoft_SamoyedCMG_Route(): \\Shasoft\\SamoyedCMG\\Route     {         return new \\Shasoft\\SamoyedCMG\\Route([]);     }     \/\/ Shasoft\\SamoyedCMG\\Service\\Request     static protected function Shasoft_SamoyedCMG_Service_Request(): \\Shasoft\\SamoyedCMG\\Service\\Request     {         return new \\Shasoft\\SamoyedCMG\\Service\\Request();     }     \/\/ \u0417\u0430\u043f\u0443\u0441\u043a     static public function run()     {         \/\/--------------------------------------------------------------------------------         try {             \/\/ \u0417\u0430\u043f\u0440\u043e\u0441             $request = self::getService(IRequest::class);             \/\/ \u0421\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043e\u0442\u0432\u0435\u0442             $response = self::onRequest($request);             \/\/ \u0415\u0441\u043b\u0438 \u043e\u0442\u0432\u0435\u0442 \u0432 \u0432\u0438\u0434\u0435 \u0441\u0442\u0440\u043e\u043a\u0438             if (is_string($response)) {                 \/\/ \u0442\u043e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u0443 \u0432 HTTP \u043e\u0442\u0432\u0435\u0442                 $response = new Response($response);                 $response->prepare($request->getSymfonyRequest());             }             \/\/ \u041e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u043e\u0442\u0432\u0435\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e             $response->send();         } catch (\\Exception $e) {             s_dump_error('\u0418\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 ' . get_class($e), $e);         } catch (\\Error $e) {             s_dump_error('\u041e\u0448\u0438\u0431\u043a\u0430 ' . get_class($e), $e);         }     } } \/\/ \u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 AppRoute::run();<\/code><\/pre>\n<\/div><\/div>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u0422\u0440\u0435\u0439\u0442 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u043e\u043c<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"php\">trait AppRouteOnRequest {     \/\/ \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u0430     static protected function onRequest(IRequest $request): Response     {         \/\/ \u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440         $controller = new \\Shasoft\\SExample\\Controller\\TestController();         \/\/ \u0412\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043c\u0435\u0442\u043e\u0434 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0435\u0440\u0430         $response = $controller->run( );         \/\/ \u0415\u0441\u043b\u0438 \u0432\u0435\u0440\u043d\u0443\u043b\u0438 null         if (is_null($response)) {             $response = '&lt;h3>&lt;abbr style=\"color:red\" title=\"\u041a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u0432\u0435\u0440\u043d\u0443\u043b null\">null&lt;\/abbr>&lt;\/h3>';         }         \/\/ \u0415\u0441\u043b\u0438 \u043e\u0442\u0432\u0435\u0442 \u0432 \u0432\u0438\u0434\u0435 \u0441\u0442\u0440\u043e\u043a\u0438         if (is_string($response)) {             \/\/ \u0442\u043e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u0443 \u0432 HTTP \u043e\u0442\u0432\u0435\u0442             $response = new Response($response);             $response->prepare($request->getSymfonyRequest());         }         \/\/ \u0412\u0435\u0440\u043d\u0443\u0442\u044c \u043e\u0442\u0432\u0435\u0442         return $response;     } }<\/code><\/pre>\n<\/div><\/div>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"php\">class TestController {     \/\/ \u041a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440     public function __construct()     {     }     \/\/ \u0417\u0430\u043f\u0443\u0441\u043a     public function run()     {         \/\/ \u0412\u044b\u0432\u043e\u0434 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e \u0448\u0430\u0431\u043b\u043e\u043d\u0430         return '\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430. \u041c\u0430\u0440\u0448\u0440\u0443\u0442 \u0431\u0435\u0437 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432. &lt;b>' . microtime() . '&lt;\/b>';     } }<\/code><\/pre>\n<\/div><\/div>\n<\/div><\/div>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041f\u0440\u0438\u043c\u0435\u0440 \u0434\u043b\u044f \u0434\u0435\u0440\u0435\u0432\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u0432\u044b\u0448\u0435 (+\u043c\u0430\u0440\u0448\u0440\u0443\u0442 \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u043c $id)<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"php\">class SiteExample0 extends SiteGenerator {     \/\/ \u041a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440     public function __construct()     {         parent::__construct();         \/\/ \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0434\u043e\u043c\u0435\u043d\u044b         $this             ->addDomain('host1.ru', function (DomainGenerator $domain) {                 \/\/ \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043c\u0430\u0440\u0448\u0440\u0443\u0442 host1.ru\/                 $domain->addRoute(new RouteGeneratorController(TestController::class));                 \/\/ \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u0443\u0442\u044c                 $domain->addPath('\/favicon.ico', null, function (PathGenerator $path) {                     \/\/ \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043c\u0430\u0440\u0448\u0440\u0443\u0442 host1.ru\/favicon.ico                     $path->addRoute(new RouteGeneratorController(TestController::class));                 });             })->addDomain('host2.ru', function (DomainGenerator $domain) {                 \/\/ \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043c\u0430\u0440\u0448\u0440\u0443\u0442 host2.ru\/                 $domain->addRoute(new RouteGeneratorController(TestController::class));                 \/\/ \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u0443\u0442\u044c                 $domain->addPath('forum', null, function (PathGenerator $path) {                     \/\/ \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043c\u0430\u0440\u0448\u0440\u0443\u0442 host2.ru\/forum                     $path->addRoute(new RouteGeneratorController(TestController::class));                     \/\/ \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u0443\u0442\u044c                     $path->addPath('edit', null, function (PathGenerator $path) {                         \/\/ \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043c\u0430\u0440\u0448\u0440\u0443\u0442 host2.ru\/forum\/edit                         $path                             ->addRoute(new RouteGeneratorController(TestController::class))                             ->setHttpMethod('GET|POST');                     });                     \/\/ \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u0443\u0442\u044c                     $path->addPath('view\/$id', null, function (PathGenerator $path) {                         \/\/ \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043c\u0430\u0440\u0448\u0440\u0443\u0442 host2.ru\/forum\/view\/$id                         $path->addRoute(new RouteGeneratorController(TestController::class));                     });                 });             });     } }<\/code><\/pre>\n<\/div><\/div>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">*\u0424\u0430\u0439\u043b .htaccess<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<p>\u0412 \u0444\u0430\u0439\u043b\u0435 .htaccess \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f RegExp \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 $id \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u0435\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432 \u0441\u043a\u0440\u0438\u043f\u0442 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438.<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">    #-- host1.ru\/     RewriteCond %{HTTP_HOST} host1.ru     RewriteCond %{REQUEST_METHOD} GET     RewriteRule ^$ \/@\/host1.ru\/164b9b11.php [L]      #-- host1.ru\/favicon.ico     RewriteCond %{HTTP_HOST} host1.ru     RewriteCond %{REQUEST_METHOD} GET     RewriteRule ^favicon.ico$ \/@\/host1.ru\/3bc202d3.php [L]      #-- host2.ru\/     RewriteCond %{HTTP_HOST} host2.ru     RewriteCond %{REQUEST_METHOD} GET     RewriteRule ^$ \/@\/host2.ru\/164b9b11.php [L]      #-- host2.ru\/forum     RewriteCond %{HTTP_HOST} host2.ru     RewriteCond %{REQUEST_METHOD} GET     RewriteRule ^forum$ \/@\/host2.ru\/473c6874.php [L]      #-- host2.ru\/forum\/edit     RewriteCond %{HTTP_HOST} host2.ru     RewriteCond %{REQUEST_METHOD} GET|POST     RewriteRule ^forum\/edit$ \/@\/host2.ru\/79849227.php [L]      #-- host2.ru\/forum\/view\/$id     RewriteCond %{HTTP_HOST} host2.ru     RewriteCond %{REQUEST_METHOD} GET     RewriteRule ^forum\/view\/([^\/]+)$ \/@\/host2.ru\/dcacf4a6.php?Z5a50cb9c0=$1 [QSA,L]<\/code><\/pre>\n<\/div><\/div>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">*\u0422\u0440\u0435\u0439\u0442 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u043e\u043c<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<p>\u0412 \u0442\u0440\u0435\u0439\u0442\u0435 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 <strong>$id<\/strong> \u0438\u0437 \u0441\u043a\u0440\u0438\u043f\u0442\u0430 \u0432 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440<\/p>\n<p>  <\/p>\n<pre><code class=\"php\">trait AppRouteOnRequest {     \/\/ \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u0430     static protected function onRequest(IRequest $request): Response     {         \/\/ \u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440         $controller = new \\Shasoft\\SExample\\Controller\\TestArgController();         \/\/ \u0412\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043c\u0435\u0442\u043e\u0434 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0435\u0440\u0430         $response = $controller->run(self::$argsRoute['id']);         \/\/ \u0415\u0441\u043b\u0438 \u0432\u0435\u0440\u043d\u0443\u043b\u0438 null         if (is_null($response)) {             $response = '&lt;h3>&lt;abbr style=\"color:red\" title=\"\u041a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u0432\u0435\u0440\u043d\u0443\u043b null\">null&lt;\/abbr>&lt;\/h3>';         }         \/\/ \u0415\u0441\u043b\u0438 \u043e\u0442\u0432\u0435\u0442 \u0432 \u0432\u0438\u0434\u0435 \u0441\u0442\u0440\u043e\u043a\u0438         if (is_string($response)) {             \/\/ \u0442\u043e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u0443 \u0432 HTTP \u043e\u0442\u0432\u0435\u0442             $response = new Response($response);             $response->prepare($request->getSymfonyRequest());         }         \/\/ \u0412\u0435\u0440\u043d\u0443\u0442\u044c \u043e\u0442\u0432\u0435\u0442         return $response;     } }<\/code><\/pre>\n<\/div><\/div>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">*\u041a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<p>\u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430 <strong>$id<\/strong>.<\/p>\n<p>  <\/p>\n<pre><code class=\"php\">class TestArgController {     \/\/ \u041a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440     public function __construct()     {     }     \/\/ \u0417\u0430\u043f\u0443\u0441\u043a     static public function run($id)     {         \/\/ \u0412\u044b\u0432\u043e\u0434 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e \u0448\u0430\u0431\u043b\u043e\u043d\u0430         return '\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430. \u041c\u0430\u0440\u0448\u0440\u0443\u0442 \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u043c $id = [&lt;b>' . $id . '&lt;\/>] &lt;b>' . microtime() . '&lt;\/b>';     } }<\/code><\/pre>\n<\/div><\/div>\n<\/div><\/div>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041f\u0440\u043e\u0441\u0442\u043e\u0439 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u0431\u0435\u0437 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u0432 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0435 + \u043f\u043e\u0441\u0440\u0435\u0434\u043d\u0438\u043a\u0438<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<p>\u0421\u0430\u0439\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043e\u0434\u0438\u043d \u043c\u0430\u0440\u0448\u0440\u0443\u0442 <strong>s-cmg2.ru\/test<\/strong><\/p>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"php\">class SiteExample2 extends SiteGenerator {     \/\/ \u041a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440     public function __construct()     {         parent::__construct();         \/\/ \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0434\u043e\u043c\u0435\u043d         $this->addDomain('s-cmg2.ru', function (DomainGenerator $domain) {             $this->addMiddleware(TestMiddleware::class, ['role' => 'admin']);             \/\/ \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u0443\u0442\u044c             $domain->addPath('test', null, function (PathGenerator $path) {                 $this->addMiddleware(TestMiddleware2::class, ['x' => 1]);                 \/\/ \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043c\u0430\u0440\u0448\u0440\u0443\u0442                 $path->addRoute(new RouteGeneratorController(TestController::class));             });         });     } }<\/code><\/pre>\n<\/div><\/div>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u0424\u0430\u0439\u043b .htaccess<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"plaintext\">    #-- s-cmg2.ru\/test     RewriteCond %{HTTP_HOST} s-cmg2.ru     RewriteCond %{REQUEST_METHOD} GET     RewriteRule ^test$ \/@\/s-cmg2.ru\/f684f00a.php [L]<\/code><\/pre>\n<\/div><\/div>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">*\u041a\u043e\u0434 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u0430, \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u043e\u0442\u0432\u0435\u0442\u0430 \u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<p>\u0412\u043e\u0442 \u0442\u0443\u0442 \u043f\u043e\u044f\u0432\u0438\u043b\u0438\u0441\u044c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u043f\u043e \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044e \u0441 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u043e\u043c \u0431\u0435\u0437 \u043f\u043e\u0441\u0440\u0435\u0434\u043d\u0438\u043a\u043e\u0432. \u041f\u043e\u044f\u0432\u0438\u043b\u0441\u044f \u043c\u0435\u0442\u043e\u0434 <strong>onMiddlewares<\/strong> \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432\u044b\u0437\u043e\u0432 \u043f\u043e\u0441\u0440\u0435\u0434\u043d\u0438\u043a\u043e\u0432 + \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043c\u0435\u0442\u043e\u0434 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b <strong>onRequest<\/strong>. \u041f\u0440\u0438 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0438 \u043f\u043e\u0441\u0440\u0435\u0434\u043d\u0438\u043a\u043e\u0432 \u0432\u043c\u0435\u0441\u0442\u043e \u043c\u0435\u0442\u043e\u0434\u0430 <strong>onMiddlewares<\/strong> \u0441\u0440\u0430\u0437\u0443 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043c\u0435\u0442\u043e\u0434 <strong>onRequest<\/strong>.<\/p>\n<p>  <\/p>\n<pre><code class=\"php\">class AppRoute {     \/\/ \u0422\u0440\u0435\u0439\u0442 \u0441 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 onRequest \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u043e\u0442\u0432\u0435\u0442     use \\Shasoft\\SamoyedCMG\\AppRouteOnRequest;     \/\/ \u0421\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0435 \u0421\u0435\u0440\u0432\u0438\u0441 => \u0418\u043c\u044f \u043a\u043b\u0430\u0441\u0441\u0430     protected static array $serviceName2Classname = [         \"Shasoft\\\\SamoyedCMG\\\\Service\\\\IRequest\" => \"Shasoft_SamoyedCMG_Service_Request\",         \"Shasoft\\\\SamoyedCMG\\\\Service\\\\IService\" => \"Shasoft_SamoyedCMG_Service_Request\",         IRoute::class => \"Shasoft_SamoyedCMG_Route\"     ];     \/\/ \u0421\u043f\u0438\u0441\u043e\u043a \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432     protected static array $instances = [];     \/\/ \u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u0435\u0440\u0432\u0438\u0441 (\u0438\u043b\u0438 false \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0435\u0433\u043e \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u044f)     static public function getServiceSafe(string $serviceName): IService|false     {         \/\/ \u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0441\u0435\u0440\u0432\u0438\u0441\u0430\/\u0438\u043c\u044f \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 => \u0438\u043c\u044f \u043a\u043b\u0430\u0441\u0441\u0430         if (array_key_exists($serviceName, self::$serviceName2Classname)) {             \/\/ \u0418\u043c\u044f \u043c\u0435\u0442\u043e\u0434\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f             $methodName = self::$serviceName2Classname[$serviceName];             \/\/ \u0410 \u043c\u043e\u0436\u0435\u0442 \u0441\u0435\u0440\u0432\u0438\u0441 \u0443\u0436\u0435 \u0441\u043e\u0437\u0434\u0430\u043d?             if (array_key_exists($methodName, self::$instances)) {                 \/\/ \u0412\u0435\u0440\u043d\u0443\u0442\u044c \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0439 \u0440\u0430\u043d\u0435\u0435 \u0441\u0435\u0440\u0432\u0438\u0441                 return self::$instances[$methodName];             } else {                 \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f                 if (method_exists(__CLASS__, $methodName)) {                     \/\/ \u0412\u044b\u0437\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434 \u043f\u043e \u0438\u043c\u0435\u043d\u0438 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u0430                     $ret = self::$methodName();                     \/\/ \u0417\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0435\u0440\u0432\u0438\u0441 \u0432 \u041a\u0415\u0428                     self::$instances[$methodName] = $ret;                     \/\/ \u0412\u0435\u0440\u043d\u0443\u0442\u044c \u0441\u0435\u0440\u0432\u0438\u0441                     return $ret;                 }             }         }         \/\/ \u0418\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435         return false;     }     \/\/ \u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u0435\u0440\u0432\u0438\u0441     static public function getService(string $serviceName): IService     {         $ret = self::getServiceSafe($serviceName);         \/\/ \u0415\u0441\u043b\u0438 \u0441\u0435\u0440\u0432\u0438\u0441 \u043d\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d         if ($ret === false) {             \/\/ \u0418\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435             throw new \\Exception(\"\u0421\u0435\u0440\u0432\u0438\u0441\u0430 \" . $serviceName . \" \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442!\");         }         return $ret;     }     \/\/ \u0421\u0435\u0440\u0432\u0438\u0441 \u0441 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0435\u0439 \u043e \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0435     static protected function Shasoft_SamoyedCMG_Route(): \\Shasoft\\SamoyedCMG\\Route     {         return new \\Shasoft\\SamoyedCMG\\Route([]);     }     \/\/ Shasoft\\SamoyedCMG\\Service\\Request     static protected function Shasoft_SamoyedCMG_Service_Request(): \\Shasoft\\SamoyedCMG\\Service\\Request     {         return new \\Shasoft\\SamoyedCMG\\Service\\Request();     }     \/\/ \u041f\u043e\u0441\u0440\u0435\u0434\u043d\u0438\u043a\u0438     static protected function onMiddlewares(IRequest $request): Response     {         \/\/ \u0412\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043f\u043e\u0441\u0440\u0435\u0434\u043d\u0438\u043a Shasoft\\SExample\\Middleware\\TestMiddleware         return (new \\Shasoft\\SExample\\Middleware\\TestMiddleware())->handle($request, function ($request) {             \/\/ \u0412\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043f\u043e\u0441\u0440\u0435\u0434\u043d\u0438\u043a Shasoft\\SExample\\Middleware\\TestMiddleware2             return (new \\Shasoft\\SExample\\Middleware\\TestMiddleware2())->handle($request, function ($request) {                 \/\/ \u0412\u044b\u0437\u0432\u0430\u0442\u044c \u043e\u0441\u043d\u043e\u0432\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438                 $response = self::onRequest($request);                 \/\/ \u0415\u0441\u043b\u0438 \u043e\u0442\u0432\u0435\u0442 \u0432 \u0432\u0438\u0434\u0435 \u0441\u0442\u0440\u043e\u043a\u0438                 if (is_string($response)) {                     \/\/ \u0442\u043e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u0443 \u0432 HTTP \u043e\u0442\u0432\u0435\u0442                     $response = new Response($response);                     $response->prepare($request->getSymfonyRequest());                 }                 return $response;             }, array(                 'x' => 1,             ));         }, array(             'role' => 'admin',         ));     }     \/\/ \u0417\u0430\u043f\u0443\u0441\u043a     static public function run()     {         \/\/--------------------------------------------------------------------------------         try {             \/\/ \u0417\u0430\u043f\u0440\u043e\u0441             $request = self::getService(IRequest::class);             \/\/ \u0421\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043e\u0442\u0432\u0435\u0442             $response = self::onMiddlewares($request);             \/\/ \u041e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u043e\u0442\u0432\u0435\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e             $response->send();         } catch (\\Exception $e) {             s_dump_error('\u0418\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 ' . get_class($e), $e);         } catch (\\Error $e) {             s_dump_error('\u041e\u0448\u0438\u0431\u043a\u0430 ' . get_class($e), $e);         }     } } \/\/ \u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 AppRoute::run();<\/code><\/pre>\n<\/div><\/div>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u0422\u0440\u0435\u0439\u0442 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u043e\u043c<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"php\">trait AppRouteOnRequest {     \/\/ \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u0430     static protected function onRequest(IRequest $request): Response     {         \/\/ \u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440         $controller = new \\Shasoft\\SExample\\Controller\\TestController();         \/\/ \u0412\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043c\u0435\u0442\u043e\u0434 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0435\u0440\u0430         $response = $controller->run( );         \/\/ \u0415\u0441\u043b\u0438 \u0432\u0435\u0440\u043d\u0443\u043b\u0438 null         if (is_null($response)) {             $response = '&lt;h3>&lt;abbr style=\"color:red\" title=\"\u041a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u0432\u0435\u0440\u043d\u0443\u043b null\">null&lt;\/abbr>&lt;\/h3>';         }         \/\/ \u0415\u0441\u043b\u0438 \u043e\u0442\u0432\u0435\u0442 \u0432 \u0432\u0438\u0434\u0435 \u0441\u0442\u0440\u043e\u043a\u0438         if (is_string($response)) {             \/\/ \u0442\u043e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u0443 \u0432 HTTP \u043e\u0442\u0432\u0435\u0442             $response = new Response($response);             $response->prepare($request->getSymfonyRequest());         }         \/\/ \u0412\u0435\u0440\u043d\u0443\u0442\u044c \u043e\u0442\u0432\u0435\u0442         return $response;     } }<\/code><\/pre>\n<\/div><\/div>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"php\">class TestController {     \/\/ \u041a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440     public function __construct()     {     }     \/\/ \u0417\u0430\u043f\u0443\u0441\u043a     public function run()     {         \/\/ \u0412\u044b\u0432\u043e\u0434 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e \u0448\u0430\u0431\u043b\u043e\u043d\u0430         return '\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430. \u041c\u0430\u0440\u0448\u0440\u0443\u0442 \u0431\u0435\u0437 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432. &lt;b>' . microtime() . '&lt;\/b>';     } }<\/code><\/pre>\n<\/div><\/div>\n<\/div><\/div>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u0430 \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 IPath<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<p>\u0421\u0435\u0440\u0432\u0438\u0441 IPath \u0441\u043b\u0443\u0436\u0438\u0442 \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0439 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430 (\u0438\u043c\u0435\u043d\u043d\u043e \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430(!), \u0430 \u043d\u0435 \u0441\u0430\u0439\u0442\u0430 \u0432 \u0446\u0435\u043b\u043e\u043c. \u0422.\u0435. \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0434\u0430\u0442\u044c \u0441\u0432\u043e\u0438 \u043f\u0443\u0442\u0438).<\/p>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u0430<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<p>\u0412\u0441\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043e\u0442 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 <strong>IService<\/strong><\/p>\n<p>  <\/p>\n<pre><code class=\"php\">\/\/ \u041f\u0443\u0442\u0438 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430 interface IPath extends IService {     \/\/ \u0414\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f \u0441\u0430\u0439\u0442\u0430     public function site(?string $pathX = null): string;     \/\/ \u0414\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f \u043f\u0430\u043a\u0435\u0442\u043e\u0432     public function vendor(?string $pathX = null): string;     \/\/ \u0414\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f \u043f\u0430\u043a\u0435\u0442\u0430     public function package(string $packageName, ?string $pathX = null): string;     \/\/ \u0412\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f     public function temp(?string $pathX = null): string;     \/\/ \u0414\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f \u0441\u0430\u0439\u0442\u0430 \u0432 \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u043e\u0439 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438     public function public_html(?string $pathX = null): string;     \/\/ \u0425\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435     public function storage(?string $pathX = null): string; }<\/code><\/pre>\n<\/div><\/div>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u0413\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u0441\u0435\u0440\u0432\u0438\u0441\u0430<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<p>\u0413\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u0441\u043e\u0437\u0434\u0430\u0451\u0442 \u043a\u043b\u0430\u0441\u0441 \u0438\u0437 \u0448\u0430\u0431\u043b\u043e\u043d\u0430. \u0412\u0430\u0436\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442: \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0441\u043b\u0438 \u043f\u0440\u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0435 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 IPath \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430 \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435. \u0422.\u0435. \u043f\u0440\u0438 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e\u043c \u0432\u044b\u0437\u043e\u0432\u0435 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043d\u0435 \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0434\u0435\u0442. \u042d\u0442\u043e \u0432\u0430\u0436\u043d\u043e, \u0442\u0430\u043a \u043a\u0430\u043a \u0435\u0441\u043b\u0438 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u043f\u0440\u043e\u0438\u0437\u0432\u0435\u043b \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f, \u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0443\u0441\u043a \u0432\u0441\u0435\u0445 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u0432, \u0434\u0430\u0436\u0435 \u0442\u0435\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0443\u0436\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u043b\u0438\u0441\u044c. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u0442\u0441\u043b\u0435\u0436\u0438\u0432\u0430\u0442\u044c \u0447\u0442\u043e\u0431\u044b \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u043d\u0435 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043b \u0442\u043e, \u0447\u0442\u043e \u043e\u043d \u0443\u0436\u0435 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043b \u0440\u0430\u043d\u0435\u0435.<br \/>  \u0422.\u0435. \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u043a\u043b\u0430\u0441\u0441\u0430 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u0435\u0442\u043e\u0434\u0430 <strong>setService<\/strong>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 TRUE \u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0441\u043b\u0438 \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435.<\/p>\n<p>  <\/p>\n<pre><code class=\"php\">class ServiceGeneratorPath extends ServiceCodeGenerator {     \/\/ \u041a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440     public function __construct(protected string $dataKey)     {         parent::__construct();     }     \/\/ \u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f     protected function onGenerate(ApiMake $api): void     {         \/\/ \u0418\u043c\u044f \u043a\u043b\u0430\u0441\u0441\u0430         $classname = str_replace('IPath', 'Path', IPath::class);         \/\/ \u0413\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d \u0434\u043b\u044f \u0443\u0437\u043b\u0430 \u0421\u0430\u0439\u0442?         if ($api->hasType('site')) {             $host = null;         } else {             $host = $api->parentObject()->domain()->host();         }         \/\/ \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043a\u043b\u0430\u0441\u0441 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0438 \u0435\u0441\u043b\u0438 \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432         if ($api->setService(IPath::class, $classname)) {             \/\/ \u0422\u043e \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043b\u0430\u0441\u0441 \u043f\u043e \u0448\u0430\u0431\u043b\u043e\u043d\u0443             $api->addScript(__DIR__ . '\/..\/..\/..\/twig\/Service\/Path.php.twig', [                 'host' => $host,                 'classname' => $classname,                 'dataKey' => $this->dataKey             ]);         }     } } <\/code><\/pre>\n<\/div><\/div>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">Twig \u0448\u0430\u0431\u043b\u043e\u043d \u0441\u0435\u0440\u0432\u0438\u0441\u0430<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"plaintext\">&lt;?php  {{ classname | namespace }}  use Shasoft\\Support\\File; use Shasoft\\SamoyedCMG\\Service\\IPath; \/\/ \u041f\u0443\u0442\u0438 class {{ classname | class }} implements IPath {     \/\/ \u0411\u0430\u0437\u043e\u0432\u0430\u044f \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f     protected string $basepath;     \/\/ \u041a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440     public function __construct()     {         \/\/ \u0411\u0430\u0437\u043e\u0432\u0430\u044f \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f \u0441\u0430\u0439\u0442\u0430         $this->basepath = File::normalize(__DIR__ . \"\/..\", true);     }     \/\/ \u0414\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f \u0441\u0430\u0439\u0442\u0430     public function site(?string $pathX = null): string     {         $ret = $this->basepath;         if (!is_null($pathX)) {             $ret .= '\/' . $pathX;         }         return $ret;     }     \/\/ \u0414\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f \u043f\u0430\u043a\u0435\u0442\u043e\u0432     public function vendor(?string $pathX = null): string     {         $ret = $this->site('vendor');         $ret = '';         if (!is_null($pathX)) {             $ret .= '\/' . $pathX;         }         return $ret;     }     \/\/ \u0414\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f \u043f\u0430\u043a\u0435\u0442\u0430     public function package(string $packageName, ?string $pathX = null): string     {         $ret = $this->vendor($packageName);         if (!is_null($pathX)) {             $ret .= '\/' . $pathX;         }         return $ret;     }     \/\/ \u0412\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f     public function temp(?string $pathX = null): string     {         $ret = $this->site('~.temp\/{{ dataKey }}');         if (!is_null($pathX)) {             $ret .= '\/' . $pathX;         }         return $ret;     }     \/\/ \u0414\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f \u0441\u0430\u0439\u0442\u0430 \u0432 \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u043e\u0439 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438     public function public_html(?string $pathX = null): string     { {% if host %}         $ret = $this->site('public_html\/@\/{{ host }}');         if (!is_null($pathX)) {             $ret .= '\/' . $pathX;         }         return $ret; {% else %}         throw new \\Exception('\u0413\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d \u0434\u043b\u044f \u0443\u0437\u043b\u0430 \u0421\u0430\u0439\u0442 \u043f\u043e\u044d\u0442\u043c\u043e\u0443 \u0434\u0430\u043d\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043d\u0435\u0434\u043e\u0441\u0442\u0443\u043f\u043d\u0430!');         return ''; {% endif %}     }     \/\/ \u0424\u0430\u0439\u043b\u043e\u0432\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435     public function storage(?string $pathX = null): string     {         $ret = $this->site('storage\/{{ dataKey }}');         if (!is_null($pathX)) {             $ret .= '\/' . $pathX;         }         return $ret;     } }<\/code><\/pre>\n<\/div><\/div>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u0421\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 IPath<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"php\">class Path implements IPath {     \/\/ \u0411\u0430\u0437\u043e\u0432\u0430\u044f \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f     protected string $basepath;     \/\/ \u041a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440     public function __construct()     {         \/\/ \u0411\u0430\u0437\u043e\u0432\u0430\u044f \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f \u0441\u0430\u0439\u0442\u0430         $this->basepath = File::normalize(__DIR__ . \"\/..\", true);     }     \/\/ \u0414\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f \u0441\u0430\u0439\u0442\u0430     public function site(?string $pathX = null): string     {         $ret = $this->basepath;         if (!is_null($pathX)) {             $ret .= '\/' . $pathX;         }         return $ret;     }     \/\/ \u0414\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f \u043f\u0430\u043a\u0435\u0442\u043e\u0432     public function vendor(?string $pathX = null): string     {         $ret = $this->site('vendor');         $ret = '';         if (!is_null($pathX)) {             $ret .= '\/' . $pathX;         }         return $ret;     }     \/\/ \u0414\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f \u043f\u0430\u043a\u0435\u0442\u0430     public function package(string $packageName, ?string $pathX = null): string     {         $ret = $this->vendor($packageName);         if (!is_null($pathX)) {             $ret .= '\/' . $pathX;         }         return $ret;     }     \/\/ \u0412\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f     public function temp(?string $pathX = null): string     {         $ret = $this->site('~.temp\/demo3');         if (!is_null($pathX)) {             $ret .= '\/' . $pathX;         }         return $ret;     }     \/\/ \u0414\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f \u0441\u0430\u0439\u0442\u0430 \u0432 \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u043e\u0439 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438     public function public_html(?string $pathX = null): string     {         $ret = $this->site('public_html\/@\/s-cmg3.ru');         if (!is_null($pathX)) {             $ret .= '\/' . $pathX;         }         return $ret;     }     \/\/ \u0424\u0430\u0439\u043b\u043e\u0432\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435     public function storage(?string $pathX = null): string     {         $ret = $this->site('storage\/demo3');         if (!is_null($pathX)) {             $ret .= '\/' . $pathX;         }         return $ret;     } }<\/code><\/pre>\n<\/div><\/div>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"php\">class SiteExample3 extends SiteGenerator {     \/\/ \u041a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440     public function __construct()     {         parent::__construct();         \/\/ \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0434\u043e\u043c\u0435\u043d         $this->addDomain('s-cmg3.ru', function (DomainGenerator $domain) {             \/\/ \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 IPath             $domain->addGenerator(new ServiceGeneratorPath('demo3'));             \/\/ \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u0443\u0442\u044c             $domain->addPath('test', null, function (PathGenerator $path) {                 \/\/ \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043c\u0430\u0440\u0448\u0440\u0443\u0442                 $path->addRoute(new RouteGeneratorController(TestIPathController::class));             });         });     } }<\/code><\/pre>\n<\/div><\/div>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u0424\u0430\u0439\u043b .htaccess<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"plaintext\">    #-- s-cmg3.ru\/test     RewriteCond %{HTTP_HOST} s-cmg3.ru     RewriteCond %{REQUEST_METHOD} GET     RewriteRule ^test$ \/@\/s-cmg3.ru\/f684f00a.php [L]<\/code><\/pre>\n<\/div><\/div>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041a\u043e\u0434 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u0430, \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u043e\u0442\u0432\u0435\u0442\u0430 \u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<p>\u0412 \u0441\u043f\u0438\u0441\u043e\u043a \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432 \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0441\u044f \u043d\u043e\u0432\u044b\u0439 \u0441\u0435\u0440\u0432\u0438\u0441 IPath \u0432 \u0434\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u043a \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u043c.<\/p>\n<p>  <\/p>\n<pre><code class=\"php\">class AppRoute {     \/\/ \u0422\u0440\u0435\u0439\u0442 \u0441 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 onRequest \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u043e\u0442\u0432\u0435\u0442     use \\Shasoft\\SamoyedCMG\\AppRouteOnRequest;     \/\/ \u0421\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0435 \u0421\u0435\u0440\u0432\u0438\u0441 => \u0418\u043c\u044f \u043a\u043b\u0430\u0441\u0441\u0430     protected static array $serviceName2Classname = [         \"Shasoft\\\\SamoyedCMG\\\\Service\\\\IPath\" => \"Shasoft_SamoyedCMG_Service_Path\",         \"Shasoft\\\\SamoyedCMG\\\\Service\\\\IService\" => \"Shasoft_SamoyedCMG_Service_Path\",         \"Shasoft\\\\SamoyedCMG\\\\Service\\\\IRequest\" => \"Shasoft_SamoyedCMG_Service_Request\",         IRoute::class => \"Shasoft_SamoyedCMG_Route\"     ];     \/\/ \u0421\u043f\u0438\u0441\u043e\u043a \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432     protected static array $instances = [];     \/\/ \u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u0435\u0440\u0432\u0438\u0441 (\u0438\u043b\u0438 false \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0435\u0433\u043e \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u044f)     static public function getServiceSafe(string $serviceName): IService|false     {         \/\/ \u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0441\u0435\u0440\u0432\u0438\u0441\u0430\/\u0438\u043c\u044f \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 => \u0438\u043c\u044f \u043a\u043b\u0430\u0441\u0441\u0430         if (array_key_exists($serviceName, self::$serviceName2Classname)) {             \/\/ \u0418\u043c\u044f \u043c\u0435\u0442\u043e\u0434\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f             $methodName = self::$serviceName2Classname[$serviceName];             \/\/ \u0410 \u043c\u043e\u0436\u0435\u0442 \u0441\u0435\u0440\u0432\u0438\u0441 \u0443\u0436\u0435 \u0441\u043e\u0437\u0434\u0430\u043d?             if (array_key_exists($methodName, self::$instances)) {                 \/\/ \u0412\u0435\u0440\u043d\u0443\u0442\u044c \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0439 \u0440\u0430\u043d\u0435\u0435 \u0441\u0435\u0440\u0432\u0438\u0441                 return self::$instances[$methodName];             } else {                 \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f                 if (method_exists(__CLASS__, $methodName)) {                     \/\/ \u0412\u044b\u0437\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434 \u043f\u043e \u0438\u043c\u0435\u043d\u0438 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u0430                     $ret = self::$methodName();                     \/\/ \u0417\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0435\u0440\u0432\u0438\u0441 \u0432 \u041a\u0415\u0428                     self::$instances[$methodName] = $ret;                     \/\/ \u0412\u0435\u0440\u043d\u0443\u0442\u044c \u0441\u0435\u0440\u0432\u0438\u0441                     return $ret;                 }             }         }         \/\/ \u0418\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435         return false;     }     \/\/ \u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u0435\u0440\u0432\u0438\u0441     static public function getService(string $serviceName): IService     {         $ret = self::getServiceSafe($serviceName);         \/\/ \u0415\u0441\u043b\u0438 \u0441\u0435\u0440\u0432\u0438\u0441 \u043d\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d         if ($ret === false) {             \/\/ \u0418\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435             throw new \\Exception(\"\u0421\u0435\u0440\u0432\u0438\u0441\u0430 \" . $serviceName . \" \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442!\");         }         return $ret;     }     \/\/ \u0421\u0435\u0440\u0432\u0438\u0441 \u0441 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0435\u0439 \u043e \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0435     static protected function Shasoft_SamoyedCMG_Route(): \\Shasoft\\SamoyedCMG\\Route     {         return new \\Shasoft\\SamoyedCMG\\Route([]);     }     \/\/ Shasoft\\SamoyedCMG\\Service\\Path     static protected function Shasoft_SamoyedCMG_Service_Path(): \\Shasoft\\SamoyedCMG\\Service\\Path     {         return new \\Shasoft\\SamoyedCMG\\Service\\Path();     }     \/\/ Shasoft\\SamoyedCMG\\Service\\Request     static protected function Shasoft_SamoyedCMG_Service_Request(): \\Shasoft\\SamoyedCMG\\Service\\Request     {         return new \\Shasoft\\SamoyedCMG\\Service\\Request();     }     \/\/ \u0417\u0430\u043f\u0443\u0441\u043a     static public function run()     {         \/\/--------------------------------------------------------------------------------         try {             \/\/ \u0417\u0430\u043f\u0440\u043e\u0441             $request = self::getService(IRequest::class);             \/\/ \u0421\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043e\u0442\u0432\u0435\u0442             $response = self::onRequest($request);             \/\/ \u0415\u0441\u043b\u0438 \u043e\u0442\u0432\u0435\u0442 \u0432 \u0432\u0438\u0434\u0435 \u0441\u0442\u0440\u043e\u043a\u0438             if (is_string($response)) {                 \/\/ \u0442\u043e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u0443 \u0432 HTTP \u043e\u0442\u0432\u0435\u0442                 $response = new Response($response);                 $response->prepare($request->getSymfonyRequest());             }             \/\/ \u041e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u043e\u0442\u0432\u0435\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e             $response->send();         } catch (\\Exception $e) {             s_dump_error('\u0418\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 ' . get_class($e), $e);         } catch (\\Error $e) {             s_dump_error('\u041e\u0448\u0438\u0431\u043a\u0430 ' . get_class($e), $e);         }     } } \/\/ \u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 AppRoute::run();<\/code><\/pre>\n<\/div><\/div>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u0422\u0440\u0435\u0439\u0442 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u043e\u043c<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<p>\u041f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0430 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0432 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u043c\u043e\u0436\u043d\u043e \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440\u0435 \u043d\u0443\u0436\u043d\u044b\u0439 \u0441\u0435\u0440\u0432\u0438\u0441, \u043d\u043e \u0438 \u0432 \u043c\u0435\u0442\u043e\u0434\u0435 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430. \u042d\u0442\u043e \u0443\u0434\u043e\u0431\u043d\u043e \u0435\u0441\u043b\u0438 \u043c\u0435\u0442\u043e\u0434 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439.<\/p>\n<p>  <\/p>\n<pre><code class=\"php\">trait AppRouteOnRequest {     \/\/ \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u0430     static protected function onRequest(IRequest $request): Response     {         \/\/ \u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440         $controller = new \\Shasoft\\SExample\\Controller\\TestIPathController(\\Shasoft\\SamoyedCMG\\AppRoute::getService(\\Shasoft\\SamoyedCMG\\Service\\IPath::class));         \/\/ \u0412\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043c\u0435\u0442\u043e\u0434 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0435\u0440\u0430         $response = $controller->run( \\Shasoft\\SamoyedCMG\\AppRoute::getService(\\Shasoft\\SamoyedCMG\\Service\\IPath::class));         \/\/ \u0415\u0441\u043b\u0438 \u0432\u0435\u0440\u043d\u0443\u043b\u0438 null         if (is_null($response)) {             $response = '&lt;h3>&lt;abbr style=\"color:red\" title=\"\u041a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u0432\u0435\u0440\u043d\u0443\u043b null\">null&lt;\/abbr>&lt;\/h3>';         }         \/\/ \u0415\u0441\u043b\u0438 \u043e\u0442\u0432\u0435\u0442 \u0432 \u0432\u0438\u0434\u0435 \u0441\u0442\u0440\u043e\u043a\u0438         if (is_string($response)) {             \/\/ \u0442\u043e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u0443 \u0432 HTTP \u043e\u0442\u0432\u0435\u0442             $response = new Response($response);             $response->prepare($request->getSymfonyRequest());         }         \/\/ \u0412\u0435\u0440\u043d\u0443\u0442\u044c \u043e\u0442\u0432\u0435\u0442         return $response;     } }<\/code><\/pre>\n<\/div><\/div>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<p>\u0412 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0435 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c \u0441\u0435\u0440\u0432\u0438\u0441 \u043a\u0430\u043a \u0432 \u043a\u043e\u043d\u0442\u0441\u0440\u0443\u043a\u0442\u043e\u0440\u0435, \u0442\u0430\u043a \u0438 \u0432 \u043c\u0435\u0442\u043e\u0434\u0435 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430. \u042d\u0442\u043e \u0443\u0434\u043e\u0431\u043d\u043e \u0434\u043b\u044f \u0441\u043b\u0443\u0447\u0430\u044f \u0435\u0441\u043b\u0438 \u043c\u0435\u0442\u043e\u0434 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u0430 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439.<\/p>\n<p>  <\/p>\n<pre><code class=\"php\">class TestIPathController {     \/\/ \u041a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440     public function __construct(protected IPath $path)     {     }     \/\/ \u0417\u0430\u043f\u0443\u0441\u043a     public function run(IPath $path)     {         \/\/ \u0412\u044b\u0432\u043e\u0434 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e \u0448\u0430\u0431\u043b\u043e\u043d\u0430         return '\u0414\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f storage:&lt;br\/>' .             $this->path->storage() . '&lt;br\/>' .             $path->storage() . '&lt;br\/>' .             '&lt;b>' . microtime() . '&lt;\/b>';     } }<\/code><\/pre>\n<\/div><\/div>\n<\/div><\/div>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u0430 \u043a\u043e\u0434\u0430 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 ITwig (\u0441 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u043e\u0439 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u0430)<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<p>\u041d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u044b \u0442\u0440\u0435\u0431\u0443\u044e\u0442 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u0434\u043b\u044f \u0441\u0432\u043e\u0435\u0439 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438. \u041a \u043f\u0440\u0438\u043c\u0435\u0440\u0443 \u043a\u043b\u0430\u0441\u0441 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u0448\u0430\u0431\u043b\u043e\u043d\u0438\u0437\u0430\u0442\u043e\u0440\u0430 ITwig \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0443\u043a\u0430\u0437\u0430\u043d\u0438\u044f \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0439 \u0441 \u0448\u0430\u0431\u043b\u043e\u043d\u0430\u043c\u0438. \u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u0430 \u0440\u0435\u0448\u0430\u0435\u0442\u0441\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043c\u0435\u0442\u043e\u0434\u0430 <strong>tune<\/strong> \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0443 \u0432\u0441\u0435\u0445 \u043b\u0438\u0441\u0442\u043e\u0432 \u0432 \u0434\u0435\u0440\u0435\u0432\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a.<\/p>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u0430<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"php\">\/\/ \u0428\u0430\u0431\u043b\u043e\u043d\u0438\u0437\u0430\u0442\u043e\u0440 interface ITemplate extends IService {     \/\/ \u0421\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c     public function render(string $templateName, array $args = []): string; } \/\/ \u0428\u0430\u0431\u043b\u043e\u043d\u0438\u0437\u0430\u0442\u043e\u0440 Twig interface ITwig extends ITemplate { }<\/code><\/pre>\n<\/div><\/div>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u0413\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u0441\u0435\u0440\u0432\u0438\u0441\u0430<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"php\">class ServiceGeneratorTwig extends ServiceCodeGenerator {     \/\/ \u0412\u0441\u0435 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0430\u0432\u0430 \u0438\u043c\u0451\u043d     protected array $namespaces = [];     \/\/ \u041a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440     public function __construct()     {         parent::__construct();     }     \/\/ \u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f     protected function onGenerate(ApiMake $api): void     {         \/\/ \u0418\u043c\u044f \u043a\u043b\u0430\u0441\u0441\u0430         $classname = str_replace('ITwig', 'Twig', ITwig::class);         \/\/ \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043a\u043b\u0430\u0441\u0441 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0441\u0435\u0440\u0432\u0438\u0441\u0430         if ($api->setService(ITwig::class, $classname)) {             \/\/ \u0421\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043b\u0430\u0441\u0441 \u043f\u043e \u0448\u0430\u0431\u043b\u043e\u043d\u0443             $api->addScript(__DIR__ . '\/..\/twig\/Twig.php.twig', [                 'classname' => $classname,                 'namespaces' => $this->namespaces,                 'dev' => $api->isDev()             ]);         }     }     \/\/ \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e \u0438\u043c\u0451\u043d     public function addNamespace(string $name, string $path): static     {         \/\/ \u041d\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0443\u0442\u044c         $path = File::normalize($path, true);         \/\/ \u0415\u0441\u043b\u0438 \u0442\u0430\u043a\u043e\u0433\u043e \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0430 \u0438\u043c\u0451\u043d \u043d\u0435\u0442 \u0418\u041b\u0418 \u043f\u0443\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f         if (!array_key_exists($name, $this->namespaces) || $this->namespaces[$name] != $path) {             \/\/ \u0412\u043d\u0435\u0441\u0442\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435             $this->namespaces[$name] = $path;             \/\/ \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0444\u043b\u0430\u0433 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f             $this->setModify();         }         \/\/ \u0412\u0435\u0440\u043d\u0443\u0442\u044c \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u0441\u0435\u0431\u044f         return $this;     }     \/\/ \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u0430 \u0438\u043c\u0451\u043d     public function addNamespaces(array $namespaces): static     {         foreach ($namespaces as $name => $path) {             $this->addNamespace($name, $path);         }         \/\/ \u0412\u0435\u0440\u043d\u0443\u0442\u044c \u0443\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u0441\u0435\u0431\u044f         return $this;     } }<\/code><\/pre>\n<\/div><\/div>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">Twig \u0448\u0430\u0431\u043b\u043e\u043d \u0441\u0435\u0440\u0432\u0438\u0441\u0430<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"plaintext\">{{ classname | namespace }}  use Shasoft\\SamoyedCMG\\Service\\IPath; use Shasoft\\STwig\\ITwig; use Twig\\Environment; use Twig\\Loader\\FilesystemLoader;  \/\/ \u0428\u0430\u0431\u043b\u043e\u043d\u0438\u0437\u0430\u0442\u043e\u0440 Twig class {{ classname | class }} implements ITwig {     \/\/ \u0423\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u043e\u0431\u044a\u0435\u043a\u0442 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0448\u0430\u0431\u043b\u043e\u043d\u0430\u043c\u0438 Twig     protected ?Environment $_twig = null;     \/\/ \u041f\u0430\u043f\u043a\u0430 \u0441 \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c\u0438 \u0448\u0430\u0431\u043b\u043e\u043d\u0430\u043c\u0438     protected string $path;     \/\/ \u041a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440     public function __construct(IPath $path)     {         \/\/ \u0414\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f \u043a\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043e\u0442\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432         $this->path = $path->temp('twig');     }     \/\/ \u0412\u044b\u0432\u0435\u0441\u0442\u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435     public function render(string $templateName, array $args = []): string     {         \/\/ \u0415\u0441\u043b\u0438 \u0448\u0430\u0431\u043b\u043e\u043d\u0438\u0437\u0430\u0442\u043e\u0440 \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u043d         if( is_null($this->_twig) ) {             \/\/ \u0417\u0430\u0433\u0440\u0443\u0437\u0447\u0438\u043a \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432             $loader = new FilesystemLoader(); {% if namespaces %}             \/\/ \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432\u0441\u0435 \u043f\u0443\u0442\u0438 {% for name, path in namespaces %}             $loader->addPath( __DIR__ . '\/{{ path | relScript }}', '{{ name }}'); {% endfor %} {% endif %}             \/\/ \u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442 \u0448\u0430\u0431\u043b\u043e\u043d\u0438\u0437\u0430\u0442\u043e\u0440\u0430             $this->_twig = new Environment($loader, [                 \/\/ \u0414\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f \u043a\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043e\u0442\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432                 'cache' => $this->path,                 \/\/ \u0420\u0435\u0436\u0438\u043c \u043e\u0442\u043b\u0430\u0434\u043a\u0438                 'debug' => {{ dev | var_export }},             ]);         }         return $this->_twig->render($templateName, $args);     } }<\/code><\/pre>\n<\/div><\/div>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u0421\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 ITwig<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"php\">class Twig implements ITwig {     \/\/ \u0423\u043a\u0430\u0437\u0430\u0442\u0435\u043b\u044c \u043d\u0430 \u043e\u0431\u044a\u0435\u043a\u0442 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0448\u0430\u0431\u043b\u043e\u043d\u0430\u043c\u0438 Twig     protected ?Environment $_twig = null;     \/\/ \u041f\u0430\u043f\u043a\u0430 \u0441 \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c\u0438 \u0448\u0430\u0431\u043b\u043e\u043d\u0430\u043c\u0438     protected string $path;     \/\/ \u041a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440     public function __construct(IPath $path)     {         \/\/ \u0414\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f \u043a\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043e\u0442\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432         $this->path = $path->temp('twig');     }     \/\/ \u0412\u044b\u0432\u0435\u0441\u0442\u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435     public function render(string $templateName, array $args = []): string     {         \/\/ \u0415\u0441\u043b\u0438 \u0448\u0430\u0431\u043b\u043e\u043d\u0438\u0437\u0430\u0442\u043e\u0440 \u043d\u0435 \u0441\u043e\u0437\u0434\u0430\u043d         if (is_null($this->_twig)) {             \/\/ \u0417\u0430\u0433\u0440\u0443\u0437\u0447\u0438\u043a \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432             $loader = new FilesystemLoader();             \/\/ \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432\u0441\u0435 \u043f\u0443\u0442\u0438             $loader->addPath(__DIR__ . '\/..\/vendor\/shasoft\/s-examples\/@twig', 'demo4');             \/\/ \u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043e\u0431\u044a\u0435\u043a\u0442 \u0448\u0430\u0431\u043b\u043e\u043d\u0438\u0437\u0430\u0442\u043e\u0440\u0430             $this->_twig = new Environment($loader, [                 \/\/ \u0414\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f \u043a\u0435\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043e\u0442\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432                 'cache' => $this->path,                 \/\/ \u0420\u0435\u0436\u0438\u043c \u043e\u0442\u043b\u0430\u0434\u043a\u0438                 'debug' => true,             ]);         }         return $this->_twig->render($templateName, $args);     } }<\/code><\/pre>\n<\/div><\/div>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<p>\u0412 \u043c\u0435\u0442\u043e\u0434\u0435 <strong>tune<\/strong> \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0442\u0438\u043f \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u0430. \u0412 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u0433\u043e \u0432\u044b\u0437\u043e\u0432\u0430 \u0431\u0443\u0434\u0443\u0442 \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u044b \u0432\u0441\u0435 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u044b \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0435\u0441\u0442\u044c \u0432 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u043c \u0443\u0437\u043b\u0435 \u0438\u043b\u0438 \u0432 \u0432\u044b\u0448\u0435\u0441\u0442\u043e\u044f\u0449\u0438\u0445 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0445 \u0443\u0437\u043b\u0430\u0445. \u0412 \u0442\u0435\u043a\u0443\u0449\u0435\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0432 \u043c\u0435\u0442\u043e\u0434\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0432 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e \u0438\u043c\u0435\u043d \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432 + \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044f \u0441 \u0448\u0430\u0431\u043b\u043e\u043d\u0430\u043c\u0438.<\/p>\n<p>  <\/p>\n<pre><code class=\"php\">class SiteExample4 extends SiteGenerator {     \/\/ \u041a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440     public function __construct()     {         parent::__construct();         \/\/ \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 ITag         $this->addGenerator(new ServiceGeneratorTwig);         \/\/ \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0434\u043e\u043c\u0435\u043d         $this->addDomain('s-cmg4.ru', function (DomainGenerator $domain) {             $domain                 \/\/ \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 IPath                             ->addGenerator(new ServiceGeneratorPath('demo4'))                 \/\/ \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043c\u0430\u0440\u0448\u0440\u0443\u0442                 ->addRoute(new RouteGeneratorController(TestControllerTwig::class))                 \/\/ \u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u0430 \u0441\u0435\u0440\u0432\u0438\u0441\u0430 ITag                 ->tune(function (ServiceGeneratorTwig $twig) {                     \/\/ \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0432 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e \u0441 \u0448\u0430\u0431\u043b\u043e\u043d\u0430\u043c\u0438 \u0441 \u043f\u0440\u043e\u0441\u0442\u0440\u0430\u043d\u0441\u0442\u0432\u043e\u043c \u0438\u043c\u0435\u043d demo4                     $twig->addNamespace('demo4', __DIR__ . '\/..\/@twig');                 });         });     } }<\/code><\/pre>\n<\/div><\/div>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u0424\u0430\u0439\u043b .htaccess<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"plaintext\">    #-- s-cmg4.ru\/     RewriteCond %{HTTP_HOST} s-cmg4.ru     RewriteCond %{REQUEST_METHOD} GET     RewriteRule ^$ \/@\/s-cmg4.ru\/164b9b11.php [L]<\/code><\/pre>\n<\/div><\/div>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041a\u043e\u0434 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u0430, \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0438 \u043e\u0442\u0432\u0435\u0442\u0430 \u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u043b\u0441\u044f \u0441\u0435\u0440\u0432\u0438\u0441 ITemplate \u0438 ITwig. \u041f\u0440\u0438 \u044d\u0442\u043e\u043c \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0432\u044b\u0441\u0442\u0443\u043f\u0430\u0435\u0442 \u043e\u0434\u0438\u043d \u0438 \u0442\u043e\u0442 \u0436\u0435 \u043a\u043b\u0430\u0441\u0441. \u0418 \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u043d \u043e\u0434\u0438\u043d \u043e\u0431\u044a\u0435\u043a\u0442 \u0434\u0430\u043d\u043d\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430.<\/p>\n<p>  <\/p>\n<pre><code class=\"php\">class AppRoute {     \/\/ \u0422\u0440\u0435\u0439\u0442 \u0441 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 onRequest \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u043e\u0442\u0432\u0435\u0442     use \\Shasoft\\SamoyedCMG\\AppRouteOnRequest;     \/\/ \u0421\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0435 \u0421\u0435\u0440\u0432\u0438\u0441 => \u0418\u043c\u044f \u043a\u043b\u0430\u0441\u0441\u0430     protected static array $serviceName2Classname = [         \"Shasoft\\\\SamoyedCMG\\\\Service\\\\IPath\" => \"Shasoft_SamoyedCMG_Service_Path\",         \"Shasoft\\\\SamoyedCMG\\\\Service\\\\IService\" => \"Shasoft_SamoyedCMG_Service_Path\",         \"Shasoft\\\\SamoyedCMG\\\\Service\\\\IRequest\" => \"Shasoft_SamoyedCMG_Service_Request\",         \"Shasoft\\\\STwig\\\\ITwig\" => \"Shasoft_STwig_Twig\",         \"Shasoft\\\\SamoyedCMG\\\\Service\\\\ITemplate\" => \"Shasoft_STwig_Twig\",         IRoute::class => \"Shasoft_SamoyedCMG_Route\"     ];     \/\/ \u0421\u043f\u0438\u0441\u043e\u043a \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0445 \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u0432     protected static array $instances = [];     \/\/ \u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u0435\u0440\u0432\u0438\u0441 (\u0438\u043b\u0438 false \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0435\u0433\u043e \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u044f)     static public function getServiceSafe(string $serviceName): IService|false     {         \/\/ \u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0441\u0435\u0440\u0432\u0438\u0441\u0430\/\u0438\u043c\u044f \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 => \u0438\u043c\u044f \u043a\u043b\u0430\u0441\u0441\u0430         if (array_key_exists($serviceName, self::$serviceName2Classname)) {             \/\/ \u0418\u043c\u044f \u043c\u0435\u0442\u043e\u0434\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f             $methodName = self::$serviceName2Classname[$serviceName];             \/\/ \u0410 \u043c\u043e\u0436\u0435\u0442 \u0441\u0435\u0440\u0432\u0438\u0441 \u0443\u0436\u0435 \u0441\u043e\u0437\u0434\u0430\u043d?             if (array_key_exists($methodName, self::$instances)) {                 \/\/ \u0412\u0435\u0440\u043d\u0443\u0442\u044c \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0439 \u0440\u0430\u043d\u0435\u0435 \u0441\u0435\u0440\u0432\u0438\u0441                 return self::$instances[$methodName];             } else {                 \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f                 if (method_exists(__CLASS__, $methodName)) {                     \/\/ \u0412\u044b\u0437\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434 \u043f\u043e \u0438\u043c\u0435\u043d\u0438 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u0430                     $ret = self::$methodName();                     \/\/ \u0417\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0441\u0435\u0440\u0432\u0438\u0441 \u0432 \u041a\u0415\u0428                     self::$instances[$methodName] = $ret;                     \/\/ \u0412\u0435\u0440\u043d\u0443\u0442\u044c \u0441\u0435\u0440\u0432\u0438\u0441                     return $ret;                 }             }         }         \/\/ \u0418\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435         return false;     }     \/\/ \u041f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u0435\u0440\u0432\u0438\u0441     static public function getService(string $serviceName): IService     {         $ret = self::getServiceSafe($serviceName);         \/\/ \u0415\u0441\u043b\u0438 \u0441\u0435\u0440\u0432\u0438\u0441 \u043d\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d         if ($ret === false) {             \/\/ \u0418\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435             throw new \\Exception(\"\u0421\u0435\u0440\u0432\u0438\u0441\u0430 \" . $serviceName . \" \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442!\");         }         return $ret;     }     \/\/ \u0421\u0435\u0440\u0432\u0438\u0441 \u0441 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0435\u0439 \u043e \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0435     static protected function Shasoft_SamoyedCMG_Route(): \\Shasoft\\SamoyedCMG\\Route     {         return new \\Shasoft\\SamoyedCMG\\Route([]);     }     \/\/ Shasoft\\SamoyedCMG\\Service\\Path     static protected function Shasoft_SamoyedCMG_Service_Path(): \\Shasoft\\SamoyedCMG\\Service\\Path     {         return new \\Shasoft\\SamoyedCMG\\Service\\Path();     }     \/\/ Shasoft\\SamoyedCMG\\Service\\Request     static protected function Shasoft_SamoyedCMG_Service_Request(): \\Shasoft\\SamoyedCMG\\Service\\Request     {         return new \\Shasoft\\SamoyedCMG\\Service\\Request();     }     \/\/ Shasoft\\STwig\\Twig     static protected function Shasoft_STwig_Twig(): \\Shasoft\\STwig\\Twig     {         return new \\Shasoft\\STwig\\Twig(\\Shasoft\\SamoyedCMG\\AppRoute::getService(\\Shasoft\\SamoyedCMG\\Service\\IPath::class));     }     \/\/ \u0417\u0430\u043f\u0443\u0441\u043a     static public function run()     {         \/\/--------------------------------------------------------------------------------         try {             \/\/ \u0417\u0430\u043f\u0440\u043e\u0441             $request = self::getService(IRequest::class);             \/\/ \u0421\u0444\u043e\u0440\u043c\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043e\u0442\u0432\u0435\u0442             $response = self::onRequest($request);             \/\/ \u0415\u0441\u043b\u0438 \u043e\u0442\u0432\u0435\u0442 \u0432 \u0432\u0438\u0434\u0435 \u0441\u0442\u0440\u043e\u043a\u0438             if (is_string($response)) {                 \/\/ \u0442\u043e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u0443 \u0432 HTTP \u043e\u0442\u0432\u0435\u0442                 $response = new Response($response);                 $response->prepare($request->getSymfonyRequest());             }             \/\/ \u041e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u043e\u0442\u0432\u0435\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e             $response->send();         } catch (\\Exception $e) {             s_dump_error('\u0418\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 ' . get_class($e), $e);         } catch (\\Error $e) {             s_dump_error('\u041e\u0448\u0438\u0431\u043a\u0430 ' . get_class($e), $e);         }     } } \/\/ \u0417\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 AppRoute::run();<\/code><\/pre>\n<\/div><\/div>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u0422\u0440\u0435\u0439\u0442 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440\u043e\u043c<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"php\">trait AppRouteOnRequest {     \/\/ \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u0430     static protected function onRequest(IRequest $request): Response     {         \/\/ \u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440         $controller = new \\Shasoft\\SExample\\Controller\\TestControllerTwig();         \/\/ \u0412\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043c\u0435\u0442\u043e\u0434 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0435\u0440\u0430         $response = $controller->run(\\Shasoft\\SamoyedCMG\\AppRoute::getService(\\Shasoft\\SamoyedCMG\\Service\\ITemplate::class));         \/\/ \u0415\u0441\u043b\u0438 \u0432\u0435\u0440\u043d\u0443\u043b\u0438 null         if (is_null($response)) {             $response = '&lt;h3>&lt;abbr style=\"color:red\" title=\"\u041a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u0432\u0435\u0440\u043d\u0443\u043b null\">null&lt;\/abbr>&lt;\/h3>';         }         \/\/ \u0415\u0441\u043b\u0438 \u043e\u0442\u0432\u0435\u0442 \u0432 \u0432\u0438\u0434\u0435 \u0441\u0442\u0440\u043e\u043a\u0438         if (is_string($response)) {             \/\/ \u0442\u043e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u0443 \u0432 HTTP \u043e\u0442\u0432\u0435\u0442             $response = new Response($response);             $response->prepare($request->getSymfonyRequest());         }         \/\/ \u0412\u0435\u0440\u043d\u0443\u0442\u044c \u043e\u0442\u0432\u0435\u0442         return $response;     } }<\/code><\/pre>\n<\/div><\/div>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"php\">class TestControllerTwig {     \/\/ \u041a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440     public function __construct()     {     }     \/\/ \u0417\u0430\u043f\u0443\u0441\u043a     public function run(ITemplate $template)     {         \/\/ \u0412\u044b\u0432\u043e\u0434 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e \u0448\u0430\u0431\u043b\u043e\u043d\u0430         return $template->render('@demo4\/Test.twig', [             'Title' => '\u0417\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0438\u0437 \u0448\u0430\u0431\u043b\u043e\u043d\u0430!',             'datetime' => microtime()         ]);     } }<\/code><\/pre>\n<\/div><\/div>\n<\/div><\/div>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u0413\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044f \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0444\u0430\u0439\u043b\u0430\/\u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<p>\u0412\u0441\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u044b \u0432\u044b\u0448\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u043b\u0435\u0440 \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b. \u041e\u0434\u043d\u0430\u043a\u043e \u044d\u0442\u043e \u043d\u0435 \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u0430\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c. \u041c\u043e\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0444\u0430\u0439\u043b\u0430\/\u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438. \u041a \u043f\u0440\u0438\u043c\u0435\u0440\u0443 \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0441\u0441\u044b\u043b\u043e\u043a \u043d\u0430 \u0440\u0435\u0441\u0443\u0440\u0441\u044b. \u0415\u0441\u043b\u0438 \u043c\u0430\u0440\u0448\u0440\u0443\u0442 \u043d\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043f\u043e\u0441\u0440\u0435\u0434\u043d\u0438\u043a\u0438, \u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0444\u0430\u0439\u043b.<\/p>\n<p>  <\/p>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"php\">class SiteExample5 extends SiteGenerator {     \/\/ \u041a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0442\u043e\u0440     public function __construct()     {         parent::__construct();         \/\/ \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0434\u043e\u043c\u0435\u043d         $this->addDomain('s-cmg5.ru', function (DomainGenerator $domain) {             \/\/ \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043c\u0430\u0440\u0448\u0440\u0443\u0442: \u0444\u0430\u0439\u043b \u0431\u0435\u0437 \u043f\u043e\u0441\u0440\u0435\u0434\u043d\u0438\u043a\u043e\u0432             $domain->addRoute(new RouteGeneratorLink(__DIR__ . '\/..\/@assets\/favicon.ico'), function (RouteGeneratorLink $route) {                 $route->setRoute('link\/file.ico');             });             \/\/ \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043c\u0430\u0440\u0448\u0440\u0443\u0442: \u0444\u0430\u0439\u043b \u0441 \u043f\u043e\u0441\u0440\u0435\u0434\u043d\u0438\u043a\u0430\u043c\u0438             $domain->addRoute(new RouteGeneratorLink(__DIR__ . '\/..\/@assets\/favicon.ico'), function (RouteGeneratorLink $route) {                 $route->setRoute('link\/file\/middleware.ico');                 $route->addMiddleware(TestMiddleware::class, ['a' => 1]);             });             \/\/ \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043c\u0430\u0440\u0448\u0440\u0443\u0442: \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0441 \u0431\u0435\u0437 \u043f\u043e\u0441\u0440\u0435\u0434\u043d\u0438\u043a\u043e\u0432             $domain->addRoute(new RouteGeneratorLink(__DIR__ . '\/..\/@assets\/images'), function (RouteGeneratorLink $route) {                 $route->setRoute('link\/folder');             });             \/\/ \u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043c\u0430\u0440\u0448\u0440\u0443\u0442: \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0441 \u0441 \u043f\u043e\u0441\u0440\u0435\u0434\u043d\u0438\u043a\u0430\u043c\u0438             $domain->addRoute(new RouteGeneratorLink(__DIR__ . '\/..\/@assets\/images'), function (RouteGeneratorLink $route) {                 $route->setRoute('link\/folder\/middleware');                 $route->addMiddleware(TestMiddleware::class, ['b' => 2]);             });         });     } }<\/code><\/pre>\n<\/div><\/div>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u0424\u0430\u0439\u043b .htaccess<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<p>\u0412 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438 \/@\/s-cmg5.ru\/ \u043f\u0440\u0438 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0438\u0438 \u043f\u043e\u0441\u0440\u0435\u0434\u043d\u0438\u043a\u043e\u0432 \u0441\u043e\u0437\u0434\u0430\u044e\u0442\u0441\u044f \u0441\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u0444\u0430\u0439\u043b\/\u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e.<\/p>\n<p>  <\/p>\n<pre><code class=\"plaintext\">    #-- s-cmg5.ru\/link\/file.ico     RewriteCond %{HTTP_HOST} s-cmg5.ru     RewriteCond %{REQUEST_METHOD} GET     RewriteRule ^link\/file.ico$ \/@\/s-cmg5.ru\/96495f91.ico [L]      #-- s-cmg5.ru\/link\/file\/middleware.ico     RewriteCond %{HTTP_HOST} s-cmg5.ru     RewriteCond %{REQUEST_METHOD} GET     RewriteRule ^link\/file\/middleware.ico$ \/@\/s-cmg5.ru\/469c3124.php [L]      #-- s-cmg5.ru\/link\/folder     RewriteCond %{HTTP_HOST} s-cmg5.ru     RewriteCond %{REQUEST_METHOD} GET     RewriteRule ^link\/folder\/(.*)$ \/@\/s-cmg5.ru\/5e754869\/$1 [L]      #-- s-cmg5.ru\/link\/folder\/middleware     RewriteCond %{HTTP_HOST} s-cmg5.ru     RewriteCond %{REQUEST_METHOD} GET     RewriteRule ^link\/folder\/middleware\/(.*)$ \/@\/s-cmg5.ru\/ea49e04d.php?Z7c0d736e0=$1 [QSA,L]<\/code><\/pre>\n<\/div><\/div>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u0422\u0440\u0435\u0439\u0442 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0444\u0430\u0439\u043b\u0430<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"php\">trait AppRouteOnRequest {     \/\/ \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u0430     static protected function onRequest(IRequest $request): Response     {         \/\/ \u0418\u043c\u044f \u0444\u0430\u0439\u043b\u0430 \u0441 \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u043e\u043c         $filepath = __DIR__ . '\/..\/..\/vendor\/shasoft\/s-examples\/@assets\/favicon.ico';         \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u0438\u043c \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0444\u0430\u0439\u043b\u0430?         if( is_file($filepath) &amp;&amp; file_exists($filepath) )         {             \/\/ \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043e\u0442\u0432\u0435\u0442\u0430 \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0444\u0430\u0439\u043b             $response = new \\Symfony\\Component\\HttpFoundation\\BinaryFileResponse($filepath);             \/\/ \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043e\u0442\u0432\u0435\u0442\u0430 \u043f\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u0430             $response->prepare($request->getSymfonyRequest());         } else {             \/\/ \u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442             $response = new Response('\u0424\u0430\u0439\u043b\u0430 \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442!', Response::HTTP_NOT_FOUND);         }          \/\/ \u0412\u0435\u0440\u043d\u0443\u0442\u044c \u043e\u0442\u0432\u0435\u0442         return $response;     } }<\/code><\/pre>\n<\/div><\/div>\n<div class=\"spoiler\" role=\"button\" tabindex=\"0\">                         <b class=\"spoiler_title\">\u0422\u0440\u0435\u0439\u0442 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438<\/b>                         <\/p>\n<div class=\"spoiler_text\">\n<pre><code class=\"php\">trait AppRouteOnRequest {     \/\/ \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u0430     static protected function onRequest(IRequest $request): Response     {         \/\/ \u0418\u043c\u044f \u0444\u0430\u0439\u043b\u0430 \u0441 \u043a\u043e\u043d\u0442\u0435\u043d\u0442\u043e\u043c         $filepath = __DIR__ . '\/..\/..\/vendor\/shasoft\/s-examples\/@assets\/images\/'.str_replace('..\/','\/',self::$argsRoute['filename']);         \/\/ \u041f\u0440\u043e\u0432\u0435\u0440\u0438\u043c \u043d\u0430\u043b\u0438\u0447\u0438\u0435 \u0444\u0430\u0439\u043b\u0430?         if( is_file($filepath) &amp;&amp; file_exists($filepath) )         {             \/\/ \u0412 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043e\u0442\u0432\u0435\u0442\u0430 \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0444\u0430\u0439\u043b             $response = new \\Symfony\\Component\\HttpFoundation\\BinaryFileResponse($filepath);             \/\/ \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043e\u0442\u0432\u0435\u0442\u0430 \u043f\u043e \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u0430             $response->prepare($request->getSymfonyRequest());         } else {             \/\/ \u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442             $response = new Response('\u0424\u0430\u0439\u043b\u0430 \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442!', Response::HTTP_NOT_FOUND);         }          \/\/ \u0412\u0435\u0440\u043d\u0443\u0442\u044c \u043e\u0442\u0432\u0435\u0442         return $response;     } }<\/code><\/pre>\n<\/div><\/div>\n<\/div><\/div>\n<p>  <\/p>\n<h2 id=\"zaklyuchenie\">\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h2>\n<p>  <\/p>\n<p>\u0414\u0430\u043d\u043d\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0430 \u0434\u043b\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0441\u0432\u043e\u0438\u0445 \u043c\u044b\u0441\u043b\u0435\u0439. \u0417\u0430\u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0443\u0436\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0438 \u043f\u043e\u043f\u044b\u0442\u0430\u0442\u044c\u0441\u044f \u043f\u043e\u043d\u044f\u0442\u044c \u0447\u0442\u043e \u044f \u0443\u043f\u0443\u0441\u0442\u0438\u043b. \u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u044d\u0442\u0430\u043f \u2014 \u0434\u043e\u0432\u0435\u0441\u0442\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0434\u043e \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043a\u043e\u0433\u0434\u0430 \u043c\u043e\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0430\u0439\u0442 \u0438 \u0432\u044b\u043b\u043e\u0436\u0438\u0442\u044c \u0435\u0433\u043e \u043d\u0430 \u0445\u043e\u0441\u0442\u0438\u043d\u0433\u0435.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p> <!----> <!----><\/div>\n<p> <!----> <!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/717706\/\"> https:\/\/habr.com\/ru\/post\/717706\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-1\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u041e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0438\u0434\u0435\u044f <strong>CMG<\/strong> (Content management generator) \u2014 \u043d\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u0432 Runtime \u0442\u043e, \u0447\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 \u0432\u0438\u0434\u0435 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e PHP \u043a\u043e\u0434\u0430.<br \/>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/webt\/fd\/ff\/ck\/fdffck9jbx07xfqneofhmdbblzu.png\" data-src=\"https:\/\/habrastorage.org\/webt\/fd\/ff\/ck\/fdffck9jbx07xfqneofhmdbblzu.png\"\/><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-345674","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/345674","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=345674"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/345674\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=345674"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=345674"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=345674"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}