{"id":15099169,"url":"https://github.com/andy87/knock-knock","last_synced_at":"2026-01-28T06:36:40.181Z","repository":{"id":239976007,"uuid":"801130210","full_name":"andy87/knock-knock","owner":"andy87","description":"Facade for PHP requests on cURL ","archived":false,"fork":false,"pushed_at":"2024-06-28T06:29:16.000Z","size":1189,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-06-28T07:34:07.845Z","etag":null,"topics":["api","api-client","api-gateway","api-wrapper","curl","curl-library","curlphp","httpclient","php","php-library","php8"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/andy87.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-05-15T16:45:53.000Z","updated_at":"2024-06-28T07:34:12.213Z","dependencies_parsed_at":"2024-06-28T07:44:23.757Z","dependency_job_id":null,"html_url":"https://github.com/andy87/knock-knock","commit_stats":null,"previous_names":["andy87/api_requester","andy87/curl_facade","andy87/knockknock","andy87/knock-knock"],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andy87%2Fknock-knock","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andy87%2Fknock-knock/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andy87%2Fknock-knock/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/andy87%2Fknock-knock/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/andy87","download_url":"https://codeload.github.com/andy87/knock-knock/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240662257,"owners_count":19837364,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","api-client","api-gateway","api-wrapper","curl","curl-library","curlphp","httpclient","php","php-library","php8"],"created_at":"2024-09-25T17:06:58.416Z","updated_at":"2026-01-28T06:36:40.106Z","avatar_url":"https://github.com/andy87.png","language":"PHP","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n\u003ch1 align=\"center\"\u003eKnockKnock\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\u003cimg src=\"assets/logo/KnockKnockLogo_256.png\" style=\"width:256px; height: auto\" alt=\"KnockKnock php curl facade\"/\u003e\u003c/p\u003e\n\nKnockKnock - это простая библиотека, реализующая Фасад и предоставляющая удобный интерфейс для выполнения запросов в PHP,\nиспользуя расширение cURL.  Она упрощает работу, предоставляя более высокоуровневый API и быстрый доступ к настройкам.\n\nЦель: сделать простой и лёгкий в настройке компонента и запроса пакет.\n\nP.S. я знаю про существование таких библиотек как: [Guzzle](https://github.com/guzzle/guzzle), [Client](https://github.com/yiisoft/yii2-httpclient) _(в моём любимом Yii2)_, но хотелось попробовать создать свою реализацию.  \nБез \"лишних\" данных, вызовов и настроек, nullWarningStyle - только то, что нужно: сухо, лаконично, минималистично.  \n_Разумеется, это не конкурент, а просто попытка создать что-то своё_\n\n### Содержание:\n\n - [Установка](#knockknock-setup)\n - [Объект - Базовый класс](#knockknock-src-Operator)\n - [Объект - Запрос](#knockknock-src-Request)\n - [Объект - Ответ](#knockknock-src-Response)\n - [Дополнительные возможности](#knockknock-src-feature)\n - [Расширение на основе базового класса](#knockknock-extends)\n - [Пример Custom реализации](#knockknock-Custom)\n - [Тесты](#knockknock-tests)\n\n___\n\n\u003ch2 align=\"center\"\u003e \u003cspan id=\"knockknock-setup\"\u003e\u003c/span\u003e\n    Установка\n\u003c/h2\u003e\n\n\n\u003ch3\u003eТребования\u003c/h3\u003e \u003cspan id=\"knockknock-setup-require\"\u003e\u003c/span\u003e\n\n- php 8.0\n- ext cURL\n- ext JSON\n\n\n\u003ch3\u003e\n    \u003ca href=\"https://getcomposer.org/download/\"\u003eComposer\u003c/a\u003e\n\u003c/h3\u003e \u003cspan id=\"knockknock-setup-composer\"\u003e\u003c/span\u003e\n\n## Добавление пакета в проект\n\n\u003ch3\u003eИспользуя: консольные команды. \u003ci\u003e(Предпочтительней)\u003c/i\u003e\u003c/h3\u003e\u003cspan id=\"knockknock-setup-composer-cli\"\u003e\u003c/span\u003e\n\n- при composer, установленном локально:\n```bash\ncomposer require andy87/knockknock\n````  \n- при использовании composer.phar:\n```bash\nphp composer.phar require andy87/knockknock\n```\n**Далее:** обновление зависимостей `composer update`\n\n\n\u003ch3\u003eИспользуя: файл `composer.json`\u003c/h3\u003e\u003cspan id=\"knockknock-setup-composer-composer-json\"\u003e\u003c/span\u003e\n\nОткрыть файл `composer.json`  \nВ раздел, ключ `require` добавить строку  \n`\"andy87/knockknock\": \"*\"`  \n**Далее:** обновление зависимостей `composer update`\n\n\n\u003ch2\u003eИспользуя: подключение авто загрузчика\u003c/h2\u003e\u003cspan id=\"knockknock-setup-composer-autoload\"\u003e\u003c/span\u003e\n\nВ месте, где необходимо использовать библиотеку, подключите авто загрузчик:\n```php\nrequire_once 'путь/к/корню/проекта/autoload.php';\n\n```\n**Примечания:**\n- Убедитесь, что путь к autoload.php правильный и соответствует структуре вашего проекта.\n\n\n\u003cp align=\"center\"\u003e- - - - -\u003c/p\u003e\n\n___\n\n\n\n\u003ch2\u003eЛогика работы библиотеки (блок-схема)\u003c/h2\u003e \u003cspan id=\"knockknock-logic-schema\"\u003e\u003c/span\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003cimg src=\"assets/logicOperator.png\" id=\"knockknock-logic-schema-img\" width=\"640px\" alt=\"логика схемы работы приложения\"\u003e\n\u003c/p\u003e\n\n### Простой пример работы.\n\n```php\nuse andy87\\knock_knock\\lib\\Method;\nuse andy87\\knock_knock\\lib\\ContentType;\nuse andy87\\knock_knock\\core\\Operator;\nuse andy87\\knock_knock\\core\\Response;\n\n// Получаем компонент реализующий отправку запросов\n$operator = new Operator( $_ENV['API_HOST'] )-\u003edisableSSL();  \n\n/**\n * Краткая форма записи (с не очевидным объектом запроса) \n */\n$content = $operator-\u003esend( $operator-\u003econstructRequest(Method::GET, 'info/me') )-\u003econtent;\n\n/** \n * Детальная форма записи с дополнительными возможностями\n */\n$request = $operator-\u003econstructRequest(Method::GET, 'info/me'); // Создаём объект запроса\n$request-\u003esetCurlInfo([ CURLINFO_CONTENT_TYPE ]); // Назначаем опции cURL\n$response = $operator-\u003esend($request); // Отправляем запрос и получаем ответ\n\n$content = $response-\u003econtent; // Получаем данные ответа\n$curlOptions = $response-\u003erequest-\u003ecurlOptions; // Получаем опции cURL\n\n$output = ( $curlOptions[CURLINFO_CONTENT_TYPE] === ContentType::JSON ) ? json_decode( $content ) : $content;\n\nprint_r( $output );\n\n```\n\n\n\u003cp align=\"center\"\u003e- - - - -\u003c/p\u003e\n\n___\n\n\n\n\u003ch2 align=\"center\"\u003eБазовый класс\u003c/h2\u003e \u003cspan id=\"knockknock-src-Operator\"\u003e\u003c/span\u003e\n\n_use [andy87\\knock_knock\\core\\Operator](src/core/Operator.php);_  \n\nPHP Фасад\\Адаптер для отправки запросов через ext cURL\n\n\u003ch3\u003eReadOnly свойства:\u003c/h3\u003e \u003cspan id=\"knockknock-src-Operator-readonly\"\u003e\u003c/span\u003e\n\n- **commonRequest** \n  - _Объект содержащий параметры, назначаемые всем исходящим запросам_\n- **realRequest** \n  - _Используемый запрос_\n- **eventHandlers** \n  - _Список обработчиков событий_\n- **host** \n  - _Хост, на который будет отправляться запросы_\n- **logs** \n  - _Список логов_\n\nВозможности/фичи:\n - Настройки параметров запросов\n - Защита данных от перезаписи\n - Обработчики событий\n - Инкапсуляция\n - Singleton\n - логирование\n  \n#### ВАЖНЫЙ МОМЕНТ!  \n- В классах применяется инкапсуляция, поэтому для доступа к свойствам компонентов используются ReadOnly свойства.  \n- `CURL_OPTIONS` по умолчанию пустые! В большинстве случаев, для получения валидных ответов, требуется задать необходимые настройки.   \n\n\n\n\u003ch2 align=\"center\"\u003e\"Получение\" объекта/экземпляра класса\u003c/h2\u003e \u003cspan id=\"knockknock-src-Operator-construct\"\u003e\u003c/span\u003e\n\nПередавая параметры напрямую в конструктор:\n```php\n$operator = new Operator( $_ENV['API_HOST'], $commonRequestParams );\n``` \nПрименяя, паттерн Singleton:\n```php\n$operator = Operator::getInstance( $_ENV['API_HOST'], $commonRequestParams );\n```\nМетоды возвращают объект(экземпляр класса `Operator`), принимая на вход два аргумента:\n- `string $host` - хост\n- `array $operatorConfig` - массив с настройками для всех исходящих запросов.\n\nПри создании объекта `Operator` будет вызван метод `init()`, который запускает пользовательские инструкции.  \nПосле выполнения `init()` запускается обработчик события привязанный к ключу `EVENT_AFTER_CONSTRUCT`\n\n\u003ch2 align=\"center\" id=\"knockknock-src-Operator-params\"\u003e\n  Общие настройки запросов\n\u003c/h2\u003e\nЧто бы указать настройки применяемые ко всем исходящим запросам,  \nпри создании объекта `Operator` передаётся массив (ключ - значение), с необходимыми настройками.\n\nПример настройки:\n```php\n// настройки для последующих исходящих запросов\n$commonRequestParams = [\n    Request::SETUP_PROTOCO =\u003e $_ENV['API_PROTOCOL'],\n    Request::SETUP_CONTENT_TYPE =\u003e Request::CONTENT_TYPE_JSON,\n    Request::SETUP_CURL_OPTIONS =\u003e [\n        CURLOPT_HEADER =\u003e false,\n        CURLOPT_RETURNTRANSFER =\u003e true\n    ]\n];\n// Получаем компонент для отправки запросов\n$operator = new Operator( $_ENV['API_HOST'], $commonRequestParams );\n\n//Применяя, паттерн Singleton:\n$operator = Operator::getInstance( $_ENV['API_HOST'], $commonRequestParams );\n```\nДоступные ключи для настройки(константы класса `Request`):\n\n- `SETUP_PROTOCOL`\n- `SETUP_HOST`\n- `SETUP_METHOD`\n- `SETUP_HEADERS`\n- `SETUP_CONTENT_TYPE`\n- `SETUP_DATA`\n- `SETUP_CURL_OPTIONS`\n- `SETUP_CURL_INFO`\n\n\n\u003ch2\u003eОбработчики событий\u003c/h2\u003e \u003cspan id=\"knockknock-src-events-setupEventHandlers\"\u003e\u003c/span\u003e\n\n\u003ch3\u003eСписок событий\u003c/h3\u003e \u003cspan id=\"knockknock-src-events-list\"\u003e\u003c/span\u003e\n\n- `EVENT_AFTER_CONSTRUCT` после создания объекта knockKnock\n- `EVENT_CREATE_REQUEST` после создания объекта запроса\n- `EVENT_BEFORE_SEND` перед отправкой запроса\n- `EVENT_CURL_Operator` перед отправкой curl запроса\n- `EVENT_CREATE_RESPONSE` после создания объекта ответа\n- `EVENT_AFTER_SEND` после получения ответа\n\n\u003ch5\u003eПример установки обработчиков событий\u003c/h5\u003e \u003cspan id=\"knockknock-src-Handler-events-example\"\u003e\u003c/span\u003e\n\n```php\n$operator-\u003esetupEventHandlers([\n    Operator::EVENT_AFTER_CONSTRUCT =\u003e function( Operator $operator ) {\n        // ...\n    },\n    Operator::EVENT_CREATE_REQUEST =\u003e function( Operator $operator, Request $request ) {\n        // ...\n    },\n    Operator::EVENT_BEFORE_SEND =\u003e function( Operator $operator, Request $request ) {\n        // ...\n    },\n    Operator::EVENT_CURL_HANDLER =\u003e function( Operator $operator, resource $ch ) {\n        // ...\n    },\n    Operator::EVENT_CREATE_RESPONSE =\u003e function( Operator $operator, Response $response ) {\n        // ...\n    },\n    Operator::EVENT_AFTER_SEND =\u003e function( Operator $operator, Response $response ) {\n        // ...\n    }\n]);\n```\nПервый аргумент - ключ события, второй - callback функция.\n\nВсе callback функции принимают первым аргументом объект/экземпляр класса `Operaotr`.  \nВторым аргументом передаётся объект/экземпляр класса в зависимости от события:\n- `Request` - для событий `EVENT_CREATE_REQUEST`, `EVENT_BEFORE_SEND`\n- `Response` - для событий `EVENT_CREATE_RESPONSE`, `EVENT_AFTER_SEND`\n\n\n\u003cp align=\"center\"\u003e- - - - -\u003c/p\u003e\n\n___\n\n\n\n\u003ch1 align=\"center\"\u003eЗапрос\u003c/h1\u003e\u003cspan id=\"knockknock-src-Request\"\u003e\u003c/span\u003e\n\n_use [andy87\\knock_knock\\core\\Request](src/core/Request.php);_  \n\nОбъект запроса, содержащий данные для отправки запроса.\n\n\u003ch3\u003eReadOnly свойства:\u003c/h3\u003e \u003cspan id=\"knockknock-src-Request-readonly\"\u003e\u003c/span\u003e\n\n- **protocol** - _протокол_\n- **host** - _хост_\n- **endpoint** - _конечная точка_\n- **method** - _метод_\n- **headers** - _заголовки_\n- **contentType** - _тип контента_\n- **data** - _данные_\n- **curlOptions** - _опции cURL_\n- **curlInfo** - _информация cURL_\n- **params** - _параметры запроса_\n- **url** - _полный URL_\n- **params** - _все свойства в виде массива_\n- **fakeResponse** - _установленные фэйковые данные ответа_\n- **errors** - _лог ошибок_\n\n\u003ch3 align=\"center\"\u003eСоздание объекта запроса\u003c/h3\u003e \u003cspan id=\"knockknock-src-Request-construct\"\u003e\u003c/span\u003e\n\nПередавая параметры напрямую в конструктор:\n```php\n$request = new Request( 'info/me', [\n    Request::METHOD =\u003e Method::POST,\n    Request::DATA =\u003e [ 'client_id' =\u003e 34 ],\n    Request::HEADERS =\u003e [ 'api-secret-key' =\u003e $_ENV['API_SECRET_KEY'] ],\n    Request::CURL_OPTIONS =\u003e [ CURLOPT_TIMEOUT =\u003e 10 ],\n    Request::CURL_INFO =\u003e [\n        CURLINFO_CONTENT_TYPE,\n        CURLINFO_HEADER_SIZE,\n        CURLINFO_TOTAL_TIME\n    ],\n    Request::CONTENT_TYPE =\u003e ContentType::FORM_DATA,\n]);\n```\nМетодом, который вызывает _callback_ функцию, привязанную к ключу `EVENT_CREATE_REQUEST`\n```php\n$request = $operator-\u003econstructRequest(Method::GET, 'info/me', [\n    Request::METHOD =\u003e Method::POST,\n    Request::DATA =\u003e [ 'client_id' =\u003e 45 ],\n    Request::HEADERS =\u003e [ 'api-secret-key' =\u003e $_ENV['API_SECRET_KEY'] ],\n    Request::CURL_OPTIONS =\u003e [ CURLOPT_TIMEOUT =\u003e 10 ],\n    Request::CURL_INFO =\u003e [\n        CURLINFO_CONTENT_TYPE,\n        CURLINFO_HEADER_SIZE,\n        CURLINFO_TOTAL_TIME\n    ],\n    Request::CONTENT_TYPE =\u003e ContentType::FORM_DATA,\n]);\n```\nКлонируя существующий объект запроса:\n```php\n$request = $operator-\u003econstructRequest(Method::GET, 'info/me');\n\n$response = $operator-\u003esend($request);\n\n//Клонирование объекта запроса (без статуса отправки)\n$cloneRequest = $request-\u003eclone();\n\n// Отправка клона запроса\n$response = $operator-\u003esetupRequest( $cloneRequest )-\u003esend();\n```\n\n\u003ch3\u003e\n    Назначение/Изменение/Получение отдельных параметров запроса (set/get)\n\u003c/h3\u003e \u003cspan id=\"knockknock-src-Request-setter-getter\"\u003e\u003c/span\u003e\n\nТаблица set/get методов для взаимодействия с отдельными свойствами запроса\n\n| Параметр        | Сеттер                                | Геттер                     | Информация                                                                                                                                                                   |\n|-----------------|---------------------------------------|----------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n| Протокол        | setProtocol( string $protocol )       | getProtocol(): string      | \u003ca href=\"https://curl.se/docs/protdocs.html\" target=\"_blank\"\u003eпротоколы\u003c/a\u003e                                                                                                   |\n| Хост            | setHost( string $host )               | getHost(): string          | ---                                                                                                                                                                          |\n| Endpoint        | setEndpoint( string $url )            | getEndpoint(): string      | ---                                                                                                                                                                          |\n| Метод           | setMethod( string $method )           | getMethod(): string        | \u003ca href=\"https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods\" target=\"_blank\"\u003eметоды\u003c/a\u003e                                                                               |\n| Заголовки       | setHeaders( array $headers )          | getHeaders(): array        | \u003ca href=\"https://ru.wikipedia.org/wiki/%D0%A1%D0%BF%D0%B8%D1%81%D0%BE%D0%BA_%D0%B7%D0%B0%D0%B3%D0%BE%D0%BB%D0%BE%D0%B2%D0%BA%D0%BE%D0%B2_HTTP\" target=\"_blank\"\u003eзаголовки\u003c/a\u003e |\n| Тип контента    | setContentType( string $contentType ) | getContentType(): string   | \u003ca href=\"https://ru.wikipedia.org/wiki/%D0%A1%D0%BF%D0%B8%D1%81%D0%BE%D0%BA_MIME-%D1%82%D0%B8%D0%BF%D0%BE%D0%B2\" target=\"_blank\"\u003eТип контента\u003c/a\u003e                            |\n| Данные          | setData( mixed $data )                | getData(): mixed           | ---                                                                                                                                                                          |\n| Опции cURL      | setCurlOptions( array $curlOptions )  | getCurlOptions(): array    | \u003ca href=\"https://www.php.net/manual/ru/function.curl-setopt.php\" target=\"_blank\"\u003eОпции cURL\u003c/a\u003e                                                                              |\n| Информация cURL | setCurlInfo( array $curlInfo )        | getCurlInfo(): array       | \u003ca href=\"https://www.php.net/manual/ru/function.curl-getinfo.php\" target=\"_blank\"\u003eИнформация cURL\u003c/a\u003e                                                                        |\n| Фэйковый ответ  | setFakeResponse( array $response )    | getFakeResponse(): array   |                                                                                                                                                                              |\n\n```php\n$request = $operator-\u003econstructRequest(Method::GET, 'info/me');\n\n$request-\u003esetMethod( Method::GET );\n$request-\u003esetData(['client_id' =\u003e 67]);\n$request-\u003esetHeaders(['api-secret-key' =\u003e 'secretKey67']);\n$request-\u003esetCurlOptions([\n    CURLOPT_TIMEOUT =\u003e 10,\n    CURLOPT_RETURNTRANSFER =\u003e true\n]);\n$request-\u003esetCurlInfo([\n    CURLINFO_CONTENT_TYPE,\n    CURLINFO_HEADER_SIZE,\n    CURLINFO_TOTAL_TIME\n]);\n$request-\u003esetContentType( ContentType::JSON );\n\n$protocol = $request-\u003egetPrococol(); // String\n$host = $request-\u003egetHost(); // String\n// ... аналогичным образом доступны и другие подобные методы для получения свойств запроса\n```\n\u003ch3\u003eНазначение запроса с переназначением свойств\u003c/h3\u003e \u003cspan id=\"knockknock-src-Request-setupRequest\"\u003e\u003c/span\u003e\n\n```php\n$operator-\u003esetupRequest( $request, [\n    Request::SETUP_HOST =\u003e $_ENV['API_HOST'],\n    Request::SETUP_HEADERS =\u003e [\n        'api-secret' =\u003e $_ENV['API_SECRET_KEY']\n    ],\n]);\n```\n`setupRequest( Request $request, array $options = [] ): self`\n\n\n##### addError( string $error )\nДобавление ошибки в лог ошибок\n```php\n$request = $operator-\u003econstructRequest(Method::GET, 'info/me');\n\n$request-\u003eaddError('Ошибка!');\n\n```\n\n\n\u003cp align=\"center\"\u003e- - - - -\u003c/p\u003e\n\n___\n\n\n\n\u003ch1 align=\"center\"\u003eОтвет\u003c/h1\u003e\u003cspan id=\"knockknock-src-Response\"\u003e\u003c/span\u003e\n\n_use [andy87\\knock_knock\\core\\Response](src/core/Response.php);_  \n\nОбъект ответа, содержащий данные ответа на запрос.\n\u003ch3\u003eReadOnly свойства\u003c/h3\u003e \u003cspan id=\"knockknock-src-Response-readonly\"\u003e\u003c/span\u003e\n\n- **content**\n  - _данные ответа_\n- **httpCode**\n  - _код ответа_\n- **request**\n  - _объект запроса, содержащий данные о запросе_\n- **curlOptions**\n  - _быстрый доступ к request-\u003ecurlOptions_\n- **curlInfo**\n  - _быстрый доступ к request-\u003ecurlInfo_\n\n\u003ch3 align=\"center\"\u003eСоздание объекта ответа\u003c/h3\u003e \u003cspan id=\"knockknock-src-Response-construct\"\u003e\u003c/span\u003e\n\nПередавая параметры напрямую в конструктор:\n```php\n$response = new Response('{\"id\" =\u003e 806034, \"name\" =\u003e \"and_y87\"}', 200 );\n```\nМетодом, который вызывает _callback_ функцию, привязанную к ключу `EVENT_CREATE_RESPONSE`\n```php\n$response = $operator-\u003econstructResponse([\n    Response::CONTENT =\u003e [\n        'id' =\u003e 806034,\n        'name' =\u003e 'and_y87'\n    ],\n    Response::HTTP_CODE =\u003e 400,\n], $request );\n```\n`constructResponse( array $responseParams, ?Request $request = null ): Response`\n\n\u003ch2\u003eОтправка запроса\u003c/h2\u003e \u003cspan id=\"knockknock-src-Handler-send\"\u003e\u003c/span\u003e\n\n`send( ?Request $request = null ): Response`\nВызов возвращает объект/экземпляр класса `Response`.  \nСрабатывают callback функции, привязанные к ключам:\n - `EVENT_AFTER_SEND`\n - `EVENT_CREATE_RESPONSE`\n - `EVENT_BEFORE_SEND`\n - `EVENT_CURL_HANDLER`\n\n```php\n$operator = new Operator( $_ENV['API_HOST'] );\n$request = $operator-\u003econstructRequest(Method::GET, 'info/me');\n$response = $operator-\u003esend($request);\n\n// Аналог\n$operator = new Operator( $_ENV['API_HOST'] );\n$response = $operator-\u003esend( $operator-\u003econstructRequest(Method::GET, 'info/me') );\n```\nНельзя повторно отправить запрос, выбрасывается исключение `RequestCompleteException`.\nДля повторной отправки запроса, необходимо создать новый объект запроса и использовать его:\n```php\n$operator = new Operator( $_ENV['API_HOST'] );\n$request = $operator-\u003econstructRequest(Method::GET, 'info/me');\n$response = $operator-\u003esend($request);\n\n// повторная отправка запроса\n$response = $operator-\u003esend($request-\u003eclone());\n```\n\n\u003ch2\u003eОтправка запроса с фэйковым ответом\u003c/h2\u003e \u003cspan id=\"knockknock-src-Handler-fakeResponse\"\u003e\u003c/span\u003e\n\n\n```php\n// параметры возвращаемого ответа\n$fakeResponse = [\n    Response::HTTP_CODE =\u003e 200,\n    Response::CONTENT =\u003e '{\"id\" =\u003e 8060345, \"nickName\" =\u003e \"and_y87\"}'\n];\n$request-\u003esetFakeResponse( $fakeResponse );\n\n$response = $operator-\u003esend( $request );\n```\nобъект `$response` будет содержать в свойствах `content`, `httpCode` данные переданные в аргументе `$fakeResponse`\n\n\u003ch2\u003eДанные в ответе\u003c/h2\u003e \u003cspan id=\"knockknock-src-Response-setter\"\u003e\u003c/span\u003e\n\nВ созданный объект `Response`, чей запрос не был отправлен, разрешено задавать данные, используя методы группы `set`.  \n```php\n$response = $operator-\u003esend($request);\n\n$response\n    -\u003esetHttpCode(200)\n    -\u003esetContent('{\"id\" =\u003e 8060345, \"nickName\" =\u003e \"and_y87\"}');\n```\n**Внимание!** Если данные в объекте уже существуют, повторно задать их нельзя выбрасывается `ParamUpdateException`.  \nВ случае необходимости заменить данные, используется вызов метода `replace( string $key, mixed $value )` см. далее\n\n\u003ch3 id=\"knockknock-src-Response-replace\"\u003e\n    Подмена данных\n\u003c/h3\u003e \u003cspan\u003e\u003c/span\u003e\nЭто сделано для явного действия, когда необходимо заменить данные в объекте `Response`.\n\n```php\n$response = $operator-\u003esend($request);\n\n$response\n    -\u003ereplace( Response::HTTP_CODE, 200 )\n    -\u003ereplace( Response::CONTENT, '{\"id\" =\u003e 8060345, \"nickName\" =\u003e \"and_y87\"}' );\n```\n\n\u003ch2\u003eДанные запроса из ответа\u003c/h2\u003e \u003cspan id=\"knockknock-src-Response-request\"\u003e\u003c/span\u003e\n\nДля получения из объекта `Response` данных запроса, необходимо обратиться к ReadOnly свойству `request`  \nи далее взаимодействовать с ним аналогично объекту `Request`    \n```php\n$operator = new Operator( $_ENV['API_HOST'] );\n$response = $operator-\u003esetRequest( $operator-\u003econstructRequest(Method::GET, 'info/me') )-\u003esend();\n\n// Получение компонента запроса\n$request = $response-\u003erequest;\n\n$method = $request-\u003emethod; // получение метода запроса\n```\n\nПолучения свойств cURL запроса \n```php\n$operator = new Operator( $_ENV['API_HOST'] );\n$response = $operator-\u003esetRequest( $operator-\u003econstructRequest(Method::GET, 'info/me') )-\u003esend();\n\n$response-\u003erequest;\n\n// Получение свойств через объект запроса\n$curlOptions =  $response-\u003erequest-\u003ecurlOption;\n$curlInfo =  $response-\u003erequest-\u003ecurlInfo;\n\n//Вариант с использованием быстрого доступа\n$curlOptions =  $response-\u003ecurlOption;\n$curlInfo =  $response-\u003ecurlInfo;\n```\n\u003ch3\u003easArray()\u003c/h3\u003e \u003cspan id=\"knockknock-src-Response-asArray\"\u003e\u003c/span\u003e\n\nПреобразование в массив.  \n - преобразование данных ответа на запрос `asArray()`\n - преобразование всего объекта в массив `asArray(true)`\n```php\n$response = $operator-\u003esend($request)-\u003easArray(); // $response\n$array = $response-\u003econtent; // Array$response\n```\n##### addError( string $error )\nДобавление ошибки в лог ошибок\n```php\n$request = $operator-\u003econstructRequest(Method::GET, 'info/me');\n\n$response = $operator-\u003esend($request);\n\n$response-\u003eaddError('Ошибка!');\n\n```\n\n\u003cp align=\"center\"\u003e- - - - -\u003c/p\u003e\n\n___\n\n\u003cp align=\"center\"\u003e- - - - -\u003c/p\u003e\n\n\n\u003ch1 align=\"center\" \u003eДополнительные возможности\u003c/h1\u003e \u003cspan id=\"knockknock-src-feature\"\u003e\u003c/span\u003e\n\n\u003ch3\u003eSSL\u003c/h3\u003e \u003cspan id=\"knockknock-src-ssl\"\u003e\u003c/span\u003e\n\nФункционал включения/отключения SSL верификации в объектах `Operaotr` \u0026 `Request`.  \n\nВ `curlOptions` добавляется ключ `CURLOPT_SSL_VERIFYPEER` и `CURLOPT_SSL_VERIFYHOST`.\n\n`-\u003edisableSSL( bool $verifyPeer = false, int $verifyHost = 0 );`  \n`-\u003eenableSSL( bool $verifyPeer = true, int $verifyHost = 2 );`  \n\n`Operaotr` - для всех запросов\n```php\n$operator = new Operator( $_ENV['API_HOST'] );\n$operator-\u003edisableSSL();\n\n$request = $operator-\u003econstructRequest(Method::GET, 'info/me');\n\n$response = $operator-\u003esetupRequest( $request )-\u003esend();\n```\n\n`Request` - для конкретного запроса  \n```php\n$operator = new Operator( $_ENV['API_HOST'] )-\u003edisableSSL();\n\n$request = $operator-\u003econstructRequest(Method::GET, 'info/me');\n$request-\u003eenableSSL();\n\n$response = $operator-\u003esetupRequest( $request )-\u003esend();\n```\n\u003ch3\u003eCookie\u003c/h3\u003e \u003cspan id=\"knockknock-src-Cookie\"\u003e\u003c/span\u003e\n\nВ объекте `Operaotr` имеется функционал использования cookie.  \n`Operaotr` - для всех запросов  \n```php\n$operator = new Operator( $_ENV['API_HOST'] );\n\n$cookie = $_ENV['COOKIE'];\n$jar = $_ENV['COOKIE_JAR'];\n\n$operator-\u003euseCookie( $cookie, $jar );\n```  \n`$operator-\u003euseCookie( string $cookie, string $jar, ?string $file = null )`  \nпо умолчанию `$file = null` и  `$file` приравнивается к `$jar`  \n\n\u003ch3\u003eЛогирование\u003c/h3\u003e \u003cspan id=\"knockknock-src-logs\"\u003e\u003c/span\u003e\n\nДобавление сообщений во внутренний массив `logs` \n\n```php\n$operator = new Operator( $_ENV['API_HOST'] );\n\n$operator-\u003eaddLog( 'Какое то сообщение' );\n```\n`$operator-\u003eaddLog( string $message )`  \n\n\n\u003cp align=\"center\"\u003e- - - - -\u003c/p\u003e\n\n___\n\n\u003cp align=\"center\"\u003e- - - - -\u003c/p\u003e\n\n\n\u003ch1 align=\"center\"\u003eРасширения на основе базового класса\u003c/h1\u003e\u003cspan  id=\"knockknock-extends\"\u003e\u003c/span\u003e\n\n\u003ch3 align=\"center\"\u003e\n    \u003ca href=\"docs/KnockKnock/KnockKnockOctopus.md\" target=\"_blank\"\u003e\n        KnockKnockOctopus\n        \u003cbr\u003e\n        \u003cimg src=\"assets/logo/KnockKnockOctopus_320.png\" style=\"width:200px; height: auto\" alt=\"KnockKnockOctopus php curl facade\"/\u003e\n    \u003c/a\u003e\n\u003c/h3\u003e \u003cspan id=\"knockknock-Octopus\"\u003e\u003c/span\u003e\n\nКласс с функционалом простой реализации отправки запросов и минимальными настройками\n\n\u003ch4\u003eДоступные методы.\u003c/h4\u003e \u003cspan id=\"knockknock-Octopus-methods\"\u003e\u003c/span\u003e\n\n| get() | post() | put() | patch() | delete() | head() | options() | trace() |\n|-------|--------|-------|---------|----------|--------|-----------|---------|\n\n\u003ch4\u003eКаждый метод принимает два аргумента:\u003c/h4\u003e \u003cspan id=\"knockknock-Octopus-methods-args\"\u003e\u003c/span\u003e\n\n| Аргумент  |   Тип   | Обязательный  | Описание                       |\n|:----------|:-------:|:-------------:|:-------------------------------|\n| $endpoint | string  |      Да       | URL запроса (без хоста)        |\n| $params   |  array  |      Нет      | Данные запроса в виде массива  |\n_P.S. host задаётся в конструкторе_\n\n\u003ch4\u003eПростой пример использования\u003c/h4\u003e \u003cspan id=\"knockknock-Octopus-methods-example\"\u003e\u003c/span\u003e\n\n```php\n$knockKnockOctopus = new KnockKnockOctopus($_ENV['API_URL']);\n\n$knockKnockOctopus-\u003eget( '/profile', [ 'id' =\u003e 806034 ] ); //GET запрос\n\n$knockKnockOctopus-\u003epost( '/new', [  //POST запрос\n    'name' =\u003e 'Новая новость',\n    'content' =\u003e 'Текст новости' \n]);\n```\n\n\n\u003cp align=\"center\"\u003e - - - - - \u003c/p\u003e\n\n\u003ch3 align=\"center\"\u003e\n    \u003ca href=\"docs/KnockKnock/KnockKnockSecurity.md\" target=\"_blank\"\u003e\n        KnockKnockSecurity\n        \u003cbr\u003e\n        \u003cimg src=\"assets/logo/KnockKnockSecurity_280.png\" style=\"width:auto; height: 128px\" alt=\"KnockKnockSecurity php curl facade\"/\u003e\n    \u003c/a\u003e\n\u003c/h3\u003e \u003cspan id=\"knockknock-security\"\u003e\u003c/span\u003e\n\nРасширяет класс [KnockKnockOctopus](docs/KnockKnock/KnockKnockOctopus.md), предоставляя доступ к функционалу для простой и  \nбыстрой реализации авторизации, и настройки запросов.\n\n```php\n$knockKnockSecurity = new KnockKnockSecurity($_ENV['API_URL']);\n\n// Настройка параметров запроса по умолчанию\n$knockKnockSecurity\n    -\u003edisableSSL()\n    -\u003esetupAuthorization( KnockKnockSecurity::TOKEN_BEARER, 'token' )\n    -\u003esetupHeaders([ 'X-Api-Key' =\u003e $_ENV['X_API_KEY'] ])\n    -\u003esetupContentType( ContentType::JSON )\n    -\u003eon( Operator::EVENT_AFTER_SEND, function( Operator $operator, Response $response ) =\u003e \n    {\n        $logFilePath = $_SERVER['DOCUMENT_ROOT'] . '/api_log.txt';\n\n        file_put_contents( $logFilePath, $response-\u003econtent, FILE_APPEND );\n    });\n\n// Получение ответа на запрос методом `patch`\n$responsePatch = $knockKnockSecurity-\u003epatch( 'product', [\n    'price' =\u003e 1000\n]);\n\n$product = $responsePatch-\u003easArray();\n\n$price = $product['price'];\n\n// Изменение типа контента на `application/json`, для следующего запроса\n$knockKnockSecurity-\u003euseContentType( ContentType::JSON );\n\n// Отправка POST запроса и получение ответа\n$responsePost = $knockKnockSecurity-\u003epost( 'category', [\n    'name' =\u003e 'Фреймворки'\n]);\n\n$response = json_decode( $responsePost-\u003econtent );\n\n$category_id = $response-\u003eid;\n\n```\n\n\n\u003cp align=\"center\"\u003e- - - - -\u003c/p\u003e\n\n___\n\n\u003cp align=\"center\"\u003e- - - - -\u003c/p\u003e\n\n\n\u003ch1\u003eCustom реализация\u003c/h1\u003e \u003cspan id=\"knockknock-Custom\"\u003e\u003c/span\u003e\n\nCustom реализация Базового класса, к примеру с добавлением логирования работающим \"под капотом\"\n```php\nclass KnockKnockYandex extends Operator\n{\n    private const LOGGER = 'logger';\n\n\n    private string $host = 'https://api.yandex.ru/'\n\n    private string $contentType = ContentType::JSON\n\n    private YandexLogger $logger;\n\n\n\n    /**\n     * @return void\n     */\n    public function init(): void\n    {\n        $this-\u003esetupYandexLoggerEventHandlers();\n    }\n    \n    /**\n     * @param array $callbacks\n     * \n     * @return self\n     */\n    private function setupYandexLoggerEventHandlers( array $callbacks ): self\n    {\n        $this-\u003eon( self::AFTER_CREATE_REQUEST, function( Request $request ) =\u003e \n        {\n            $logData = $this-\u003egetLogDataByRequest( $request );\n\n            $this-\u003eaddYandexLog( $logData );\n        };\n\n        $this-\u003eon(self::EVENT_AFTER_SEND, function( Response $response ) =\u003e \n        {\n            $logData = $this-\u003egetLogDataByRequest( $response-\u003erequest );\n\n            $this-\u003eaddYandexLog( $logData );\n        };\n    }\n\n    /**\n      * @param Request $request\n      * \n      * @return array\n      */\n    private function getLogDataByRequest( Request $request ): array\n    {\n        return $request-\u003egetParams();\n    }\n\n    /**\n     * @param array $logData\n     * \n     * @return void\n     */\n    private function addYandexLog( array $logData ): bool\n    {\n        return $logger-\u003elog( $logData );\n    }\n}\n\n```\n\u003ch3\u003e\n    Пример использования custom реализации\n\u003c/h3\u003e \u003cspan id=\"knockknock-Custom-use\"\u003e\u003c/span\u003e\n\n```php\n\n$knockKnockYandex = KnockKnockYandex::getInstanсe( $_ENV['API_HOST'], [\n    KnockKnockYandex::LOGGER =\u003e new YandexLogger(),\n]);\n\n$response = $knockKnockYandex-\u003esetupRequest( 'profile', [ \n    Request::METHOD =\u003e Method::PATCH,\n    Request::DATA =\u003e [ 'city' =\u003e 'Moscow' ],\n]); // Логирование `afterCreateRequest`\n\n$response = $knockKnockYandex-\u003esend(); // Логирование `afterSend`\n```\n\n\n\u003cp align=\"center\"\u003e- - - - -\u003c/p\u003e\n\n___\n\n\u003cp align=\"center\"\u003e- - - - -\u003c/p\u003e\n\n\n\u003ch2\u003eТесты\u003c/h2\u003e \u003cspan id=\"knockknock-tests\"\u003e\u003c/span\u003e\n\n - tests: 100+\n - assertions: 350+\n\n\u003ch3\u003e\n    Запуск тестов:\n\u003c/h3\u003e \u003cspan id=\"knockknock-tests-run\"\u003e\u003c/span\u003e\n\nНативный  \n```bash\nvendor/bin/phpunit\n```  \nИнформационный  \n```bash\nvendor/bin/phpunit --testdox\n```  \nС логированием  \n```bash\nvendor/bin/phpunit --log-junit \"tests/logs/phpunit.xml\"\n```\n\n\u003ch2\u003eЛицензия\u003c/h2\u003e \u003cspan id=\"knockknock-license\"\u003e\u003c/span\u003e\n\nhttps://github.com/andy87/KnockKnock под лицензией CC BY-SA 4.0  \nДля получения дополнительной информации смотрите http://creativecommons.org/licenses/by-sa/4.0/  \nСвободно для не коммерческого использования  \nС указанием авторства для коммерческого использования\n\n[Packagist](https://packagist.org/packages/andy87/knockknock)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandy87%2Fknock-knock","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fandy87%2Fknock-knock","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandy87%2Fknock-knock/lists"}