8、Workerman 基本使用 - HTTP 服务 请求与响应

作者: 温新

图书: 【Workerman 基本使用】

阅读: 459

时间: 2024-11-10 13:20:30

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();

返回值可能是GETPOSTPUTDELETEOPTIONSHEAD中的一个。

获取请求 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();
请登录后再评论