PHPackages                             playm3u8/whttp - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [HTTP &amp; Networking](/categories/http)
4. /
5. playm3u8/whttp

ActiveLibrary[HTTP &amp; Networking](/categories/http)

playm3u8/whttp
==============

PHP非阻塞并发HTTP请求类(采集爬虫专用)

v4.5.5(8mo ago)121474[1 issues](https://github.com/playm3u8/whttp/issues)Apache-2.0PHPPHP &gt;=7.1.0

Since Mar 24Pushed 8mo agoCompare

[ Source](https://github.com/playm3u8/whttp)[ Packagist](https://packagist.org/packages/playm3u8/whttp)[ RSS](/packages/playm3u8-whttp/feed)WikiDiscussions master Synced yesterday

READMEChangelog (7)DependenciesVersions (29)Used By (0)

Whttp
=====

[](#whttp)

PHP非阻塞并发HTTP请求类(采集爬虫专用)
=======================

[](#php非阻塞并发http请求类采集爬虫专用)

*下面是详细使用方法*

```
$ composer require playm3u8/whttp

```

*1. 引用命名空间*

```
use PL\Whttp;
```

*2. 请求方式*

```
// GET:
$http = Whttp::get('https://www.baidu.com');
if ($http->getError()) {
    $http = "error: ".$http->getError();
} else {
    $http = $http->getBody();
}
p($http,true);
```

```
// POST:
$http = Whttp::post('https://www.baidu.com',['name'=>'playm3u8']);
if ($http->getError()) {
    $http = "error: ".$http->getError();
} else {
    $http = $http->getBody();
}
p($http,true);
```

```
// PUT:
$http = Whttp::put('https://www.baidu.com',['name'=>'playm3u8']);
if ($http->getError()) {
    $http = "error: ".$http->getError();
} else {
    $http = $http->getBody();
}
p($http,true);
```

```
// PATCH:
$http = Whttp::patch('https://www.baidu.com',['name'=>'playm3u8']);
if ($http->getError()) {
    $http = "error: ".$http->getError();
} else {
    $http = $http->getBody();
}
p($http,true);
```

```
// DELETE:
$http = Whttp::delete('https://www.baidu.com',['name'=>'playm3u8']);
if ($http->getError()) {
    $http = "error: ".$http->getError();
} else {
    $http = $http->getBody();
}
p($http,true);
```

*3. 设置Cookie*

```
$http = Whttp::get('https://www.baidu.com')->cookie('user=playm3u8');
if ($http->getError()) {
    $http = "error: ".$http->getError();
} else {
    $http = $http->getBody();
}
p($http,true);
```

*4. 我们来尝试获取百度搜索的Headers，看看是怎么操作的。*

```
$http = Whttp::get('https://www.baidu.com')->nobody();
if ($http->getError()) {
    $http = "error: ".$http->getError();
} else {
    $http = $http->getHeaders();
}
p($http,true);
```

*5. 获取响应状态（code）*

```
$http = Whttp::get('https://www.baidu.com');
if ($http->getError()) {
    $http = "error: ".$http->getError();
} else {
    $http = $http->getCode();
}
p($http,true);
```

*6. 获取响应状态（info）*

```
$http = Whttp::get('https://www.baidu.com');
if ($http->getError()) {
    $http = "error: ".$http->getError();
} else {
    $http = $http->getInfo();
}
p($http,true);
```

*7. 获取JSON再格式化为数组*

```
$http = Whttp::get('http://route.showapi.com/6-1');
if ($http->getError()) {
    $http = "error: ".$http->getError();
} else {
    $http = $http->getJson();
}
p($http,true);
```

*8. 批量处理URL*

```
$urls = array(
    'http://route.showapi.com/6-1',
    'http://route.showapi.com/6-1',
    'http://route.showapi.com/6-1',
);
Whttp::get($urls)->gany(function($data){
    if($data['error']){
        echo "error: ".$data['error']."";
    } else {
        // 不是每个请求都很快响应，这里就可以做到谁请求完成了就处理谁
        p($data);
    }
    // 可以吧数据返回出去
    // return "sssss";
})->getAll();
```

*9. 下载文件*

```
// 单个URL
$url = 'https://www.baidu.com/index.html';
$http = Whttp::get($url)->getDownload();
if (empty($http['error']) {
    $http = "error: ".$http['error'];
} else {
    $http = $http['download'];
}
p($http,true);
// (简单)批量, 建议在命令行模式下运行
$url[] = 'https://www.baidu.com/index.html';
$url[] = 'https://www.baidu.com/index.html';
$url[] = 'https://www.baidu.com/index.html';
$rsult = Whttp::get($url)
    ->savepath($path)
    ->concurrent(10)
    ->gany(Function($data) {
        if($data['error']){
            echo "error: ".$data['error']."\n";
        } else {
            // 不是每个请求都很快响应，这里就可以做到谁请求完成了就处理谁
            p($data['download']);
        }
        // 可以吧数据修改了返回出去
        $data['download']['state'] = 123;
        return $data;
    }
)->getDownload();
p($result,true);
```

*10. 上传文件*

```
$path = 'qrcode-viewfile.png';
$data = [
  'id'   => 'WU_FILE_0',
  'name' => 'qrcode-viewfile.png',
  'type' => 'image/png',
  'lastModifiedDate' => date('r',filemtime($path)).' (中国标准时间)',
  'size' => filesize($path),
  'file' => new CURLFile($path),
];
$http = Whttp::post('http://www.wwei.cn/qrcode-fileupload.html?op=index_jiema', $data);
$http = $http->header(['Access-Sign: *','Origin: http://www.wwei.cn']);
p($http->getJson(), true);
```

*11. 过程干预*

```
$urls = 'https://www.baidu.com';
$http = Whttp::get($urls)->writefunc(function($ch, $exec){
    // 一段一段的读取，可以用来响应数据进行分析
    echo $exec;
    // 必须要,断开连接返回false
    return true;
});
if ($http->getError()) {
    $http = "error: ".$http->getError();
} else {
    $http = $http->getBody();
}
p($http,true);
```

*12. 一个缓存例子*

```
$param = [
    'redis' => [
        'host'     => '127.0.0.1',
        // 获取今天剩余时间(秒)
        'expire'   => 86400-(time()+8*3600)%86400,
        // 'decache' => true,
        'callback' => function($data) {
            // 先判断数据是否是正常的，不是想要的就不缓存
            if( strlen((string)$data['body']) != 64){
                // 不缓存
                return false;
            } else {
                // 缓存
                return true;
            }
        },
    ],

    'url'  => 'http://demo.com/v1/login/',
    'data' => 'user=123&password=123',
];
$token = Whttp::get($param['url'], $param['data'])
            ->cache($param['redis'])
            ->core('token":"','"')
            ->getBody();
return (string)$token;
```

\*13. 更多说明

```
/**
 * 请求模式参数
 * @var array
 */
private static $method = [
    'GET'     => ['string|array', 'string|array'],
    'POST'    => ['string|array', 'string|array'],
    'PUT'     => ['string|array', 'string|array'],
    'PATCH'   => ['string|array', 'string|array'],
    'DELETE'  => ['string|array', 'string|array'],
];

/**
 * 设置参数列表1
 * @var array
 */
protected static $setlist1 = [
    'jump'      => ['boolean|NULL'],
    // 跳过重定向(默认会跳过重定向)(可空)

    'header'    => ['array'],
    // 请求协议头

    'cookie'    => ['string'],
    // 请求cookie

    'timeoutms' => ['integer', 'integer|NULL'],
    // 默认超时时间都是5000毫秒
    // 超时时间(参数1响应超时、参数2连接超时)默认设置一个参数是请求超时，支持数组(毫秒)

    'nobody'    => ['boolean|NULL'],
    // 不要body 只返回响应头信息(默认要body)(超快)(可空)

    'referer'   => ['string'],
    // 伪装请求来路

    'proxy'     => ['string'],
    // HTTP代理

    'socks5'    => ['string'],
    // socks5代理

    'fool'      => ['string'],
    // 伪装用户IP，有些无效

    'utf8'      => ['boolean|NULL'],
    // 解码UTF8响应内容(在返回内容乱码的情况下使用)(可空)

    'left'      => ['string'],
    // 截取返回Body指定左边字符

    'core'      => ['string', 'string'],
    // 截取返回Body指定中间字符

    'right'     => ['string'],
    // 截取返回Body指定右边字符

    'cache'     => ['array|NULL'],
    /* 默认缓存配置(Redis)(为空时就使用下面默认配置)
    $default = [
        'host'    => '127.0.0.1',  // Redis连接IP
        'pass'    => '',           // 密码
        'expire'  => 60,           // 默认缓存到期时间
        'decache' => false,        // 删除缓存并且重新请求
        'cacheid' => '',           // 设置缓存id,不设置默认id
        // 允许失败或超时请求次数
        // 意思就是请求3次都错误就请求返回空，
        // 避免服务器高请求导致大量占用资源卡死
        'count'   => 3,  // 默认0不限制
        // 超时请求高于次数设置的缓存时间（秒）
        // 意思就是上面的错误次数后,服务器返回空的时间
        'overtimedue' => 60,
        // 缓存数据先处理,选择性进行数据缓存(true:缓存,false:不缓存)
        'callback' => null, // 有1个参数 function($data){}
    ];
    */

    'writefunc' => ['callable'],
    // 回调方法,可以干预实时获取的内容,有2个参数 function($ch,$exec){}

    'savepath'  => ['string'],
    // 下载保存的路径

    'savename'  => ['string'],
    // 下载保存文件名称(批量下载无效)(默认下载地址获取文件名称)

    'concurrent' => ['integer|NULL'],
    // 设置并发数量限制(默认为10)

    'gany'       => ['object'],
    // 回调处理,不是每个请求都很快响应，这里就可以做到谁请求完成了就处理谁 function($data){}
];

// 返回方法说明
/**
 * 获取响应状态码(不支持并发)
 * @return int 状态码
 */
// public function getCode();

/**
 * 获取响应头部(不支持并发)
 * @param  string $name 名称(.号分割)
 * @return string
 */
// public function getHeaders (string $name="");

/**
 * 获取响应内容(不支持并发)
 * @return data
 */
// public function getBody();

/**
 * 获取请求信息(不支持并发)
 * @param  string $name 名称(.号分割)
 * @return array
 */
// public function getInfo(string $name="");

/**
 * 获取错误信息(不支持并发)
 * @return string
 */
// public function getError();

/**
 * 以数组形式返回(不支持并发)
 * @param  string $name 名称(.号分割)
 * @return array
 */
// public function getJson(string $name="");

/**
 * 获取到全部信息(不支持并发)
 * @param  string $name 名称(.号分割)
 * @return array
 */
// public function getAll(string $name="");

/**
 * 下载文件(批量下载无法显示进度)
 * @Author   laoge
 * @DateTime 2021-03-23
 * @param    callable   $callback  回调处理,不是每个请求都很快响应，这里就可以做到谁请求完成了就处理谁
 * @return   array
 */
// public function getDownload(callable $callback=null)
```

###  Health Score

39

—

LowBetter than 86% of packages

Maintenance59

Moderate activity, may be stable

Popularity19

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity58

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~60 days

Recently: every ~356 days

Total

28

Last Release

245d ago

PHP version history (3 changes)v4.2.8PHP &gt;=7.2.0

v4.4.0PHP &gt;=7.1.0

v4.5.1PHP &gt;=7.1.0 &lt;8.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/db9e85d8273dd919743b6899015f22d056fe799657610477d8388956cf1a864e?d=identicon)[playm3u8](/maintainers/playm3u8)

---

Top Contributors

[![playm3u8](https://avatars.githubusercontent.com/u/42953966?v=4)](https://github.com/playm3u8 "playm3u8 (17 commits)")

### Embed Badge

![Health badge](/badges/playm3u8-whttp/health.svg)

```
[![Health](https://phpackages.com/badges/playm3u8-whttp/health.svg)](https://phpackages.com/packages/playm3u8-whttp)
```

###  Alternatives

[friendsofsymfony/rest-bundle

This Bundle provides various tools to rapidly develop RESTful API's with Symfony

2.8k73.3M319](/packages/friendsofsymfony-rest-bundle)[php-http/discovery

Finds and installs PSR-7, PSR-17, PSR-18 and HTTPlug implementations

1.3k309.5M1.2k](/packages/php-http-discovery)[nyholm/psr7

A fast PHP7 implementation of PSR-7

1.3k235.4M2.4k](/packages/nyholm-psr7)[pusher/pusher-php-server

Library for interacting with the Pusher REST API

1.5k94.8M293](/packages/pusher-pusher-php-server)[spatie/crawler

Crawl all internal links found on a website

2.8k16.3M52](/packages/spatie-crawler)[react/http

Event-driven, streaming HTTP client and server implementation for ReactPHP

78126.4M414](/packages/react-http)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
