bitrix-best-practice-core

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Bitrix Core Best Practice

Bitrix核心最佳实践

Скилл помогает понять, какие нужно использовать Bitrix/PHP best practices.
本技能可帮助你了解应采用哪些Bitrix/PHP最佳实践。

Как использовать

使用方法

  1. Определи архитектурный слой, который затрагивает задача.
  2. Открой только те rule-файлы, которые напрямую относятся к этому слою.
  3. Сначала следуй более строгим правилам репозитория и ограничениям модуля.
  4. Предпочитай framework-native паттерны Bitrix вместо собственных абстракций.
  1. 确定任务涉及的架构层。
  2. 仅打开与该架构层直接相关的规则文件(rule-файлы)。
  3. 优先遵循仓库的更严格规则和模块限制。
  4. 优先使用Bitrix原生框架模式,而非自定义抽象。

Выбор rule-файла

规则文件选择

<!-- rules-dictionary:start -->
<!-- rules-dictionary:start -->

Когда читать
rules/controller.md

何时阅读
rules/controller.md

Читай
rules/controller.md
, если задача затрагивает хотя бы одну из этих областей:
  • класс, наследующий
    Bitrix\Main\Engine\Controller
    или его наследника;
  • любой
    *Action()
    -метод;
  • filters, attributes, prefilters и ответы Engine Controller.
若任务涉及以下任一领域,请阅读
rules/controller.md
  • 继承自
    Bitrix\Main\Engine\Controller
    或其子类的类;
  • 任意
    *Action()
    方法;
  • Engine Controller的过滤器(filters)、属性(attributes)、预过滤器(prefilters)及响应。

Когда читать
rules/error.md

何时阅读
rules/error.md

Читай
rules/error.md
, если задача затрагивает хотя бы одну из этих областей:
  • Bitrix\Main\Error
    ,
    Bitrix\Main\ErrorCollection
    или прикладные error-классы поверх них;
  • getErrors()
    ,
    getError()
    ,
    getErrorCollection()
    или
    getErrorByCode()
    в service, controller или response flow;
  • выбор
    code
    ,
    customData
    и публичного error-contract для UI, AJAX или другого клиента;
  • перенос уже созданных ошибок между
    Result
    , controller lifecycle и
    AjaxJson
    .
若任务涉及以下任一领域,请阅读
rules/error.md
  • Bitrix\Main\Error
    Bitrix\Main\ErrorCollection
    或基于它们的业务错误类;
  • service、controller或响应流程中的
    getErrors()
    getError()
    getErrorCollection()
    getErrorByCode()
    方法;
  • 为UI、AJAX或其他客户端选择
    code
    customData
    及公开错误契约;
  • Result
    、controller生命周期与
    AjaxJson
    之间传递已创建的错误。

Когда читать
rules/result.md

何时阅读
rules/result.md

Читай
rules/result.md
, если задача затрагивает хотя бы одну из этих областей:
  • Bitrix\Main\Result
    ,
    isSuccess()
    ,
    setData()
    ,
    getData()
    ,
    addError()
    или
    addErrors()
    ;
  • возврат
    Result
    из service, command, handler или integration layer как outcome-contract;
  • выбор между
    Bitrix\Main\Result
    , самодельным
    *Result
    -классом и неявным массивом как return DTO;
  • состав payload в
    Result::setData()
    и граница между success-data и error flow.
若任务涉及以下任一领域,请阅读
rules/result.md
  • Bitrix\Main\Result
    isSuccess()
    setData()
    getData()
    addError()
    addErrors()
  • 从service、command、handler或集成层返回
    Result
    作为结果契约;
  • Bitrix\Main\Result
    、自定义
    *Result
    类与隐式数组之间选择返回DTO;
  • Result::setData()
    中的负载构成,以及成功数据与错误流程的边界。

Когда читать
rules/request.md

何时阅读
rules/request.md

Читай
rules/request.md
, если задача затрагивает хотя бы одну из этих областей:
  • Bitrix\Main\Request
    ,
    HttpRequest
    ,
    $this->getRequest()
    или
    Context::getCurrent()->getRequest()
    ;
  • выбор между
    get()
    ,
    getQuery()
    ,
    getPost()
    ,
    getHeader()
    ,
    getCookie()
    или
    getJsonList()
    ;
  • замена
    $_REQUEST
    ,
    $_GET
    ,
    $_POST
    ,
    $_COOKIE
    и
    php://input
    на framework-native request API;
  • JSON body,
    JsonPayload
    ,
    decodeJson()
    или
    decodeJsonStrict()
    .
若任务涉及以下任一领域,请阅读
rules/request.md
  • Bitrix\Main\Request
    HttpRequest
    $this->getRequest()
    Context::getCurrent()->getRequest()
  • get()
    getQuery()
    getPost()
    getHeader()
    getCookie()
    getJsonList()
    之间选择使用;
  • 使用框架原生request API替代
    $_REQUEST
    $_GET
    $_POST
    $_COOKIE
    php://input
  • JSON请求体、
    JsonPayload
    decodeJson()
    decodeJsonStrict()

Когда читать
rules/response.md

何时阅读
rules/response.md

Читай
rules/response.md
, если задача затрагивает хотя бы одну из этих областей:
  • Bitrix\Main\Response
    ,
    HttpResponse
    ,
    addHeader()
    ,
    setStatus()
    ,
    addCookie()
    или
    redirectTo()
    ;
  • Bitrix\Main\Engine\Response\Json
    ,
    AjaxJson
    ,
    Redirect
    ,
    File
    ,
    HtmlContent
    или render-response helper'ы;
  • замена ручного
    header()
    ,
    Set-Cookie
    ,
    setcookie()
    или
    json_encode()
    на штатный response layer Bitrix;
  • выбор типа HTTP-ответа для controller action или другого infrastructure endpoint.
若任务涉及以下任一领域,请阅读
rules/response.md
  • Bitrix\Main\Response
    HttpResponse
    addHeader()
    setStatus()
    addCookie()
    redirectTo()
  • Bitrix\Main\Engine\Response\Json
    AjaxJson
    Redirect
    File
    HtmlContent
    或渲染响应助手;
  • 使用Bitrix原生响应层替代手动
    header()
    Set-Cookie
    setcookie()
    json_encode()
  • 为controller action或其他基础设施端点选择HTTP响应类型。

Когда читать
rules/routing.md

何时阅读
rules/routing.md

Читай
rules/routing.md
, если задача затрагивает хотя бы одну из этих областей:
  • файл в
    <module>/install/routes/
    или регистрация маршрутов в
    /bitrix/routes/
    и
    /local/routes/
    ;
  • RoutingConfigurator
    ,
    prefix
    ,
    group
    , HTTP-методы маршрута,
    where
    ,
    default
    ,
    name
    ;
  • PublicPageController
    или перенос legacy URL с
    urlrewrite.php
    на modern routing;
  • site-guard и маршруты для конкретного сайта в мультисайтовой установке;
  • массив
    [Controller::class, 'action']
    в маршруте.
若任务涉及以下任一领域,请阅读
rules/routing.md
  • <module>/install/routes/
    下的文件,或在
    /bitrix/routes/
    /local/routes/
    中注册路由;
  • RoutingConfigurator
    prefix
    group
    、路由HTTP方法、
    where
    default
    name
  • PublicPageController
    或通过
    urlrewrite.php
    将旧版URL迁移至现代路由;
  • 多站点安装中的站点防护与特定站点路由;
  • 路由中的
    [Controller::class, 'action']
    数组。

Когда читать
rules/loader.md

何时阅读
rules/loader.md

Читай
rules/loader.md
, если задача затрагивает хотя бы одну из этих областей:
  • Loader::includeModule()
    или
    Loader::requireModule()
    ;
  • CModule::IncludeModule()
    или
    CModule::IncludeModuleEx()
    ;
  • optional module integration с fallback при отсутствии модуля;
  • fail-fast dependency, где отсутствие модуля должно привести к ошибке, а не к тихому пропуску.
若任务涉及以下任一领域,请阅读
rules/loader.md
  • Loader::includeModule()
    Loader::requireModule()
  • CModule::IncludeModule()
    CModule::IncludeModuleEx()
  • 可选模块集成,模块不存在时提供降级方案;
  • 快速失败依赖,模块不存在时应触发错误而非静默跳过。

Когда читать
rules/geo-ip.md

何时阅读
rules/geo-ip.md

Читай
rules/geo-ip.md
, если задача затрагивает хотя бы одну из этих областей:
  • Bitrix\Main\Service\GeoIp\Manager
    ,
    getRealIp()
    ,
    getDataResult()
    или convenience getters вроде
    getCountryCode()
    /
    getCityName()
    ;
  • Bitrix\Main\Web\IpAddress
    в контексте GeoIP lookup, range cache или различий между IPv4 и IPv6 для geodata;
  • custom GeoIP handler, наследник
    Bitrix\Main\Service\GeoIp\Base
    или регистрация через
    onMainGeoIpHandlersBuildList
    ;
  • post-processing GeoIP результата через
    onGeoIpGetResult
    ;
  • выбор между простым string lookup и полным
    Result
    -based GeoIP lookup.
  • определение геолокации
若任务涉及以下任一领域,请阅读
rules/geo-ip.md
  • Bitrix\Main\Service\GeoIp\Manager
    getRealIp()
    getDataResult()
    getCountryCode()
    /
    getCityName()
    等便捷获取方法;
  • GeoIP查询、范围缓存或IPv4与IPv6地理数据差异场景下的
    Bitrix\Main\Web\IpAddress
  • 继承自
    Bitrix\Main\Service\GeoIp\Base
    的自定义GeoIp处理器,或通过
    onMainGeoIpHandlersBuildList
    注册;
  • 通过
    onGeoIpGetResult
    对GeoIP结果进行后处理;
  • 在简单字符串查询与完整基于
    Result
    的GeoIP查询之间选择;
  • 地理位置识别

Когда читать
rules/uri.md

何时阅读
rules/uri.md

Читай
rules/uri.md
, если задача затрагивает хотя бы одну из этих областей:
  • Bitrix\Main\Web\Uri
    ,
    new Uri($url)
    ,
    getQuery()
    ,
    addParams()
    ,
    deleteParams()
    ,
    toAbsolute()
    или
    resolveRelativeUri()
    ;
  • разбор, изменение или пересборка URL / URI / redirect URL в Bitrix-коде;
  • выбор между
    Uri
    ,
    parse_url()
    и
    parse_str()
    для query string, host, path, fragment или absolute URL;
  • query-параметры с точками или пробелами, где важен
    preserveDots
    .
若任务涉及以下任一领域,请阅读
rules/uri.md
  • Bitrix\Main\Web\Uri
    new Uri($url)
    getQuery()
    addParams()
    deleteParams()
    toAbsolute()
    resolveRelativeUri()
  • 在Bitrix代码中解析、修改或重构URL/URI/重定向URL;
  • Uri
    parse_url()
    parse_str()
    之间选择用于查询字符串、主机、路径、片段或绝对URL的处理;
  • 含点或空格的查询参数,需注意
    preserveDots
    参数。

Когда читать
rules/http-client.md

何时阅读
rules/http-client.md

Читай
rules/http-client.md
, если задача затрагивает хотя бы одну из этих областей:
  • Bitrix\Main\Web\HttpClient
    ,
    new HttpClient()
    ,
    get()
    ,
    post()
    ,
    query()
    или
    download()
    ;
  • outbound HTTP(S)-запросы, webhook sender, remote download/upload или external API integration;
  • замена
    file_get_contents($url)
    /
    stream_context_create()
    для remote
    http
    /
    https
    URL;
  • замена
    curl_init
    ,
    curl_setopt
    ,
    curl_exec
    и других raw
    curl_*
    вызовов на framework-native transport.
若任务涉及以下任一领域,请阅读
rules/http-client.md
  • Bitrix\Main\Web\HttpClient
    new HttpClient()
    get()
    post()
    query()
    download()
  • 出站HTTP(S)请求、webhook发送、远程下载/上传或外部API集成;
  • 使用框架原生传输层替代
    file_get_contents($url)
    /
    stream_context_create()
    处理远程
    http
    /
    https
    URL;
  • 使用框架原生传输层替代
    curl_init
    curl_setopt
    curl_exec
    等原生
    curl_*
    调用。

Когда читать
rules/jwt.md

何时阅读
rules/jwt.md

Читай
rules/jwt.md
, если задача затрагивает хотя бы одну из этих областей:
  • Bitrix\Main\Web\JWT
    ,
    JWT::encode()
    ,
    JWT::decode()
    ,
    JWT::urlsafeB64Encode()
    или
    JWT::urlsafeB64Decode()
    ;
  • Bitrix\Main\Web\JWK
    ,
    JWK::parseKeySet()
    или
    JWK::parseKey()
    ;
  • выпуск, проверка или разбор JWT / JWK / JWKS / JOSE-compatible данных;
  • выбор между framework-native JWT/JWK API и ручной сборкой токена, key parsing или Base64 URL-safe helper-ом.
若任务涉及以下任一领域,请阅读
rules/jwt.md
  • Bitrix\Main\Web\JWT
    JWT::encode()
    JWT::decode()
    JWT::urlsafeB64Encode()
    JWT::urlsafeB64Decode()
  • Bitrix\Main\Web\JWK
    JWK::parseKeySet()
    JWK::parseKey()
  • JWT/JWK/JWKS/JOSE兼容数据的签发、验证或解析;
  • 在框架原生JWT/JWK API与手动构建令牌、密钥解析或Base64 URL安全助手之间选择。

Когда читать
rules/date-time.md

何时阅读
rules/date-time.md

Читай
rules/date-time.md
, если задача затрагивает хотя бы одну из этих областей:
  • Bitrix\Main\Type\Date
    или
    Bitrix\Main\Type\DateTime
    ;
  • createFromUserTime()
    ,
    tryParse()
    ,
    toUserTime()
    ,
    toString()
    ,
    createFromTimestamp()
    или
    createFromPhp()
    ;
  • parsing, formatting или timestamp conversion для даты и времени в Bitrix-коде;
  • выбор между Bitrix date types и
    \DateTime
    /
    \DateTimeImmutable
    .
若任务涉及以下任一领域,请阅读
rules/date-time.md
  • Bitrix\Main\Type\Date
    Bitrix\Main\Type\DateTime
  • createFromUserTime()
    tryParse()
    toUserTime()
    toString()
    createFromTimestamp()
    createFromPhp()
  • 在Bitrix代码中解析、格式化日期时间或进行时间戳转换;
  • 在Bitrix日期类型与
    \DateTime
    /
    \DateTimeImmutable
    之间选择。

Когда читать
rules/option.md

何时阅读
rules/option.md

Читай
rules/option.md
, если задача затрагивает хотя бы одну из этих областей:
  • Bitrix\Main\Config\Option
    ,
    Option::get()
    ,
    set()
    ,
    getRealValue()
    ,
    getForModule()
    или
    delete()
    ;
  • COption::GetOptionString()
    ,
    SetOptionString()
    ,
    GetOptionInt()
    или
    RemoveOption()
    как legacy trigger;
  • default_option.php
    , module
    options.php
    , site-specific setting или feature flag / policy в БД;
  • выбор между постоянной конфигурацией в
    Option
    , deploy-time config в
    .settings.php
    и временным runtime-state.
若任务涉及以下任一领域,请阅读
rules/option.md
  • Bitrix\Main\Config\Option
    Option::get()
    set()
    getRealValue()
    getForModule()
    delete()
  • 作为旧版触发方式的
    COption::GetOptionString()
    SetOptionString()
    GetOptionInt()
    RemoveOption()
  • default_option.php
    、模块
    options.php
    、站点特定设置或数据库中的功能开关/策略;
  • Option
    中的持久化配置、部署时
    .settings.php
    中的配置与临时运行时状态之间选择。

Когда читать
rules/logger.md

何时阅读
rules/logger.md

Читай
rules/logger.md
, если задача затрагивает хотя бы одну из этих областей:
  • Bitrix\Main\Diag\Logger
    ,
    Bitrix\Main\Diag\LoggerFactory
    ,
    LoggerRegistry
    ,
    FileLogger
    или
    LogFormatter
    ;
  • Psr\Log\LoggerInterface
    , PSR-3 levels (
    info
    ,
    warning
    ,
    error
    ,
    debug
    ) и structured
    context
    ;
  • регистрацию logger id в
    .settings.php
    через секцию
    loggers
    или DI через
    constructorParams
    ;
  • замену
    AddMessage2Log()
    ,
    Logger::create()
    или ad hoc
    file_put_contents()
    /
    error_log()
    на framework-native logging path;
  • выбор между именованным logger id, default logger fallback и legacy logging boundary.
若任务涉及以下任一领域,请阅读
rules/logger.md
  • Bitrix\Main\Diag\Logger
    Bitrix\Main\Diag\LoggerFactory
    LoggerRegistry
    FileLogger
    LogFormatter
  • Psr\Log\LoggerInterface
    、PSR-3日志级别(
    info
    warning
    error
    debug
    )及结构化
    context
  • 通过
    .settings.php
    中的
    loggers
    部分注册日志ID,或通过
    constructorParams
    进行DI注入;
  • 使用框架原生日志方案替代
    AddMessage2Log()
    Logger::create()
    或临时的
    file_put_contents()
    /
    error_log()
  • 在命名日志ID、默认日志降级方案与旧版日志边界之间选择。

Когда читать
rules/uuid-generator.md

何时阅读
rules/uuid-generator.md

Читай
rules/uuid-generator.md
, если задача затрагивает хотя бы одну из этих областей:
  • Bitrix\Main\UuidGenerator
    или
    UuidGenerator::generateV4()
    ;
  • генерацию UUID v4 для session id, correlation id, upload token, public proxy id или другого random opaque identifier;
  • выбор между
    UuidGenerator
    ,
    uniqid()
    ,
    Random::getBytes()
    , ручной сборкой UUID или локальным helper-генератором;
  • legacy boundary, где нужен UUID в обертке вроде
    {uuid}
    , но canonical generator должен остаться единым.
若任务涉及以下任一领域,请阅读
rules/uuid-generator.md
  • Bitrix\Main\UuidGenerator
    UuidGenerator::generateV4()
  • 为会话ID、关联ID、上传令牌、公共代理ID或其他随机不透明标识符生成UUID v4;
  • UuidGenerator
    uniqid()
    Random::getBytes()
    、手动构建UUID或本地助手生成器之间选择;
  • 旧版边界场景,需将UUID包装为
    {uuid}
    格式,但标准生成器需保持统一。

Когда читать
rules/validation.md

何时阅读
rules/validation.md

Читай
rules/validation.md
, если задача затрагивает хотя бы одну из этих областей:
  • Bitrix\Main\Validation\Rule\...
    на параметрах
    *Action()
    или свойствах input object;
  • ValidationParameter
    ,
    ValidationService
    ,
    ValidationResult
    ,
    ValidationError
    или
    ValidationGroup
    ;
  • автоматическая валидация входа до входа в action или ручная валидация DTO / command в service layer;
  • выбор между validation attributes,
    ValidationParameter
    и явным
    ValidationService::validate()
    ;
  • custom validators и custom validation attributes поверх
    Bitrix\Main\Validation
    .
若任务涉及以下任一领域,请阅读
rules/validation.md
  • *Action()
    参数或输入对象属性上的
    Bitrix\Main\Validation\Rule\...
    规则;
  • ValidationParameter
    ValidationService
    ValidationResult
    ValidationError
    ValidationGroup
  • 在进入action前自动验证输入,或在service层手动验证DTO/command;
  • 在验证属性、
    ValidationParameter
    与显式
    ValidationService::validate()
    之间选择;
  • 基于
    Bitrix\Main\Validation
    的自定义验证器与自定义验证属性。

Когда читать
rules/service-locator.md

何时阅读
rules/service-locator.md

Читай
rules/service-locator.md
, если задача затрагивает хотя бы одну из этих областей:
  • Bitrix\Main\DI\ServiceLocator
    ,
    ServiceLocator::getInstance()
    ,
    get()
    ,
    has()
    ,
    addInstance()
    или
    addInstanceLazy()
    ;
  • {module}/.settings.php
    , service registration, service id, FQCN binding или interface binding для DI;
  • выбор между action autowiring, explicit
    ServiceLocator::get(...)
    и ручным
    new MyService()
    для shared service;
  • замена ad hoc создания service-класса на framework-native container path.
若任务涉及以下任一领域,请阅读
rules/service-locator.md
  • Bitrix\Main\DI\ServiceLocator
    ServiceLocator::getInstance()
    get()
    has()
    addInstance()
    addInstanceLazy()
  • {module}/.settings.php
    、服务注册、服务ID、FQCN绑定或DI接口绑定;
  • 在action自动注入、显式
    ServiceLocator::get(...)
    与手动
    new MyService()
    之间选择共享服务的获取方式;
  • 使用框架原生容器方案替代临时创建service类。

Когда читать
rules/persistent-storage.md

何时阅读
rules/persistent-storage.md

Читай
rules/persistent-storage.md
, если задача затрагивает хотя бы одну из этих областей:
  • Bitrix\Main\Data\Storage\PersistentStorageInterface
    ,
    StorageInterface
    ,
    DeferredStorageDecorator
    или
    ServiceLocator::get(PersistentStorageInterface::class)
    ;
  • Bitrix\Main\Config\Option::get()
    /
    Option::set()
    в сценарии, где нужно понять, конфигурация это или временное runtime-state;
  • TTL state, progress/checkpoint, one-time token, upload/import session, rate-limit counter или другой временный server-side state между запросами;
  • выбор между
    Option
    , persistent storage и cache (
    Bitrix\Main\Data\Cache
    /
    ManagedCache
    ) для хранения данных.
若任务涉及以下任一领域,请阅读
rules/persistent-storage.md
  • Bitrix\Main\Data\Storage\PersistentStorageInterface
    StorageInterface
    DeferredStorageDecorator
    ServiceLocator::get(PersistentStorageInterface::class)
  • 需要区分是配置还是临时运行时状态场景下的
    Bitrix\Main\Config\Option::get()
    /
    Option::set()
  • 请求间的TTL状态、进度/检查点、一次性令牌、上传/导入会话、速率限制计数器或其他临时服务器端状态;
  • Option
    、持久化存储与缓存(
    Bitrix\Main\Data\Cache
    /
    ManagedCache
    )之间选择数据存储方式。

Когда читать
rules/cache.md

何时阅读
rules/cache.md

Читай
rules/cache.md
, если задача затрагивает хотя бы одну из этих областей:
  • Bitrix\Main\Data\Cache
    ,
    ManagedCache
    ,
    TaggedCache
    ,
    Cache::createInstance()
    ,
    initCache()
    ,
    startDataCache()
    ,
    endDataCache()
    или
    abortDataCache()
    ;
  • Application::getInstance()->getCache()
    ,
    getManagedCache()
    ,
    getTaggedCache()
    или container binding cache-сервисов в
    main/.settings.php
    ;
  • выбор между простым TTL-cache, managed invalidation по key/dir и tag-based invalidation;
  • CPHPCache
    ,
    CCacheManager
    ,
    $CACHE_MANAGER
    или
    CStackCacheManager
    как legacy trigger;
  • derived read-cache, который можно потерять и пересчитать, в отличие от runtime-state и постоянной конфигурации.
<!-- rules-dictionary:end -->
若任务涉及以下任一领域,请阅读
rules/cache.md
  • Bitrix\Main\Data\Cache
    ManagedCache
    TaggedCache
    Cache::createInstance()
    initCache()
    startDataCache()
    endDataCache()
    abortDataCache()
  • Application::getInstance()->getCache()
    getManagedCache()
    getTaggedCache()
    main/.settings.php
    中的容器缓存服务绑定;
  • 在简单TTL缓存、基于键/目录的托管失效与基于标签的失效之间选择;
  • 作为旧版触发方式的
    CPHPCache
    CCacheManager
    $CACHE_MANAGER
    CStackCacheManager
  • 派生只读缓存,可丢失并重新计算,区别于运行时状态与持久化配置。
<!-- rules-dictionary:end -->