git / code.ach.gov.ru / kabakov_iv / bitrix_php_code_standarts
commit 8ec1dd09ffede4257039a62fd04d8fb001d21086
author kabakov_iv <kabakov.i@yandex.ru>
date 2026-05-12 13:03:15 +0300
parents 22653eff
message
небольшие правки
files
| file | add | del |
|---|---|---|
| README.md | +3 | -3 |
| src/05-arrays.md | +1 | -2 |
| src/10-database.md | +4 | -10 |
| src/13-comments.md | +1 | -1 |
| src/14-general.md | +11 | -1 |
| src/15-events.md | +2 | -2 |
| src/16-logging.md | +8 | -7 |
| src/tips/isset-vs-empty.md | +2 | -17 |
patch
diff --git a/README.md b/README.md
index d55f19371d6bac82fd63428aacf09f7d64c68575..80a08b93be3d6ad175bc6f0f2b5481bcfcccdce4 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# PHP Team Code Standards
-> Корпоративные правила написания кода для команды Битрикс24-разработки
+> Корпоративные правила `АНО "Цифровой аудит"` написания кода для команды Битрикс24-разработки
[](https://www.php.net/)
[](https://www.bitrix24.ru/)
@@ -24,7 +24,7 @@
### Структура документации
```
-README.md ← описание репозитория (этот файл)
+README.md ← этот файл
src/
index.md ← вступление и полное оглавление
01-naming.md
@@ -60,7 +60,7 @@
| Версия | Дата | Изменения |
|--------|------|-----------|
| 2.0 | 2026 | Исправленная и дополненная редакция |
-| 1.0 | — | Первая версия |
+| 1.0 | 2026 | Первая версия |
---
diff --git a/src/05-arrays.md b/src/05-arrays.md
index 0f3f9f25b00eb998d432c4ce930bf4ef5a776191..dd8521a5998ab91d9204165ac6746d8c1fc2a4cb 100755
--- a/src/05-arrays.md
+++ b/src/05-arrays.md
@@ -56,8 +56,7 @@ ```
**ХОРОШО — ILLUMINATE/COLLECTIONS**
```php
-use Illuminate\Support\Collection;
-$totalSum = Collection::make($dealProducts)
+$totalSum = collect($dealProducts)
->sum(fn($row) => $row['PRICE'] * $row['QUANTITY']);
```
diff --git a/src/10-database.md b/src/10-database.md
index 46e51add48d932413f53bb8b871ee43846c3d6ff..4105e6d0e5f5e94fe6b1a5494a8b92ae5e7a2747 100755
--- a/src/10-database.md
+++ b/src/10-database.md
@@ -4,9 +4,9 @@ [← Оглавление](./index.md)
---
-## Репозиторий инкапсулирует работу с данными
+## В объемных (по количеству кода) сервисах Репозиторий инкапсулирует работу с данными
-**ПЛОХО — ORM-ЗАПРОСЫ РАЗБРОСАНЫ ПО СЕРВИСАМ**
+**ПЛОХО — ORM-ЗАПРОСЫ РАЗБРОСАНЫ ПО СЕРВИСАМ И ТАКИХ МЕТОДОВ МОЖЕТ БЫТЬ МНОГО**
```php
class DealReportService {
public function getWonDealsSum(): float {
@@ -27,7 +27,7 @@ }
}
```
-**ХОРОШО — ПАТТЕРН REPOSITORY**
+**ХОРОШО — ПАТТЕРН REPOSITORY, ВСЯ ЛОГИКА РАБОТЫ С БД ВЫНЕСЕНА В ОТДЕЛЬНЫЙ КЛАСС**
```php
interface DealRepository {
public function getTotalWonOpportunity(): float;
@@ -119,13 +119,7 @@ ---
## fetchCollection() и работа с объектами
-**ПЛОХО — НЕСУЩЕСТВУЮЩИЙ МЕТОД КОЛЛЕКЦИИ**
-```php
-$leadCollection = \Bitrix\Crm\LeadTable::getList(['select' => ['*']])->fetchCollection();
-$titles = $leadCollection->getTitleList(); // метод не существует!
-```
-
-**ХОРОШО — ГЕТТЕРЫ ЧЕРЕЗ GETALL()**
+**ГЕТТЕРЫ ДОСТУПНЫ ЧЕРЕЗ GETALL()**
```php
$leadCollection = \Bitrix\Crm\LeadTable::query()
->setSelect(['ID', 'TITLE'])
diff --git a/src/13-comments.md b/src/13-comments.md
index 2405d42a962dfa62fb936d344494488fd3cc14dd..cc43413021618ecd08bdbbf4fe6c4486dc0f5c47 100755
--- a/src/13-comments.md
+++ b/src/13-comments.md
@@ -17,7 +17,7 @@
**ХОРОШО — ИМЯ ГОВОРИТ САМО ЗА СЕБЯ, КОММЕНТАРИЙ ОБЪЯСНЯЕТ БИЗНЕС-ПРАВИЛО**
```php
$totalPrice = $product->getPrice() * $product->getQuantity();
-// Скидка для VIP-клиентов введена с Q1 2024 (см. задачу PROJ-1234)
+// Скидка для VIP-клиентов введена с Q1 2026 (см. задачу 1234)
if ($client->isVip()) {
$totalPrice *= (1 - self::VIP_DISCOUNT_RATE);
}
diff --git a/src/14-general.md b/src/14-general.md
index 142d2c6aea60f493be9e145a32a5d9015cb3d2dc..38a4761190b070e261f7b2f8d2491c2c1b2a4984 100755
--- a/src/14-general.md
+++ b/src/14-general.md
@@ -4,7 +4,7 @@ [← Оглавление](./index.md)
---
-## DRY — не дублируйте знания
+## DRY — не дублируйте код (как минимум, в одном модуле)
**ПЛОХО — ОДНА И ТА ЖЕ ЛОГИКА В ДВУХ МЕСТАХ**
```php
@@ -53,6 +53,16 @@ public function getContactCompanyCity(): ?string {
return $this->getContact()?->getCompany()?->getCity();
}
```
+### Практическое правило
+
+> Считай точки в цепочке. **Больше одной точки** — повод задуматься.
+
+`$a->b()` — ок
+`$a->b()->c()` — уже подозрительно
+`$a->b()->c()->d()` — точно нарушение
+
+*(Исключение: Fluent Interface / Builder, где `$query->select()->where()->limit()` — это один объект, возвращающий сам себя)*
+
---
diff --git a/src/15-events.md b/src/15-events.md
index 7a69e70a2e36231006d59beeae17e781f984f9b8..cf7351fe2f73af00395310d9c7c6a9d361f9e6b7 100755
--- a/src/15-events.md
+++ b/src/15-events.md
@@ -30,7 +30,7 @@ ->notifyOnLeadCreated((int)$fields['ID']);
}
}
-// Регистрация в init.php:
+// Регистрация в init.php (условно):
\Bitrix\Main\EventManager::getInstance()->addEventHandler(
'crm',
'OnAfterCrmLeadAdd',
@@ -42,7 +42,7 @@ ---
## Современный API событий (Bitrix\Main\Event)
-**ОБЪЕКТНО-ОРИЕНТИРОВАННЫЙ EVENT API**
+**ОБЪЕКТНО-ОРИЕНТИРОВАННЫЙ EVENT API ВМЕСТО AddEventHandler**
```php
\Bitrix\Main\EventManager::getInstance()->addEventHandlerCompatible(
'crm',
diff --git a/src/16-logging.md b/src/16-logging.md
index d85f1be476e338a40a5a1becf8db69d751d5a065..c8d59ade6efa40c3216cd418a015d5e48a18628b 100755
--- a/src/16-logging.md
+++ b/src/16-logging.md
@@ -6,7 +6,7 @@ ---
Инжектируйте PSR-3 `LoggerInterface`. Глобальные функции `AddMessage2Log()` — устаревший подход без уровней и контекста.
-## PSR-3 логирование через Bitrix\Main\Diag\Logger
+## PSR-3 логирование через App\Logger
**ПЛОХО — УСТАРЕВШИЕ ФУНКЦИИ БЕЗ УРОВНЕЙ**
```php
@@ -32,11 +32,13 @@
**ПЛОХО — КОНКРЕТНАЯ РЕАЛИЗАЦИЯ В КОНСТРУКТОРЕ**
```php
class LeadCreationService {
- private \Bitrix\Main\Diag\Logger $logger;
+ private $logger;
public function __construct() {
// нельзя подменить в тестах, привязка к реализации
- $this->logger = \Bitrix\Main\Diag\Logger::create('crm', '/local/logs/crm.log');
+ $this->logger = ServiceLocator::getInstance()
+ ->get('da.main.logger')
+ ->getLogger($channel, $module);;
}
}
```
@@ -60,9 +62,8 @@
// Регистрация в ServiceLocator:
ServiceLocator::getInstance()->addInstanceLazy(
LoggerInterface::class,
- fn() => \Bitrix\Main\Diag\Logger::create(
- 'app',
- '/local/logs/app_' . date('Y-m-d') . '.log'
- )
+ fn() => ServiceLocator::getInstance()
+ ->get('da.main.logger')
+ ->getLogger($channel, $module);
);
```
diff --git a/src/tips/isset-vs-empty.md b/src/tips/isset-vs-empty.md
index c69a22d408004034ba3665de1ffd86a09d81c7cc..4155030b98ef0f7ce7e1fa3edd2e766795215889 100755
--- a/src/tips/isset-vs-empty.md
+++ b/src/tips/isset-vs-empty.md
@@ -124,22 +124,7 @@ ```
---
-### 4. `empty()` принимает выражения (начиная с PHP 5.5)
-
-Начиная с **PHP 5.5** в `empty()` можно передавать не только переменные, но и произвольные выражения, включая вызовы функций:
-
-```php
-// Работает начиная с PHP 5.5 — никакой ошибки нет
-if (empty(trim($name))) {
- echo 'Имя не указано';
-}
-```
-
-> До PHP 5.5 это действительно вызывало Fatal error — но все актуальные версии (7.x, 8.x) поддерживают такой синтаксис без ограничений.
-
----
-
-### 5. `isset()` и магический метод `__isset()` на объектах
+### 4. `isset()` и магический метод `__isset()` на объектах
При вызове `isset($object->property)` на недоступном (private/protected) или несуществующем свойстве PHP вызывает магический метод `__isset()`. Это важно при работе с ORM, ActiveRecord и Bitrix-сущностями:
@@ -159,7 +144,7 @@ Если класс не реализует `__isset()`, обращение к недоступному свойству через `isset()` просто вернёт `false` без ошибок.
---
-### 6. Внутренняя логика `empty()`
+### 5. Внутренняя логика `empty()`
По сути, `empty($var)` — это полный безопасный эквивалент `!isset($var) || $var == false`. Обратите внимание: используется **нестрогое сравнение `==`**. Именно поэтому `"0"`, `0`, `0.0`, `""` и `[]` приравниваются к `false`.