8、Workerman 基本使用 - HTTP 服务 请求与响应
hi,我是温新,一名 PHPer
本文根据文档中的案例进行一个演示,主要还是动手操作。
HTTP 请求
获取请求参数 GET
获取所有参数
$request->get();
获取单个参数
$request->get('name');
参数默认值,若获取的参数不存在存在,则使用默认值
$request->get('name', '王美丽');
案例
<?php
/**
 * http.php
 *
 * HTTP 服务,GET 参数
 */
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
use Workerman\Protocols\Http\Request;
require_once __DIR__ . '/vendor/autoload.php';
$http = new Worker('http://0.0.0.0:8888');
$http->onMessage = function (TcpConnection $connection, Request $request) {
    $connection->send($request->get('name', '王美美'));
};
Worker::runAll();
测试
$ curl 127.0.0.1:8888?name=meili
meili
获取请求参数 POST
post 请求获取参数与 get 一样,只是方法变成了 post。
...
    
$http->onMessage = function (TcpConnection $connection, Request $request) {
    $post = $request->post();
    print_r($post);
    $connection->send('hello');
};;
...
使用 curl 进行测试 curl -X POST 127.0.0.1:8888 -d "name=lili&age=19"
获得原始请求 post 包体
rawBody 用于获取 HTTP 原始请求数据。当发送的数据格式为 application/x-www-form-urlencoded 时,这将变得很有用,如下案例:
...
    
$http->onMessage = function (TcpConnection $connection, Request $request) {
    $post = $request->rawBody();
    print_r(json_decode($post,true));
    $connection->send('hello');
};
...
客户端测试
$ curl -X POST 127.0.0.1:8888 \
-H "Content-Type: application/x-www-form-urlencoded" \
-d '{"name":"美丽", "age":19}'
服务端输出
$ php http.php start
...
Array
(
    [name] => 美丽
    [age] => 19
)
获取请求头信息
...
    
$http->onMessage = function (TcpConnection $connection, Request $request) {
    $headers = $request->header();
    print_r($headers);
    $connection->send('hello');
};
...
浏览器中访问 127.0.0.1:8888,恶服务端输出的信息如下:
Array
(
    [host] => localhost:8888
    [connection] => keep-alive
    [sec-ch-ua] => "Google Chrome";v="119", "Chromium";v="119", "Not?A_Brand";v="24"
    [sec-ch-ua-mobile] => ?0
    [user-agent] => Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36
    [sec-ch-ua-platform] => "Linux"
    [accept] => image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8
    [sec-fetch-site] => same-origin
    [sec-fetch-mode] => no-cors
    [sec-fetch-dest] => image
    [referer] => http://localhost:8888/?name=wangmeili&age=17
    [accept-encoding] => gzip, deflate, br, zstd
    [accept-language] => zh-CN,zh;q=0.9
)
获取 cookie
···
    
$http->onMessage = function (TcpConnection $connection, Request $request) {
    $cookies = $request->cookie();
    print_r($cookies);
    $connection->send('hello');
};
...
客户端测试
$ curl --cookie "username=王美丽; id=1" -X GET 127.0.0.1:8888
服务端输出
Array
(
    [username] => 王美丽
    [id] => 1
)
上传文件
...
    
$http->onMessage = function (TcpConnection $connection, Request $request) {
    $file = $request->file('file');
    print_r($file);
    $connection->send('hello');
};
...
客户端测试
$ curl -X POST \
-F "name=file" \
-F "file=@文件路径" \
http://127.0.0.1:8888
服务端输出
$ php http.php start
...
Array
(
    [name] => swoole.jpg
    [tmp_name] => /tmp/workerman.upload.kSnhwK
    [size] => 88591
    [error] => 0
    [type] => image/jpeg
)
- name 为文件名字
 - tmp_name 为磁盘临时文件位置
 - size 为文件大小
 - error 为错误码
 - type 为文件 mine 类型。
 
注意:上传的文件不存在则返回 null
获取 host
// 127.0.0.1:8888
$host = $request->host();
// 127.0.0.1
$host = $request->host(true);
若不需要端口,则传递 true
获取请求方法
$method = $request->method();
返回值可能是GET、POST、PUT、DELETE、OPTIONS、HEAD中的一个。
获取请求 uri
$uri = $request->uri();
测试
$ curl http://127.0.0.1:8888 # 输出 /
$ curl http://127.0.0.1:8888/user/index # 输出 /user/index
$ curl http://127.0.0.1:8888/user?page=1 # 输出 /user?page=1
获取请求路径
$path = $request->path();
测试
$ curl http://127.0.0.1:8888/user/index.php # 输出 /user/index.php
$ curl http://127.0.0.1:8888/user?query=meili # 输出 /user
获取查询参数
$queryString = $request->queryString();
浏览器访问 http://127.0.0.1:8888/?name=meili&age=19 ,输出 name=meili&age=19。
HTTP 响应
状态码
<?php
/**
 * http.php
 *
 * HTTP 服务 响应
 */
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
use Workerman\Protocols\Http\Request;
use Workerman\Protocols\Http\Response;
require_once __DIR__ . '/vendor/autoload.php';
$http = new Worker('http://0.0.0.0:8888');
$http->onMessage = function (TcpConnection $connection, Request $request) {
    if ($request->path() === '/404') {
        $connection->send(new Response(404,[], '<h1>哦豁,页面丢失了~~</h1>'));
    }
    $connection->send('<h1>workerman 一个牛逼的男银</h1>');
};;
Worker::runAll();
浏览器打开 F12,然后访问 http://127.0.0.1:8888/404,注意状态码。
响应 header
...
$http->onMessage = function (TcpConnection $connection, Request $request) {
    $htmlContent = '<h1>workerman 一个牛逼的男银</h1>';
    /**
     * int $status 状态码
     * array $headers 返回头信息
     * string $body 内容
     */
    $response = new Response(200, [
        'Content-Type'    => 'text/html;Charset=UTF-8',
        'x-ziruchu-views' => 3,
    ], $htmlContent);
    $connection->send($response);
};
...
测试
$ curl 127.0.0.1:8888 -i
HTTP/1.1 200 OK
Server: workerman
Content-Type: text/html;Charset=UTF-8 # 返回的头信息
x-ziruchu-views: 3 # 返回的头信息
Connection: keep-alive
Content-Length: 40
设置 cookie
...
    
$worker->onMessage = function(TcpConnection $connection, Request $request){
    $response = new Response(200, [], '设置 cookid');
    $response->cookie('name', '王美丽');
    $connection->send($response);
};
...
浏览器访问后,打开 F12 查看 cookie
发送文件
<?php
/**
 * http.php
 *
 * HTTP 服务 响应
 */
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
use Workerman\Protocols\Http\Request;
use Workerman\Protocols\Http\Response;
require_once __DIR__ . '/vendor/autoload.php';
$worker = new Worker('http://0.0.0.0:8888');
$worker->onMessage = function(TcpConnection $connection, Request $request){
    $file = '/home/www/learnSwoole/workerman/wm-study/swoole.jpg';
    // 检查请求头中的 If-Modified-Since 字段
    $ifModifiedSince = $request->header('if-modified-since');
    // 如果存在 If-Modified-Since 字段并且文件自上次修改时间以来未变化
    if (!empty($ifModifiedSince)) {
        // 获取文件的实际修改时间,并格式化为HTTP日期字符串
        $modifiedTime = date('D, d M Y H:i:s',  filemtime($file)) . ' ' . date_default_timezone_get();
        // 比较并判断文件是否已修改
        if ($modifiedTime === $ifModifiedSince) {
            // 文件未修改,发送304 Not Modified响应
            $connection->send(new Response(304));
            return;
        }
    }
    // 文件已修改或没有提供 If-Modified-Since 字段,直接发送文件内容作为响应
    $response = (new Response())->withFile($file);
    $connection->send($response);
};
Worker::runAll();
                请登录后再评论