chelkaz
@chelkaz

Пишет Class not found. Как правильно определить пространство имен?

От корня сайта создал класс:
/bitrix/templates/app/Pi/Test.php
Класс:
namespace app\Pi;
class test extends CBitrixComponent
{
// ...
}


Пробую подключить в другом файле и заставить отработать:
$test = new app\Pi\test;
// ...

Но пишет Class 'app\Pi\test' not found
  • Вопрос задан
  • 9296 просмотров
Пригласить эксперта
Ответы на вопрос 4
gromdron
@gromdron
Работаю с Bitrix24
Эээ... а что вы сделать то хотите ?

Я вот о чем говорю: при использовании ООП в bitrix вы сталкиваетесь сразу с 2 большими стенами - применение ооп и битрикс. Прежде чем разбирать конкретный код хотелось бы немножко просветить вас в самой архитектуре битрикса.
В терминологии Битрикса он использует концепцию MVC, но в рамках битрикса, а это означает что на любой странице где вы общаетесь с ним вы должны подключить пролог (хотя бы prolog_before) и эпилог (хотя бы epilog_after, ну в идеале). Именно "компонент" и является тем самым MVC (Вообще это скорее VC + row access, так как модели по сути нет). Есть класс CBitrixComponent (контроллер) и класс CBitrixComponentTemplate (который совместно с файлами шаблона и образует view).

Вызов компонента происходит из глобальной переменной $APPLICATION путем метода IncludeComponent. До версии 14 (если мне не изменяет память) вообще не было такого понятия как class.php, где можно было отнаследоваться от CBitrixComponent и перекрыть какие-нибудь функции (шаблонизатор к примеру сменить), а после нового ядра d7 появилась возможность отнаследоваться от CBitrixComponent и в файле class.php разместить свой код (таким образом мы сохраняем и class.php с новыми функциями и component.php с логикой), а перекрывая метод executeComponent вы можете избавиться и от component.php.

С точки зрения архитектуры (рекомендую изучить документацию, она очень обширна и познавательна) все компоненты должны лежать в так называемом пространстве имен, чем обычно служит ник-нейм или название компании (Естественно начинается не с цифры и содержит только латинские буквы), которые в свою очередь могут располагаться в /bitix/components/#пространство_имен#/#название_компонента#/

Теперь построчно разберем Ваш вопрос:

Вы положили свой класс сюда: /bitrix/templates/app/Pi/Test.php, что является неверным с точки зрения архитектуры, так как поместили класс отвечающий за контроллер в папку с шаблоном. Если вы не пишете свой модуль вы можете подключить его например в /local/php_interface/classes/ (пример надуманный, можете просто в /local/php_interface положить или сразу в init.php), однако для этого вы должны будете написать autoloader, так как у битрикса он работает только для модулей. Предположим вы в init.php напишете грубый require_once с файлом.

Затем вы делаете следующее:

Что является неверным, так как по сути вы обьявляете неймспейс для файла и это с точки зрения php выглядит вот так в конечном итоге:

class app\Pi\test extends app\Pi\CBitrixComponent
{
// ...
}

А класса app\Pi\CBitrixComponent не существует. Так что вам нужно поправить пример хотя бы так:

class test extends \CBitrixComponent

Настоятельно рекомендую прочитать документацию или хотя бы посмотреть видео с академии битрикс. Сама система не подарок, а другой программист который увидит ваш код будет говорить что это битрикс виноват.
Ответ написан
Комментировать
alexfilus
@alexfilus
Senior backend developer
Сам по себе, от того что файл с классом лежит в папке с шаблоном, видимым не станет. Его нужно либо проинклудить, либо использовать автозагрузку классов php.net/manual/ru/language.oop5.autoload.php
Либо применить битриксовые средства. Обычно классы лежат в модулях, но так как у Вас он наследуется от CBitrixComponent, предположу что для Ваших целей подходит компонент.
https://dev.1c-bitrix.ru/learning/course/?COURSE_I...
Ответ написан
Комментировать
@novrm
Было так:
$test = new app\Pi\test;
Попробуйте вот так:
$test = new \app\Pi\test;
А вообще-то Все нужно делать из Заглавной. Вот так:
$test = new \App\Pi\Test();
Ответ написан
Комментировать
@khrisanfov
Программист
С битриксом не знаком, но подозреваю, что имя класса должно быть Test а не test
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы