{"id":13700034,"url":"https://github.com/swlib/saber","last_synced_at":"2025-05-15T04:07:32.141Z","repository":{"id":45702254,"uuid":"127649693","full_name":"swlib/saber","owner":"swlib","description":"⚔️ Saber, PHP异步协程HTTP客户端 | PHP Coroutine HTTP client - Swoole Humanization Library","archived":false,"fork":false,"pushed_at":"2021-10-15T03:34:48.000Z","size":485,"stargazers_count":981,"open_issues_count":29,"forks_count":124,"subscribers_count":38,"default_branch":"v1.x","last_synced_at":"2025-05-06T05:03:01.589Z","etag":null,"topics":["ajax","async","axios","coroutine","http","http-client","php","psr7","psr7-http-client","requests","saber","swoole"],"latest_commit_sha":null,"homepage":"https://packagist.org/packages/swlib/saber","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/swlib.png","metadata":{"files":{"readme":"README-EN.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-04-01T16:31:21.000Z","updated_at":"2025-04-12T14:33:13.000Z","dependencies_parsed_at":"2022-08-28T19:30:40.221Z","dependency_job_id":null,"html_url":"https://github.com/swlib/saber","commit_stats":null,"previous_names":[],"tags_count":28,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swlib%2Fsaber","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swlib%2Fsaber/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swlib%2Fsaber/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/swlib%2Fsaber/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/swlib","download_url":"https://codeload.github.com/swlib/saber/tar.gz/refs/heads/v1.x","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253102628,"owners_count":21854501,"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":["ajax","async","axios","coroutine","http","http-client","php","psr7","psr7-http-client","requests","saber","swoole"],"created_at":"2024-08-02T20:00:47.586Z","updated_at":"2025-05-15T04:07:27.129Z","avatar_url":"https://github.com/swlib.png","language":"PHP","readme":"# Saber\n\n[![Latest Version](https://img.shields.io/github/release/swlib/saber.svg)](https://github.com/swlib/saber/releases)\n[![PHPUnit for Saber](https://github.com/swlib/saber/workflows/PHPUnit%20for%20Saber/badge.svg)](https://github.com/swlib/saber/actions)\n[![Php Version](https://img.shields.io/badge/php-%3E=7.1-brightgreen.svg?maxAge=2592000)](https://secure.php.net/)\n[![Swoole Version](https://img.shields.io/badge/swoole-%3E=2.1.2-brightgreen.svg?maxAge=2592000)](https://github.com/swoole/swoole-src)\n[![Saber License](https://img.shields.io/hexpm/l/plug.svg?maxAge=2592000)](https://github.com/swlib/saber/blob/master/LICENSE)\n\n## Intro\n\nThe PHP high-performance HTTP client for `Swoole Humanized Component Library`, based on Swoole native coroutine client, supports multiple styles of operation, provides high-performance solutions at the bottom, allows developers to focus on feature development, and emancipate from traditional synchronous blocking network libs.\n\n- Development based on Swoole Coroutine Client\n- User-friendly style, ajax.js/axios.js/requests.py users' gospel, also supports PSR style operation\n- Complete browser-level cookie management mechanism, perfect for crawler/API proxy applications\n- Request/response interceptors\n- Multiple requests concurrent, concurrent redirection optimization, automated multiplexing long connections\n- Automatic transcoding of response messages\n- HTTPS connection, CA certificate automation support\n- HTTP/Socks5 Proxy Support\n- Redirection control, automated long connection multiplexing\n- Automation Encode Request/Parse Response Data\n- Milliseconds timeout timer\n- Random UA Generator\n\n\n\n\n## Requirement\n\n- **PHP71** or later\n- Swoole 2.1.2 or later\n- **Swoole 4 is the best**\n\n\n\n\n## Examples\n\nAll of Saber's static methods have a corresponding method in the instance. The static method is implemented by a default client instance.\n\n### Coroutine\n\nSwoole implements coroutine scheduling at the bottom layer, and the business layer does not need to be aware of it. It needs to be used in event callback functions such as `onRequet`, `onReceive`, and `onConnect`, or wrapped using the go keyword (`swoole.use_shortname` is enabled by default).\n\n```php\ngo(function () {\n    echo SaberGM::get('http://httpbin.org/get');\n})\n```\n\n### Easy Request\n\n```php\nSaberGM::get('http://httpbin.org/get');\nSaberGM::post('http://httpbin.org/post');\nSaberGM::put('http://httpbin.org/put');\nSaberGM::patch('http://httpbin.org/patch');\nSaberGM::delete('http://httpbin.org/delete');\n```\n\n### Create Instance\n\nAPI proxy service applicable\n\n```php\n$saber = Saber::create([\n    'base_uri' =\u003e 'http://httpbin.org',\n    'headers' =\u003e [\n        'User-Agent' =\u003e null,\n        'Accept-Language' =\u003e 'en,zh-CN;q=0.9,zh;q=0.8',\n        'DNT' =\u003e '1'\n    ],\n]);\necho $saber-\u003eget('/get');\necho $saber-\u003epost('/post');\necho $saber-\u003epatch('/patch');\necho $saber-\u003eput('/put');\necho $saber-\u003edelete('/delete');\n```\n\n### Create Session\n\nSession instance will save cookies automatically, Its implementation is browser-level complete.\n\n```php\n$session = Saber::session([\n    'base_uri' =\u003e 'http://httpbin.org',\n    'redirect' =\u003e 0\n]);\n$session-\u003eget('/cookies/set?foo=bar\u0026k=v\u0026apple=banana');\n$session-\u003eget('/cookies/delete?k');\necho $session-\u003eget('/cookies')-\u003ebody;\n```\n\n### Multi Request\n\nNote: A concurrent redirection optimization scheme is used here. Multiple redirects are always concurrent and do not degenerate into a single request for the queue.\n```php\n$responses = SaberGM::requests([\n    ['uri' =\u003e 'http://github.com/'],\n    ['uri' =\u003e 'http://github.com/'],\n    ['uri' =\u003e 'https://github.com/']\n]);\necho \"multi-requests [ {$responses-\u003esuccess_num} ok, {$responses-\u003eerror_num} error ]:\\n\" .\"consuming-time: {$responses-\u003etime}s\\n\";\n\n// multi-requests [ 3 ok, 0 error ]:\n// consuming-time: 0.79090881347656s\n```\n```php\n// Arguments alias make it easier.\n$saber = Saber::create(['base_uri' =\u003e 'http://httpbin.org']);\necho $saber-\u003erequests([\n    ['get','/get'],\n    ['post','/post'],\n    ['patch','/patch'],\n    ['put','/put'],\n    ['delete','/delete']\n]);\n```\n\n### HTTP Proxy\n\nSupport HTTP and Socks5\n\n```php\n$uri = 'http://myip.ipip.net/';\necho SaberGM::get($uri, ['proxy' =\u003e 'http://127.0.0.1:1087'])-\u003ebody;\necho SaberGM::get($uri, ['proxy' =\u003e 'socks5://127.0.0.1:1086'])-\u003ebody;\n```\n\n### PSR Style\n\n```php\n$bufferStream = new BufferStream();\n$bufferStream-\u003ewrite(json_encode(['foo' =\u003e 'bar']));\n$response = SaberGM::psr()\n    -\u003ewithMethod('POST')\n    -\u003ewithUri(new Uri('http://httpbin.org/post?foo=bar'))\n    -\u003ewithQueryParams(['foo' =\u003e 'option is higher-level than uri'])\n    -\u003ewithHeader('content-type', ContentType::JSON)\n    -\u003ewithBody($bufferStream)\n    -\u003eexec()-\u003erecv();\necho $response-\u003egetBody();\n```\n\n\n\n## Install\n\n**The recommended way to install Saber is through [Composer](http://getcomposer.org/)**\n\n```shell\ncomposer require swlib/saber:dev-master\n```\n\nhow to install composer?\n```bash\n# Install Composer\ncurl -sS https://getcomposer.org/installer | php\n```\n```bash\n# Global install\nmv composer.phar /usr/local/bin/composer\n```\n\n\nAfter installing, you need to require Composer's autoloader:\n\n```php\nrequire 'vendor/autoload.php';\n```\n\nYou can then later update Saber using composer:\n\n```\ncomposer update\n```\n\n\n\n## Configuration parameter table\n\n`|` splitting multiple selectable values\n\n| key                   | type                  | introduction                   | example                                                      | remark                                                       |\n| --------------------- | --------------------- | ------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |\n| protocol_version      | string                |                                | 1.1                                                          | HTTP2 in the roadmap                                         |\n| base_uri              | string                |                                | `http://httpbin.org`                                         | Will merge with uri according to rfc3986                     |\n| uri                   | string                |                                | `http://httpbin.org/get` \\| `/get` \\| `get`                  | U can use absolute and relative paths                        |\n| method                | string                |                                | `get` \\| `post` \\| `head` \\| `patch` \\| `put` \\| `delete`    | The underlying layer is automatically converted to uppercase |\n| headers               | array                 |                                | `['DNT' =\u003e '1']` \\| `['accept' =\u003e ['text/html'], ['application/xml']]` | The field names are case-insensitive, but the original case rules at the time of setting are retained. Each underlying field value is automatically split into arrays according to PSR-7. |\n| cookies               | `array`\\|`string`     |                                | `['foo '=\u003e 'bar']` \\| `'foo=bar; foz=baz'`                   | The underlying is automatically converted to a Cookies object and its domain is set to the current uri, with browser-level complete properties. |\n| useragent             | string                |                                |                                                              | The default is macos platform chrome                         |\n| redirect              | int                   | max-value                      | 5                                                            | The default is 3, 0 is not redirected.                       |\n| keep_alive            | bool                  |                                | `true` \\| `false`                                            | The default is true, the connection will be reused automatically when redirecting |\n| content_type          | string                |                                | `text/plain` \\| `Swlib\\Http\\ContentType::JSON`               | default is `application/x-www-form-urlencoded`               |\n| data                  | `array` \\| `string`   |                                | `'foo=bar\u0026dog=cat'` \\|` ['foo' =\u003e 'bar']`                    | Will automatically encode data based on content_type         |\n| before                | `callable` \\| `array` | interceptor before request     | `function(Request $request){}`                               | Specific reference to the interceptor section                |\n| after                 | `callable` \\| `array` | interceptor after response     | `function(Response $response){}`                             | Ditto.                                                       |\n| timeout               | float                 |                                | 0.5                                                          | Default 5s, support millisecond timeout                      |\n| proxy                 | string                |                                | `http://127.0.0.1:1087` \\| `socks5://127.0.0.1:1087`         | suport `http` and `socks5`                                   |\n| ssl                   | int                   | enable ssl?                    | `0=disable` `1=enable` `2=auto`                              | auto default                                                 |\n| cafile                | string                | ca file                        | `__DIR__ . '/cacert.pem'`                                    |                                                              |\n| ssl_verify_peer       | bool                  | Verify server certificate      | `false` \\| `true`                                            | close default                                                |\n| ssl_allow_self_signed | bool                  | Allow self-signed certificates | `true` \\| `false`                                            | allow default                                                |\n\n\n### Alias\n\n| key          | alias         |\n| ------------ | ------------- |\n| method       | 0             |\n| uri          | `1` \\| `url`  |\n| data         | `2` \\| `body` |\n| base_uri     | base_url      |\n| after        | callback      |\n| content_type | content-type  |\n| cookies      | cookie        |\n| headers      | header        |\n| redirect     | follow        |\n| form_data    | query         |\n| useragent    | ua            |\n\n","funding_links":[],"categories":["HTTP and WebSocket"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fswlib%2Fsaber","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fswlib%2Fsaber","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fswlib%2Fsaber/lists"}