Класс Cot. Фасад (Facade) в Cotonti
Полный разбор класса Cot как статического фасада для доступа к ключевым глобальным переменным Cotonti. Свойства, инициализация, ссылочная привязка, примеры использования в плагинах и модулях.
Фасад Cot в CMF Cotonti v.1.0 — справочное руководство по исходному коду
Основной предмет анализа — public_html/system/Cot.php, соответствующие участки public_html/system/common.php и раздел документации по хукам, где прямо описан фасад.
Оглавление
- Область анализа
- Что исходник называет фасадом
- Точное определение фасада здесь
- Устройство класса Cot
- Разбор Cot::init()
- Ссылочная привязка =&
- Как пользоваться Cot::$...
- Жизненный цикл
- Каталог свойств
- Cot::$cache
- Cot::$cfg
- Cot::$db
- Cot::$db_x
- Cot::$env
- Cot::$extrafields
- Cot::$L
- Cot::$out
- Cot::$R
- Cot::$structure
- Cot::$sys
- Cot::$usr
- Cot::$currentRoute
- Почему нет Cot::$id
- global и фасад
- Фасад в обработчиках хуков
- Чем фасад не является
- Алгоритм применения
- Как читать выражения
- Чтение и изменение
- Практические примеры
- Ошибки
- Разбор common.php
- Разбор маршрутизатора
- Разбор загрузки расширений
- Отладка
- Руководство для плагина
- Руководство для модуля
- Справочная таблица
- Границы утверждений
- Заключение
- Источниковая база
- Приложения
1. Область анализа
В материалах присутствуют два типа доказательств. Документация объясняет назначение фасада в контексте хуков. Исходник Cot.php показывает его реализацию. common.php показывает реальную точку инициализации и реальные обращения. Маршрутизатор показывает изменение Cot::$env. Поэтому здесь не нужно реконструировать архитектуру по названию: достаточно проследить цепочку «объявление → init → использование».
Документация по хукам говорит, что с версии 0.9.15 наиболее востребованные глобальные переменные доступны через специальный фасад-класс Cot, например Cot::$cfg, и перечисляет набор переменных.
Сам класс документирован как Main application class and facade to access key Cotonti globals regardless of scope. Это прямое авторское определение назначения класса.
2. Что исходник буквально называет фасадом
В Cot.php слово facade находится непосредственно в PHPDoc класса. Это наиболее сильное основание для термина. Формулировка означает: класс предназначен как точка доступа к ключевым глобальным данным Cotonti независимо от области видимости. Нельзя расширять эту формулировку до «фасад всего приложения» без дополнительного кода.
Документация по хукам связывает это назначение с проблемой global: в процедурном коде большая часть хуков находится в глобальной области, а внутри функций для доступа к глобалам обычно требуется global. Фасад дает альтернативную форму доступа к перечисленным данным.
3. Точное определение фасада здесь
В данном коде фасад Cot — это класс с публичными статическими свойствами, которые после выполнения Cot::init() связываются ссылками с определенным набором глобальных переменных Cotonti. Пользователь получает единообразную форму Cot::$property, а конкретное значение продолжает жить там, где его определяет системный код.
Это определение намеренно узкое. Фасад не является отдельной базой данных, контейнером зависимостей, механизмом хуков или контроллером. В исходнике для этих функций есть другие механизмы, а Cot в рассматриваемом месте дает доступ к состояниям и объектам.
4. Устройство класса Cot
Класс содержит публичные статические свойства $cache, $cfg, $db, $db_x, $env, $extrafields, $L, $out, $R, $structure, $sys, $usr и отдельное $currentRoute = null. Основная привязка выполняется методом init().
class Cot
{
public static $cache;
public static $cfg;
public static $db;
public static $db_x;
public static $env;
public static $extrafields;
public static $L;
public static $out;
public static $R;
public static $structure;
public static $sys;
public static $usr;
public static $currentRoute = null;
}Список свойств и их PHPDoc непосредственно виден в исходнике. currentRoute отличается от остальных: у него нет привязки в init() к глобальной переменной.
5. Разбор Cot::init()
public static function init()
{
global $cache, $cfg, $cot_extrafields, $db, $db_x, $env, $L, $out, $R, $structure, $sys, $usr;
self::$cache =& $cache;
self::$cfg =& $cfg;
self::$db =& $db;
self::$db_x =& $db_x;
self::$env =& $env;
self::$extrafields =& $cot_extrafields;
self::$L =& $L;
self::$out =& $out;
self::$R =& $R;
self::$structure =& $structure;
self::$sys =& $sys;
self::$usr =& $usr;
}Метод начинается с global: это позволяет телу функции обращаться к указанным глобальным переменным. Далее каждое статическое свойство получает ссылку на соответствующую переменную. В этом и состоит техническая основа фасада.
PHPDoc метода говорит: Initializes static members. Call this function once all globals are defined. Следовательно, порядок вызова важен: метод предназначен для выполнения после определения нужных глобальных переменных. Сам код common.php подтверждает штатную последовательность.
6. Ссылочная привязка =&
Критическая деталь — символ &. Фактическая строка self::$cfg =& $cfg не является обычным присваиванием значения. Она устанавливает ссылочную связь. Поэтому Cot::$cfg следует рассматривать как другую точку доступа к связанному $cfg, а не как снимок его значения.
То же относится к $db, $env, $out, $usr и остальным свойствам, перечисленным в init(). В исходнике все они используют одну и ту же форму self::$... =& ....
Практическая схема: $db → Cot::init() → Cot::$db. После связывания операции чтения и изменения через фасад относятся к тому же связанному значению. Для currentRoute такая схема не доказана, потому что соответствующей ссылки в init() нет.
7. Как пользоваться Cot::$...
Фасад не вводит отдельного языка. Используется обычный синтаксис PHP для статического свойства: Cot::$cfg, Cot::$db, Cot::$env. Если значение является объектом, дальше применяется ->; если массивом — [...].
$result = Cot::$db->query($sql);
$extension = Cot::$env['ext'];
Cot::$env['ext'] = $extensionCode;В первом выражении query() является методом объекта, который находится в Cot::$db, а не методом класса Cot. Во втором выражении ext является индексом массива env. В третьем происходит изменение связанного массива.
8. Жизненный цикл
В common.php сначала создается объект базы данных в $db, затем присутствует комментарий Here we can init our globals facade и вызов Cot::init(). После этого код использует Cot::$db для запросов и Cot::$cache для операций с кэшем. Это дает непосредственное доказательство штатного порядка.
$db = new CotDB([...]);
Cot::init();
$cache && $cache->init();Нельзя переносить вывод «фасад уже готов» на произвольную раннюю точку приложения без проверки. В штатном потоке место вызова видно; вне него состояние должно быть проверено отдельно.
9. Каталог свойств
| Свойство | Источник | Назначение в PHPDoc/коде |
|---|---|---|
Cot::$cache | $cache | Cotonti cache |
Cot::$cfg | $cfg | Cotonti configuration |
Cot::$db | $db | Database connection, CotDB |
Cot::$db_x | $db_x | Database table name prefix |
Cot::$env | $env | Environment settings |
Cot::$extrafields | $cot_extrafields | Extra fields |
Cot::$L | $L | Language strings |
Cot::$out | $out | Pre-rendered output strings |
Cot::$R | $R | Resource strings |
Cot::$structure | $structure | Structure tree and properties array |
Cot::$sys | $sys | Temporary system variables |
Cot::$usr | $usr | Current user object |
Cot::$currentRoute | нет ссылки в init() | ?Route, начальное null |
Первые двенадцать строк образуют набор глобальных фасадных ссылок. currentRoute — отдельное статическое поле и потому должно анализироваться отдельно.
Cot::$cache
Объявление: public static $cache;. Источник привязки: $cache. В init() используется соответствующая форма self::$... =& .... В PHPDoc класса указано назначение: Cotonti cache.
В common.php проверяется через empty() и используется как объект, после чего вызывается $cache->db->store(...).
Граница точного вывода: Не следует приписывать store() фасаду: метод находится ниже по цепочке, у объекта кэша.
Cot::$cfg
Объявление: public static $cfg;. Источник привязки: $cfg. В init() используется соответствующая форма self::$... =& .... В PHPDoc класса указано назначение: Cotonti configuration.
Фасадная форма позволяет обращаться к конфигурационному массиву. Конкретные ключи нужно брать из реального кода.
Граница точного вывода: Само имя cfg не доказывает структуру произвольных вложенных ключей.
Cot::$db
Объявление: public static $db;. Источник привязки: $db. В init() используется соответствующая форма self::$... =& .... В PHPDoc класса указано назначение: Database connection, CotDB.
В common.php реально выполняются Cot::$db->query(...) и обращения Cot::$db->core, Cot::$db->plugins.
Граница точного вывода: core и plugins после -> относятся к объекту базы, а не к классу Cot.
Cot::$db_x
Объявление: public static $db_x;. Источник привязки: $db_x. В init() используется соответствующая форма self::$... =& .... В PHPDoc класса указано назначение: Database table name prefix.
Отдельное свойство, отдельная глобальная переменная, отдельная ссылка.
Граница точного вывода: Нельзя смешивать с объектом $db.
Cot::$env
Объявление: public static $env;. Источник привязки: $env. В init() используется соответствующая форма self::$... =& .... В PHPDoc класса указано назначение: Environment settings.
Маршрутизатор пишет ext, type, а для модуля/плагина — location.
Граница точного вывода: Точный смысл любого другого ключа требует места чтения/записи.
Cot::$extrafields
Объявление: public static $extrafields;. Источник привязки: $cot_extrafields. В init() используется соответствующая форма self::$... =& .... В PHPDoc класса указано назначение: Extra fields.
Имя фасадного свойства специально отличается от глобального имени.
Граница точного вывода: Не надо писать Cot::$cot_extrafields.
Cot::$L
Объявление: public static $L;. Источник привязки: $L. В init() используется соответствующая форма self::$... =& .... В PHPDoc класса указано назначение: Language strings.
Фасадная точка доступа к связанному $L.
Граница точного вывода: Конкретные языковые ключи не выводятся только из названия свойства.
Cot::$out
Объявление: public static $out;. Источник привязки: $out. В init() используется соответствующая форма self::$... =& .... В PHPDoc класса указано назначение: Pre-rendered output strings.
init() гарантирует значения head и subtitle, если они не установлены.
Граница точного вывода: Это связанный массив, а не отдельная копия.
Cot::$R
Объявление: public static $R;. Источник привязки: $R. В init() используется соответствующая форма self::$... =& .... В PHPDoc класса указано назначение: Resource strings.
Статическое свойство связано с $R.
Граница точного вывода: Подробная структура R требует другого исходного участка.
Cot::$structure
Объявление: public static $structure;. Источник привязки: $structure. В init() используется соответствующая форма self::$... =& .... В PHPDoc класса указано назначение: Structure tree and properties array.
Фасад предоставляет связанный $structure.
Граница точного вывода: Набор ключей не следует придумывать.
Cot::$sys
Объявление: public static $sys;. Источник привязки: $sys. В init() используется соответствующая форма self::$... =& .... В PHPDoc класса указано назначение: Temporary system variables.
common.php заполняет $sys системными значениями, а фасад предоставляет связанную точку доступа.
Граница точного вывода: Конкретный ключ нужно подтверждать кодом.
Cot::$usr
Объявление: public static $usr;. Источник привязки: $usr. В init() используется соответствующая форма self::$... =& .... В PHPDoc класса указано назначение: Current user object, PHPDoc array.
Фасадная форма доступа к $usr.
Граница точного вывода: Не расширять описание за пределы предоставленного PHPDoc и использований.
Cot::$currentRoute
currentRoute объявлен как public static $currentRoute = null и документирован как ?Route. При этом в init() нет global $currentRoute и нет self::$currentRoute =& .... Поэтому нельзя автоматически называть его алиасом глобальной переменной. Это отдельное статическое свойство класса.
Почему нет Cot::$id
Документация по хукам упоминает $id среди часто используемых глобальных переменных, но в собственном списке фасада $id отсутствует. Исходник Cot.php подтверждает отсутствие public static $id и отсутствие строки привязки self::$id =& $id. Поэтому в предоставленном коде нельзя использовать Cot::$id как доказанный способ доступа.
global и фасад
Историческая форма внутри функции: global $db;. Фасадная форма: Cot::$db. Документация прямо указывает фасад как способ избежать явного указания перечисленных глобальных переменных в global. Это не означает исчезновения глобальных переменных: сам init() получает их через global.
Разница практическая: global импортирует конкретный глобал в область функции; Cot::$db обращается к публичному статическому свойству класса, которое уже связано с глобалом. Фасад особенно удобен в обработчиках, находящихся внутри функций или иных областей, где прямой глобальный доступ неудобен.
Фасад в обработчиках хуков
Документация определяет хук как место, где подключается сторонний PHP-обработчик. В обработчиках можно делать запросы к БД, изменять значения и назначать теги. Для доступа к системным переменным фасад дает форму Cot::$....
Хук и фасад — разные вещи. Хук определяет когда дополнительный код может быть выполнен. Фасад определяет как этот код может получить доступ к перечисленному системному состоянию. Вызов обработчика через cot_getextplugins() и include не является частью механизма Cot.
Чем фасад не является
| Нельзя считать | Почему |
|---|---|
| хуком | Cot — PHP-класс; хуки имеют имена и обработчики |
| загрузчиком плагинов | плагины загружаются отдельной логикой; Cot::$db лишь дает объект БД |
| контроллером | в классе нет контроллерной логики; маршрутизатор использует фасад |
| DI-контейнером | в коде нет get()/регистрации произвольных зависимостей |
| Singleton | нет механизма единственного экземпляра |
| магическим прокси | нет __get()/__set() для произвольных имен |
| копией глобалов | для основных свойств используется =& |
Алгоритм применения
- Определите нужное системное значение.
- Найдите соответствующее свойство в
Cot.php. - Проверьте ссылку в
init(). - Проверьте, что
Cot::init()уже выполнен. - Используйте обычный PHP-синтаксис.
- Если меняете значение, учитывайте ссылочную связь.
- Если свойства нет, не придумывайте его — ищите реальный способ доступа.
Как читать выражения Cot::$...
Разбирайте выражение по уровням. В Cot::$db->query(): Cot — класс; $db — статическое свойство; query() — метод объекта, полученного из свойства. В Cot::$env['ext']: $env — фасадное свойство; ['ext'] — индекс массива. В Cot::$db->core: core уже принадлежит объекту базы.
Чтение и изменение
Ссылочная привязка делает фасад пригодным и для изменения. Реальные строки маршрутизатора: Cot::$env['ext'] = $extensionCode; и Cot::$env['type'] = $extensionType;. В init() есть self::$out['head'] = '' при отсутствии ключа. Это прямые доказательства записи через фасад.
Не надо считать любое изменение через фасад безопасным или обязательным: код только показывает техническую возможность и реальные места. Последствия конкретного изменения зависят от того, кто читает измененное значение позже в потоке выполнения.
Практические примеры
$result = Cot::$db->query($sql);
if (!empty(Cot::$cache)) {
Cot::$cache->db->store('cot_plugins', $cot_plugins, 'system');
}
$extension = Cot::$env['ext'];
Cot::$env['ext'] = $extensionCode;Первый пример работает с объектом БД. Второй показывает проверку и цепочку к объекту кэша. Третий — чтение массива окружения. Четвертый — запись в него. Эти формы соответствуют реальному стилю предоставленного исходника.
Ошибки
| Ошибка | Точный анализ |
|---|---|
Считать Cot::$cfg копией $cfg. | В init() стоит =&. |
| Использовать фасад до инициализации. | init() является механизмом связывания; штатный вызов виден в common.php. |
Писать Cot::$cot_extrafields. | Свойство называется $extrafields, хотя глобал называется $cot_extrafields. |
Писать Cot::$id. | В классе нет такого свойства. |
Считать currentRoute глобальным алиасом. | В init() нет его привязки. |
Считать query() методом Cot. | Это метод объекта, доступного через Cot::$db. |
Считать core свойством фасада. | В Cot::$db->core оно принадлежит объекту БД. |
| Считать фасад механизмом хуков. | Хуки реализуются отдельным механизмом. |
| Придумывать ключи массивов. | Их нужно подтверждать исходным кодом. |
Разбор common.php
В показанном bootstrap сначала создается $db = new CotDB([...]), затем вызывается Cot::init(). После этого код получает расширения запросом через Cot::$db->query(...), а активные плагины — аналогичным запросом. Если кэш существует, данные сохраняются через Cot::$cache->db->store(...).
$extensions = Cot::$db->query('SELECT * FROM ' . Cot::$db->core . ' WHERE ct_state = 1 AND ct_lock = 0')->fetchAll();
$sql = Cot::$db->query(
'SELECT pl_code, pl_file, pl_hook, pl_module, pl_title FROM ' . Cot::$db->plugins
. ' WHERE pl_active = 1 ORDER BY pl_hook ASC, pl_order ASC'
);Это сильный практический пример: фасад предоставляет доступ к объекту, но SQL остается непосредственно в коде. Следовательно, Cot не скрывает логику запроса.
Разбор маршрутизатора
Cot::$env['ext'] = $extensionCode;
Cot::$env['type'] = $extensionType;
if ($extensionType === ExtensionsDictionary::TYPE_MODULE) {
Cot::$env['location'] = $extensionCode;
} elseif ($extensionType === ExtensionsDictionary::TYPE_PLUGIN) {
Cot::$env['location'] = 'plugins';
}Здесь маршрутизатор записывает в связанный массив окружения код расширения, тип и location. Сам факт записи показывает, что фасад используется как изменяемая точка системного состояния.
Загрузка расширений
После Cot::init() common.php использует Cot::$db для чтения таблицы расширений и таблицы плагинов. В коде проверяется состояние расширений и активность плагинов, затем результаты помещаются в массивы. Это показывает реальный рабочий сценарий фасада: ядро обращается к уже созданному объекту базы через статическое свойство.
Отладка
При проблеме с фасадом проверяйте строго по цепочке: существует ли свойство; есть ли его привязка в init(); выполнен ли Cot::init(); какое значение находится в свойстве; правильно ли разобрана цепочка ::$property->method; не перепутан ли фасадный объект со свойствами его объекта. Это исключает большинство ошибок чтения.
Руководство для плагина
Документация по хукам показывает, что обработчик является PHP-файлом расширения. Если ему нужен системный объект базы, можно использовать Cot::$db вместо global $db, если код находится в штатном жизненном цикле после инициализации фасада. Аналогично для $cfg, $usr, $env и других доказанных свойств.
Не следует использовать фасад ради самого фасада. Если вам нужен локальный параметр обработчика, фасад здесь ни при чем. Фасад предназначен для доступа к системным данным, которые он действительно предоставляет.
Руководство для модуля
Для модуля правило такое же: определите хук или контроллерную точку, затем для системных данных используйте соответствующее свойство Cot. Фасад не определяет точку вызова вашего модуля и не заменяет механизм хуков.
Справочная таблица
| Нужно получить | Используйте | Что подтверждено |
|---|---|---|
| кэш | Cot::$cache | ссылка на $cache; реальное использование в common.php |
| конфигурацию | Cot::$cfg | ссылка на $cfg |
| БД | Cot::$db | ссылка на $db; реальный query() |
| префикс таблиц | Cot::$db_x | ссылка на $db_x |
| окружение | Cot::$env | ссылка на $env; реальные записи маршрутизатора |
| extra fields | Cot::$extrafields | ссылка на $cot_extrafields |
| языковые строки | Cot::$L | ссылка на $L |
| вывод | Cot::$out | ссылка на $out; head и subtitle |
| ресурсы | Cot::$R | ссылка на $R |
| структуру | Cot::$structure | ссылка на $structure |
| системные переменные | Cot::$sys | ссылка на $sys |
| пользователя | Cot::$usr | ссылка на $usr |
| маршрут | Cot::$currentRoute | отдельное static property, не ссылка из init() |
Границы утверждений
Нельзя по одному имени свойства вывести все его ключи, все места записи или весь жизненный цикл. Нельзя по наличию фасада утверждать наличие DI, Singleton или другого архитектурного механизма. Нельзя автоматически переносить свойства из другой версии Cotonti. Для каждого такого вывода нужен соответствующий исходник.
В этой статье фактическая структура берется из Cot.php на момент публикации статьи.
Заключение
Фасад Cot здесь — очень конкретный инструмент. Он объединяет под одним именем класса доступ к нескольким системным значениям, которые исторически существуют как глобальные переменные. Cot::init() связывает статические свойства с глобалами через =&. После этого код может использовать Cot::$cfg, Cot::$db, Cot::$env и другие доказанные свойства.
Главное практическое правило: сначала найдите свойство и его привязку, затем проверьте момент инициализации, после этого используйте обычный PHP-синтаксис. Не придумывайте отсутствующие свойства и не смешивайте фасад с хуками, маршрутизацией, загрузкой расширений или API объектов.
Источниковая база
Основные доказательства:
- документация по хукам и фасаду;
public_html/system/Cot.php; public_html/system/common.php;- участок маршрутизатора с изменением
Cot::$env.
Документация прямо перечисляет фасадные глобалы и форму Cot::$cfg. Исходник класса показывает свойства и init(). common.php показывает реальный вызов Cot::init().
Приложения
Ниже собраны методические правила работы с фасадом Cot. Текст приведён один раз: дублирующие копии из исходных материалов убраны, смысловые акценты объединены в логическую структуру.
А. Метод строгого анализа фасада
При чтении конкретного расширения начинайте не с догадки о назначении класса, а с фактов. Найдите объявление свойства. Затем найдите его строку привязки в init(). Затем найдите место вызова Cot::init(). После этого найдите реальные обращения Cot::$.... Такая последовательность позволяет построить проверяемую цепочку и не приписывать фасаду функции, которых в коде нет.
Для объекта всегда отделяйте уровень фасада от уровня объекта. В выражении Cot::$db->query(...) фасад заканчивается на $db; query() принадлежит полученному объекту. В выражении Cot::$cache->db->store(...) фасад заканчивается на $cache; дальше идет структура самого объекта кэша. В выражении Cot::$env['ext'] фасад заканчивается на $env, после чего начинается работа с массивом.
Для ссылочных свойств отдельно фиксируйте направление связи. self::$property =& $global означает, что статическое свойство получает ссылочную связь с глобальной переменной. Поэтому нельзя описывать его как «кэшированный снимок» или «копию». Если код затем записывает через Cot::$property, он работает с тем же связанным значением. Это особенно ясно в реальных строках маршрутизатора и инициализации $out.
Если документация и текущий исходник дают разные списки, для ответа о конкретном классе нужно смотреть текущий исходник класса. Например, $id фигурирует в описании часто используемых глобалов, но не фигурирует среди свойств класса Cot; это достаточно, чтобы не считать Cot::$id доказанным интерфейсом фасада. Аналогично currentRoute присутствует в классе, но не участвует в ссылочной привязке init().
Наконец, отделяйте возможность доступа от смыслового эффекта. Cot::$env['ext'] = $extensionCode доказывает запись значения окружения. Чтобы утверждать, кто именно и когда использует это значение, нужен код чтения. Поэтому строгий отчет всегда заканчивается на той границе, которую позволяет показать исходник.
Б. Проверка свойства перед использованием
Строгий анализ начинается с конкретного участка исходника. Для каждого обращения к фасаду нужно установить четыре факта:
- свойство объявлено;
- свойство имеет ожидаемое назначение или тип в PHPDoc;
- свойство связано в
init()с определенной глобальной переменной; Cot::init()вызывается до места использования в штатном потоке.
Только после этого можно делать практический вывод о доступе. Такой метод особенно полезен потому, что внешне похожие выражения Cot::$db, Cot::$env и Cot::$currentRoute технически устроены не одинаково.
В рассматриваемом классе основная группа свойств связывается в init() явно. Например, self::$db =& $db и self::$env =& $env. Это дает однозначное соответствие. У currentRoute такой строки нет. Поэтому нельзя переносить правило одной группы на другую только из-за того, что оба значения записаны как public static.
При использовании фасада также нужно отделять источник значения от способа доступа. Cot::$db не создает соединение с БД. Соединение создается раньше в common.php присваиванием $db = new CotDB([...]). Cot::init() связывает уже существующий $db со свойством. Значит, фасад не заменяет создание объекта и не является фабрикой базы данных.
Точно так же Cot::$env не является самостоятельным контейнером окружения. Это статическое свойство, связанное с $env. Маршрутизатор записывает в него сведения о расширении. Если нужно узнать дальнейшее действие после такой записи, необходимо искать последующее чтение соответствующего ключа. Сам факт записи не позволяет придумывать дальнейшую семантику.
Практическое правило: не выводить поведение по названию. Сначала искать точное объявление, затем точную привязку, затем реальное использование. Если найден только один из этих элементов, отчет должен ограничиваться найденным фактом. Это и есть граница между анализом исходника и предположением.
В. Границы фасада в выражениях
Объект после ->. В Cot::$db->query() только Cot::$db относится к фасаду; query() относится к объекту базы. В Cot::$cache->db->store() только $cache относится к фасаду, а db и store() находятся уже внутри объекта, полученного через это свойство. Это правило предотвращает ошибочную документацию API класса Cot.
Массив после []. В Cot::$env['ext'] свойство фасада — $env, а 'ext' — индекс массива. В Cot::$out['head'] свойство — $out, а 'head' — индекс. Структура массива должна анализироваться отдельно и подтверждаться местами чтения и записи.
Изменение системного состояния. Строка self::$env =& $env означает, что фасадная точка и глобальная переменная связаны. Поэтому запись через Cot::$env[...] является записью в связанное системное значение. Это не локальная копия для конкретного обработчика.
Тип операции. Если после свойства стоит ->, значение используется как объект — анализируйте методы и свойства этого объекта. Если после свойства стоит [...], значение используется как массив. Если свойство стоит слева от =, выполняется запись. Все три формы могут встречаться в одном проекте, но каждая требует отдельной проверки контекста.
Г. Почему точка Cot::init() имеет значение
Фасад не освобождает разработчика от анализа порядка исполнения. Документация по хукам перечисляет множество точек вызова, а common.php показывает место инициализации фасада. Если обработчик запускается в штатном потоке после bootstrap, фасад может использоваться согласно этому механизму. Если код запускается в иной точке, наличие класса Cot само по себе не доказывает, что нужное свойство уже связано.
Д. Заметки по отдельным свойствам
Основные свойства и их привязки описаны в каталоге свойств и справочной таблице основного текста. Ниже — только уточнения, специфичные для анализа.
| Свойство | Ключевой момент при анализе |
|---|---|
Cot::$db | Не создаёт соединение; связывается с уже созданным $db. Дальше — API объекта CotDB. |
Cot::$cache | Объект кэша; цепочки вида $cache->db->store(...) относятся к объекту, не к фасаду. |
Cot::$env | Массив окружения; маршрутизатор пишет ext, type, location. |
Cot::$out | Связанный массив; в init() гарантируются ключи head и subtitle при отсутствии. |
Cot::$cfg | Конфигурационный массив; конкретные ключи подтверждать кодом. |
Cot::$sys | Временные системные переменные; конкретный ключ — только из кода. |
Cot::$usr | Текущий пользователь; не расширять описание за пределы PHPDoc и использований. |
Cot::$structure | Дерево структуры; набор ключей не выдумывать. |
Cot::$L | Языковые строки. |
Cot::$R | Ресурсные строки. |
Cot::$extrafields | Свойство называется $extrafields, глобал — $cot_extrafields. |
Cot::$db_x | Префикс имён таблиц; не смешивать с объектом $db. |
Cot::$currentRoute | Отдельное static-свойство (?Route, начальное null); нет привязки в init(). |
Cot::$id | Отсутствует в классе и в init(). Документация по хукам упоминает $id среди глобалов, но фасад его не предоставляет. |
Е. Фасад в расширениях и маршрутизаторе
Plugin hook. Обработчик — PHP-файл расширения. Для системных данных ($db, $cfg, $usr, $env и др.) после штатной инициализации фасада можно использовать Cot::$... вместо global $.... Фасад не заменяет локальные параметры обработчика и не определяет точку вызова хука.
Module hook. Правило то же: определите хук или контроллерную точку, затем для системных данных используйте соответствующее свойство Cot. Фасад не определяет точку вызова модуля и не заменяет механизм хуков.
Маршрутизатор. Записывает в связанный массив окружения:
Cot::$env['ext'] = $extensionCode;
Cot::$env['type'] = $extensionType;
// location — в зависимости от типа расширенияФакт записи показывает, что фасад используется как изменяемая точка системного состояния. Дальнейшую семантику нужно подтверждать кодом чтения.
Ж. Поиск в исходниках и ревью кода
Как искать фасад. Начинайте с объявления свойства в Cot.php, затем строки привязки в init(), затем места вызова Cot::init(), затем реальных обращений Cot::$.... Так строится проверяемая цепочка.
Как делать ревью с Cot::$. Для каждого обращения проверяйте: объявлено ли свойство; есть ли привязка в init(); выполнен ли init() до данного места; корректно ли разобрана цепочка (::$property->method vs ::$property['key']); не перепутан ли объект фасада со свойствами/методами полученного объекта. Не приписывайте фасаду функции, которых в коде нет.
Comments (0)
Content author
Offline
Administrator
Last logged: 2026-08-31 04:06
- Page published: 2026-08-31 03:08
- Last update: 2026-08-31 03:16
Связанные статьи
Фасад Cot в Cotonti 1.0: полное справочное руководство
Фасад Cot в Cotonti 1.0: полное справочное руководствоОглавлениеВведениеЧто такое фасад в контексте