bitrix-request-response
HttpRequest/HttpResponse, Json/AjaxJson/Redirect, Uri, UuidGenerator. Use instead of $_GET/$_POST and raw headers.
Install
npx skills add https://github.com/bxmaximum/bitrix-framework-skills/tree/main/skills/bitrix-request-response
claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install bxmaximum-bitrix-framework-skills@llmmart
git clone https://github.com/bxmaximum/bitrix-framework-skills.git
The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole bxmaximum/bitrix-framework-skills collection as a plugin from our marketplace. Git is the plain clone.
Skill manifest
Application, Context, Request, Response
Baseline: main 23.0+. Features newer than baseline are marked Since.
Progressive disclosure: open only the rule files that match the task. Do not read every rules/*.md.
How to use
- Identify the layer the task touches.
- Open the matching
rules/*.mdbelow. - Prefer framework-native Bitrix patterns over custom abstractions.
Choose a rule file
When to read rules/application-context.md
Read rules/application-context.md (Application and Context) when the task involves:
- Application
- Context
When to read rules/request.md
Read rules/request.md (HttpRequest and JSON body) when the task involves:
- HttpRequest
- ParameterDictionary
When to read rules/response.md
Read rules/response.md (HttpResponse and typed responses) when the task involves:
- HttpResponse
- Built-in Response Classes
- Checklist
- Encrypted Cookies
When to read rules/uri-uuid.md
Read rules/uri-uuid.md (Uri and UuidGenerator) when the task involves:
- Uri
- UuidGenerator
Converter (not covered by rule files)
Bitrix\Main\Engine\Response\Converter converts strings/arrays via bitmask flags: TO_SNAKE, TO_SNAKE_DIGIT, TO_CAMEL, TO_UPPER, TO_LOWER, LC_FIRST, UC_FIRST, KEYS, VALUES, RECURSIVE. Methods: process($data), getFormat() / setFormat($format), static toJson().
Converter::OUTPUT_JSON_FORMAT = KEYS | RECURSIVE | TO_CAMEL | LC_FIRST — it camelCases array keys only (no VALUES flag); values keep their original case:
use Bitrix\Main\Engine\Response\Converter;
(new Converter(Converter::LC_FIRST | Converter::TO_CAMEL))->process('la_la_land'); // laLaLand
(new Converter(Converter::OUTPUT_JSON_FORMAT))->process([
'CATEGORIES' => [['ID' => 1, 'NAME' => 'Foods']],
]);
// ['categories' => [['id' => 1, 'name' => 'Foods']]] — 'Foods' stays untouched (no VALUES flag)
Checklist
- Opened only the rule file(s) needed for this task.
- Followed DI /
/local// security canons fromAGENTS.md.
Files (bitrix-framework-skills)
-
rules
-
application-context.md 1.3 KB
# Application and Context ## Application A singleton per hit, configures the kernel, provides access to general services. ```php use Bitrix\Main\Application; $app = Application::getInstance(); $app->getContext(); // current context $app->getManagedCache(); // managed cache $app->getTaggedCache(); // tagged cache $app->getSession(); // session object (see bitrix-sessions) $app->getConnection(); // primary DB connection $app->getConnection('log'); // connection by name from connections $app->getKernelSession(); // kernel session $app->addBackgroundJob(fn () => /* ... */); // see bitrix-background-jobs ``` Descendants: `HttpApplication` (HTTP hit), `CliApplication` (CLI hit — `bitrix.php`). ## Context An "envelope" for a single request: `Request`, `Response`, `Server`, language, `Culture`, site. ```php use Bitrix\Main\Context; $ctx = Context::getCurrent(); $ctx->getRequest(); // HttpRequest $ctx->getResponse(); // HttpResponse $ctx->getServer(); // Server (wrapper over $_SERVER) $ctx->getCulture(); // regional formats $ctx->getLanguage(); // 'ru' $ctx->getSite(); // 's1' $ctx->getEnvironment(); ``` `Context::getCurrent()` is a shorter alias for `Application::getInstance()->getContext()`. -
request.md 3 KB
# HttpRequest and JSON body ## HttpRequest Inherits from `ParameterDictionary`: `$request['id']` is filtered, `$request->get('id')` is too. ### Parameters Prefer `$this->getRequest()` (in controllers) or `Context::getCurrent()->getRequest()` over `$_GET` / `$_POST` / `$_REQUEST` / `$_COOKIE`. When the source is known, use the specific API — do not merge via `get()` / `$_REQUEST` unless the contract truly accepts either: | Source | API | | --- | --- | | Query string | `getQuery()` / `getQueryList()` | | Form body | `getPost()` / `getPostList()` | | Header | `getHeader()` / `getHeaders()` | | Cookie | `getCookie()` / `getCookieList()` (`getCookieRaw*` only when raw is required) | | Merged (compatibility) | `get()` — only when source truly does not matter | ```php $request = Context::getCurrent()->getRequest(); $id = (int)$request->getQuery('id'); $title = (string)$request->getQuery('title'); $body = (string)$request->getPost('body'); $file = $request->getFile('upload'); $token = $request->getHeader('X-Auth-Token'); $cookie = $request->getCookie('BITRIX_SM_GUEST_ID'); $query = $request->getQueryList(); $post = $request->getPostList(); $files = $request->getFileList(); ``` - `$request['x']` returns a value processed by system filters (proactive). This **does not** protect against SQL injections/XSS — escape yourself. - For typed input, a Request DTO wired with `ValidationParameter` in `getAutoWiredParameters()` is preferred (see `bitrix-validation`). It is an AutoWire rule, not a parameter attribute. ### JSON body | Need | API | | --- | --- | | Controller action JSON contract | `JsonPayload` autowire, or `JsonController` / `ContentType` filter | | Decoded list/array from body | `isJson()` + `getJsonList()` | | Tolerant decode (invalid/empty OK) | `decodeJson()` | | Fail-fast valid `application/json` | `decodeJsonStrict()` | | Raw body (rare) | `getInput()` | Do not `json_decode(file_get_contents('php://input'))` in every action when framework APIs cover the case. ### About the Request ```php $request->getRequestMethod(); // GET|POST|PUT|DELETE $request->isGet(); $request->isPost(); $request->isPut(); $request->isDelete(); $request->isAjaxRequest(); // X-Requested-With: XMLHttpRequest header $request->isHttps(); $request->isAdminSection(); // /bitrix/admin/* $request->getRequestUri(); // '/news/?id=1' $request->getRequestedPage(); // '/news/index.php' $request->getRequestedPageDirectory(); $request->getScriptFile(); $request->getUserAgent(); $request->getAcceptedLanguages(); ``` ### Server ```php $server = Context::getCurrent()->getServer(); $server->get('REMOTE_ADDR'); $server->getHttpHost(); $server->getDocumentRoot(); ``` ## ParameterDictionary `HttpRequest::getQueryList()`, `getPostList()`, `getFileList()` return this object. ```php $params = $request->getPostList(); $params->get('id'); // value $params->getRaw('id'); // value before filters $params->getValues(); // array $params->isEmpty(); // bool $params->offsetExists('id'); // ArrayAccess ``` -
response.md 4.9 KB
# HttpResponse and typed responses ## HttpResponse ```php use Bitrix\Main\HttpResponse; use Bitrix\Main\Web\Cookie; $response = new HttpResponse(); $response->setStatus('201 Created'); $response->addHeader('Content-Type', 'application/json; charset=UTF-8'); $response->addCookie( (new Cookie('VENDOR_TOKEN', $jwt, time() + 3600)) ->setHttpOnly(true) ->setSecure(true) ); $response->setContent(\Bitrix\Main\Web\Json::encode(['ok' => true])); return $response; ``` Methods: - `setStatus(string)`, `getStatus()`. - `addHeader(name, value)`, `setHeaders(HttpHeaders)`, `getHeaders()`. - `addCookie(Cookie $c, bool $replace = true, bool $checkExpires = true)`, `getCookies()`. - `setContent($body)`, `getContent()`. - `flush($text = '')` — send headers and current buffer. - `send($body = null)` — finalization. ## Built-in Response Classes All live in `Bitrix\Main\Engine\Response\*`. Return from controller action or route. Prefer typed responses / controller helpers over `header()`, `setcookie()`, or manual `json_encode`. | Need | Prefer | | --- | --- | | Serializable payload; Engine can wrap | plain `array` / `null` from controller | | Explicit JSON object + HTTP control | `Engine\Response\Json` | | Bitrix envelope `status` / `data` / `errors` | `AjaxJson` | | Redirect | `Redirect` or `$this->redirectTo()` | | View / component / extension | `renderView` / `renderComponent` / `renderExtension` / `Component` | | File download | `BFile` / `File` / `ResizedImage` / `Zip\Archive` | ### JSON ```php use Bitrix\Main\Engine\Response\Json; use Bitrix\Main\Engine\Response\AjaxJson; return new Json(['id' => 42]); // Content-Type: application/json; charset=UTF-8 return AjaxJson::createSuccess(['id' => 42]); // {"status":"success","data":{"id":42},"errors":[]} return AjaxJson::createError(new \Bitrix\Main\Error('Forbidden', 'ACCESS_DENIED')); // {"status":"error","errors":[...]} ``` A controller returning an array is automatically wrapped in `AjaxJson` — manual use is needed in route closures or non-standard endpoints. Do not use `AjaxJson` as a blanket wrapper when a plain `Json` response is enough. ### Redirect ```php use Bitrix\Main\Engine\Response\Redirect; // Constructor: __construct($url, bool $skipSecurity = false) — no status argument return new Redirect('/auth/', skipSecurity: false); $redirect = new Redirect('/auth/'); $redirect->setStatus('301 Moved Permanently'); // status only via setStatus() return $redirect; ``` `Redirect` checks the URL via `CHTTP` and blocks obvious XSS redirects. Do not pass `status:` to the constructor — it is not a named parameter. ### Component ```php use Bitrix\Main\Engine\Response\Component; return new Component('vendor:post.list', '.default', ['SECTION_ID' => 12]); // Response with component HTML + js/css assets — understood by BX.ajax.runAction ``` ### Files ```php use Bitrix\Main\Engine\Response\BFile; // from b_file table return BFile::createByFileId($fileId); use Bitrix\Main\Engine\Response\ResizedImage; return ResizedImage::createByImageId($fileId, 300, 300); use Bitrix\Main\Engine\Response\Zip\Archive; use Bitrix\Main\Engine\Response\Zip\ArchiveEntry; $archive = new Archive('report.zip'); $archive->addEntry(ArchiveEntry::createFromFileId($fileId)); return $archive; // For nginx with mod_zip — delivery without PHP overhead ``` ### HTML Page ```php use Bitrix\Main\Engine\Response\Html; return new Html('<h1>Hi</h1>'); ``` ## Checklist - [ ] `Context` / request API instead of `$_GET`/`$_POST`/`$_COOKIE`/`$_SERVER`. - [ ] Specific getters (`getQuery`/`getPost`/…) when the source is known; JSON via framework APIs. - [ ] Response uses typed classes / helpers (`Json`, `AjaxJson`, `Redirect`, `BFile`) — not raw `header()`. - [ ] Cookies via `Cookie` with `HttpOnly` and `Secure`; headers via `addHeader`. - [ ] URLs via `Uri`; opaque ids via `UuidGenerator::generateV4()`. - [ ] Input treated as untrusted (still validate); large files via `BFile` / `Archive`. ## Encrypted Cookies `Bitrix\Main\Web\CryptoCookie` stores values encrypted on the client. Requires `crypto` key in `.settings.php`: ```php 'crypto' => [ 'value' => ['crypto_key' => '...'], // generate a strong random key; keep outside git 'readonly' => true, ], ``` ```php use Bitrix\Main\Web\Cookie; use Bitrix\Main\Web\CryptoCookie; use Bitrix\Main\Context; $cookie = new CryptoCookie('vendor_token', $token, time() + 86400); $cookie->setHttpOnly(true); $cookie->setSecure(true); $cookie->setSameSite('Lax'); Context::getCurrent()->getResponse()->addCookie($cookie); ``` Reading: `$request->getCookie('vendor_token')` — kernel decrypts automatically when `crypto_key` is configured. For regular (non-encrypted) cookies use `Bitrix\Main\Web\Cookie` with the same security flags. CSRF and cookie policy details: skill `bitrix-security`. Kernel reference: `bitrix/modules/main/lib/web/cookie.php`, `cryptocookie.php` (if present in the project). -
uri-uuid.md 1.5 KB
# Uri and UuidGenerator ## Uri Prefer `Bitrix\Main\Web\Uri` over `parse_url()` + string concat when reading or rebuilding URLs. ```php use Bitrix\Main\Web\Uri; $uri = new Uri('/company/personal/user/15/?tab=tasks'); $uri->addParams(['from' => 'invite', 'success' => 'Y']); $url = (string)$uri; // Keep query names with dots/spaces: $uri->addParams(['a.b' => '1'], preserveDots: true); $uri->deleteParams(['utm_source']); $absolute = (new Uri('/path/'))->toAbsolute(); ``` Also: `resolveRelativeUri()`, IDN via `convertToPunycode()` / `convertToUnicode()`, `isPathTraversal()` for user-supplied paths. There is no public `getQueryParams()` — take `getQuery()` and `parse_str` only when you need an array. Raw `foo=1&bar=2` payloads (no URL parts) may skip `Uri`. ## UuidGenerator For new random opaque identifiers (correlation id, upload token, public proxy id) use `Bitrix\Main\UuidGenerator::generateV4()` — not `uniqid()`, manual `random_bytes` assembly, or a local helper. ```php use Bitrix\Main\UuidGenerator; $id = UuidGenerator::generateV4(); // lowercase, 36 chars, with hyphens ``` - Not for deterministic IDs derived from domain input. - Legacy `{uuid}` wrappers: generate with `generateV4()`, wrap only at the boundary. - External UUIDs used for lookup/access must be validated separately — generation ≠ trust. - `uniqid()` only for local page/request-level DOM-ish ids without crypto/uniqueness requirements. Storage of TTL keys that *use* a UUID: see `bitrix-storage`.
-
-
SKILL.md 2.2 KB
--- name: bitrix-request-response description: HttpRequest/HttpResponse, Json/AjaxJson/Redirect, Uri, UuidGenerator. Use instead of $_GET/$_POST and raw headers. --- # Application, Context, Request, Response Baseline: **main 23.0+**. Features newer than baseline are marked **Since**. Progressive disclosure: open **only** the rule files that match the task. Do not read every `rules/*.md`. ## How to use 1. Identify the layer the task touches. 2. Open the matching `rules/*.md` below. 3. Prefer framework-native Bitrix patterns over custom abstractions. ## Choose a rule file ### When to read `rules/application-context.md` Read `rules/application-context.md` (`Application and Context`) when the task involves: - Application - Context ### When to read `rules/request.md` Read `rules/request.md` (`HttpRequest and JSON body`) when the task involves: - HttpRequest - ParameterDictionary ### When to read `rules/response.md` Read `rules/response.md` (`HttpResponse and typed responses`) when the task involves: - HttpResponse - Built-in Response Classes - Checklist - Encrypted Cookies ### When to read `rules/uri-uuid.md` Read `rules/uri-uuid.md` (`Uri and UuidGenerator`) when the task involves: - Uri - UuidGenerator ## Converter (not covered by rule files) `Bitrix\Main\Engine\Response\Converter` converts strings/arrays via bitmask flags: `TO_SNAKE`, `TO_SNAKE_DIGIT`, `TO_CAMEL`, `TO_UPPER`, `TO_LOWER`, `LC_FIRST`, `UC_FIRST`, `KEYS`, `VALUES`, `RECURSIVE`. Methods: `process($data)`, `getFormat()` / `setFormat($format)`, static `toJson()`. `Converter::OUTPUT_JSON_FORMAT` = `KEYS | RECURSIVE | TO_CAMEL | LC_FIRST` — it camelCases array **keys only** (no `VALUES` flag); values keep their original case: ```php use Bitrix\Main\Engine\Response\Converter; (new Converter(Converter::LC_FIRST | Converter::TO_CAMEL))->process('la_la_land'); // laLaLand (new Converter(Converter::OUTPUT_JSON_FORMAT))->process([ 'CATEGORIES' => [['ID' => 1, 'NAME' => 'Foods']], ]); // ['categories' => [['id' => 1, 'name' => 'Foods']]] — 'Foods' stays untouched (no VALUES flag) ``` ## Checklist - [ ] Opened only the rule file(s) needed for this task. - [ ] Followed DI / `/local/` / security canons from `AGENTS.md`.
Comments (0)
Sign in to join the conversation.
Reviews (0)
No reviews yet.
No comments yet.