Hyperf 安装,使用,

安装,

一般开发都是windows,所以用虚拟机或docker

使用

启动

 php bin/hyperf.php start

在这里插入图片描述

如果出现端口被占用,下面的处理方法

  1. 查看9501端口那个进程在占用
 netstat -anp|grep 9501

在这里插入图片描述
2. kill掉

kill 18
  1. 然后再启动即可

热更新

Watcher 组件除了解决上述启动问题,还提供了文件修改后立马重启的功能。

安装

composer require hyperf/watcher --dev

发布配置

php bin/hyperf.php vendor:publish hyperf/watcher

发布配置后在目录config/autoload/下自动生成watcher.php文件

在这里插入图片描述
配置 默认值 备注

driverScanFileDriver默认定时扫描文件驱动
binPHP_BINARY用于启动服务的脚本
watch.dirapp, config监听目录
watch.file.env监听文件
watch.interval2000扫描间隔(毫秒)
ext.php, .env监听目录下的文件扩展名

启动

hyperf框架可以使用hyperf/watcher进行热更新操作,不用每次修改完代码都重启服务
注意:
使用php bin/hyperf.php server:watch这个命令后,php bin/hyperf.php start 这个命令将废弃

php bin/hyperf.php server:watch

路由

配置文件路由

<?php
use Hyperf\HttpServer\Router\Router;

// 此处代码示例为每个示例都提供了三种不同的绑定定义方式,实际配置时仅可采用一种且仅定义一次相同的路由

// 设置一个 GET 请求的路由,绑定访问地址 '/get' 到 App\Controller\IndexController 的 get 方法
Router::get('/get', 'App\Controller\IndexController::get');
Router::get('/get', 'App\Controller\IndexController@get');
Router::get('/get', [\App\Controller\IndexController::class, 'get']);

// 设置一个 POST 请求的路由,绑定访问地址 '/post' 到 App\Controller\IndexController 的 post 方法
Router::post('/post', 'App\Controller\IndexController::post');
Router::post('/post', 'App\Controller\IndexController@post');
Router::post('/post', [\App\Controller\IndexController::class, 'post']);

// 设置一个允许 GET、POST 和 HEAD 请求的路由,绑定访问地址 '/multi' 到 App\Controller\IndexController 的 multi 方法
Router::addRoute(['GET', 'POST', 'HEAD'], '/multi', 'App\Controller\IndexController::multi');
Router::addRoute(['GET', 'POST', 'HEAD'], '/multi', 'App\Controller\IndexController@multi');
Router::addRoute(['GET', 'POST', 'HEAD'], '/multi', [\App\Controller\IndexController::class, 'multi']);

路由组

Router::addGroup('/user',function (){
    Router::get('/index', 'App\Controller\UserController::index');
    Router::post('/create', 'App\Controller\UserController::createUser');
    Router::put('/update', 'App\Controller\UserController::update');
    Router::delete('/delete', 'App\Controller\UserController::delete');
});

必填参数

我们可以对 $uri 进行一些参数定义,通过 {} 来声明参数,如 /user/{id} 则声明了 id 值为一个必填参数。

可选参数

有时候您可能会希望这个参数是可选的,您可以通过[]来声明中括号内的参数为一个可选参数,如 /user/[{id}]

校验参数

您也可以使用正则表达式对参数进行校验,以下是一些例子

use Hyperf\HttpServer\Router\Router;

// 可以匹配 /user/42, 但不能匹配 /user/xyz
Router::addRoute('GET', '/user/{id:\d+}', 'handler');

// 可以匹配 /user/foobar, 但不能匹配 /user/foo/bar
Router::addRoute('GET', '/user/{name}', 'handler');

// 也可以匹配 /user/foo/bar as well
Router::addRoute('GET', '/user/{name:.+}', 'handler');

// 这个路由
Router::addRoute('GET', '/user/{id:\d+}[/{name}]', 'handler');
// 等同于以下的两个路由
Router::addRoute('GET', '/user/{id:\d+}', 'handler');
Router::addRoute('GET', '/user/{id:\d+}/{name}', 'handler');

// 多个可选的嵌套也是允许的
Router::addRoute('GET', '/user[/{id:\d+}[/{name}]]', 'handler');

// 这是一条无效的路由, 因为可选部分只能出现在最后
Router::addRoute('GET', '/user[/{id:\d+}]/{name}', 'handler');

注解路由

在这里插入图片描述

例如:

<?php
/**
 * OrderController.php
 *
 * Created on Orders-11:19
 * Created by xxp 332410549@qq.com
 */

namespace App\Controller;


use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\GetMapping;
use Hyperf\HttpServer\Contract\RequestInterface;


/**
 * @Controller(prefix="order")
 */
class OrderController extends AbstractController
{

    /**
     * @GetMapping(path="index")
     */
    public function index(RequestInterface $request)
    {
        return 'OrderController'.$request->input('id');
    }
}

访问地址

http://hyperf.demos.xp:9501/order/index

HTTP 异常

在路由匹配不到路由时,如 路由找不到(404)请求方法不允许(405) 等 HTTP 异常,Hyperf 会统一抛出一个 Hyperf\HttpMessage\Exception\HttpException 异常类的子类,
您需要通过 ExceptionHandler 机制来管理这些异常并做对应的响应处理,默认情况下可以直接使用组件提供的 Hyperf\HttpServer\Exception\Handler\HttpExceptionHandler 来进行异常捕获处理,注意这个异常处理器需要您自行配置到 config/autoload/exceptions.php 配置文件中去,并保障多个异常处理器之间的顺序链路是正确的。
当您需要对 路由找不到(404)请求方法不允许(405) 等 HTTP 异常情况的响应进行自定义处理时,您可直接根据 HttpExceptionHandler 的代码实现您自己的异常处理器,并配置您自己的异常处理器。关于异常处理器的逻辑和使用说明,可具体查阅 异常处理

异常处理器

在 Hyperf 里,业务代码都运行在 Worker 进程 上,也就意味着一旦任意一个请求的业务存在没有捕获处理的异常的话,都会导致对应的 Worker 进程 被中断退出,这对服务而言也是不能接受的,捕获异常并输出合理的报错内容给客户端也是更加友好的。
我们可以通过对各个 server 定义不同的 异常处理器(ExceptionHandler),一旦业务流程存在没有捕获的异常,都会被传递到已注册的 异常处理器(ExceptionHandler) 去处理。

自定义一个异常处理

在这里插入图片描述

1. 通过配置文件注册异常处理器

config/autoload/exceptions.php 文件

<?php
// config/autoload/exceptions.php
return [
    'handler' => [
        'http' => [
            Hyperf\HttpServer\Exception\Handler\HttpExceptionHandler::class,
            App\Exception\Handler\AppExceptionHandler::class,
            App\Exception\Handler\FooExceptionHandler::class,
        ],
    ],
];


2. 定义异常处理器

app/Exception/Handler/FooExceptionHandler.php

<?php
/**
 * FooExceptionHandler.php
 *
 * Created on ExceptionHandler -13:35
 * Created by xxp 332410549@qq.com
 */

namespace App\Exception\Handler;

use App\Exception\FooException;
use Hyperf\ExceptionHandler\ExceptionHandler;
use Hyperf\HttpMessage\Stream\SwooleStream;
use Psr\Http\Message\ResponseInterface;
use Throwable;

class FooExceptionHandler extends ExceptionHandler
{

    /**
     * @inheritDoc
     */
    public function handle(Throwable $throwable, ResponseInterface $response)
    {
        // 判断被捕获到的异常是希望被捕获的异常
        if ($throwable instanceof FooException) {
            // 格式化输出
            $data = json_encode([
                'code' => $throwable->getCode(),
                'message' => $throwable->getMessage(),
            ], JSON_UNESCAPED_UNICODE);

            // 阻止异常冒泡
            $this->stopPropagation();
            return $response->withStatus(500)->withBody(new SwooleStream($data));
        }

        // 交给下一个异常处理器
        return $response;
    }

    /**
     * @inheritDoc
     */
    public function isValid(Throwable $throwable): bool
    {
       return true;
    }

}
3. 定义异常类

app/Exception/FooException.php

<?php
/**
 * FooException.php
 *
 * Created on FooException-13:40
 * Created by xxp 332410549@qq.com
 */

namespace App\Exception;

use Hyperf\Server\Exception\ServerException;

class FooException extends ServerException
{


}
4. 触发异常
<?php
/**
 * OrderController.php
 *
 * Created on Orders-11:19
 * Created by xxp 332410549@qq.com
 */

namespace App\Controller;


use App\Exception\FooException;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\GetMapping;
use Hyperf\HttpServer\Contract\RequestInterface;


/**
 * @Controller(prefix="order")
 */
class OrderController extends AbstractController
{

    /**
     * @GetMapping(path="index")
     */
    public function index(RequestInterface $request)
    {
        try {

            $data = [
                'code' => 0,
                'msg' => '获取成功',
                'data' => [
                    'orders' => '订单列表'
                ]
            ];
            if (1) {   // 如果没有数据,返回空数组
              throw new FooException('自定义异常');
            }
            return $this->response->json($data);
        } catch (\Exception $e) {
            return $this->response->json(['code' => 1,'msg' => $e->getMessage()]);
        }
    }



}
查看解决

在这里插入图片描述

总结:
在上面这个例子,我们先假设 FooException 是存在的一个异常,以及假设已经完成了该处理器的配置,那么当业务抛出一个没有被捕获处理的异常时,就会根据配置的顺序依次传递,整一个处理流程可以理解为一个管道,若前一个异常处理器调用 $this->stopPropagation() 则不再往后传递,若最后一个配置的异常处理器仍不对该异常进行捕获处理,那么就会交由 Hyperf 的默认异常处理器处理了。

Error 监听器

框架提供了 error_reporting() 错误级别的监听器 Hyperf\ExceptionHandler\Listener\ErrorExceptionHandler

配置

在 config/autoload/listeners.php 中添加监听器

<?php
return [
    \Hyperf\ExceptionHandler\Listener\ErrorExceptionHandler::class
];

抓取错误

则当出现类似以下的代码时会抛出 \ErrorException 异常

    public function index(RequestInterface $request)
    {
        try {

            $a = [];
            ($a[1]);
            return $this->response->json($data);
        } catch (\Throwable $e) {
            return $this->response->json(['code' => 1,'msg' => $e->getMessage() ."\n num:". $e->getLine()]);
        }
    }

结果

在这里插入图片描述

Ioc & Di

在这里插入图片描述
在这里插入图片描述

注入方式

简单注入

通过构造函数注入

在这里插入图片描述

Inject 注解

需要和下面 @var UserService 配置 UserService 类的类型
在这里插入图片描述

工厂对象注入

在这里插入图片描述
在这里插入图片描述

config/dependencies.php

在这里插入图片描述

php常用命令

查看php运行环境

可以看到php.ini文件所在的位置

php -i | grep ini

在这里插入图片描述

查看php某个扩展的详细详细信息

php --ri  xxx 
php --ri  swoole

在这里插入图片描述

压测工具

ab -k -c 100 -n 10000 http:127.0.0.01:9501
选项作用
-n在测试会话中所执行的请求个数。默认时,仅执行一个请求。
-c一次产生的请求个数。默认是一次一个。
-t测试所进行的最大秒数。其内部隐含值是-n 50000,它可以使对服务器的测试限制在一个固定的总时间以内。默认时,没有时间限制。
-p包含了需要POST的数据的文件。
-P对一个中转代理提供BASIC认证信任。用户名和密码由一个:隔开,并以base64编码形式发送。无论服务器是否需要(即, 是否发送了401认证需求代码),此字符串都会被发送。
-TPOST数据所使用的Content-type头信息。
-v设置显示信息的详细程度-4或更大值会显示头信息,3或更大值可以显示响应代码(404,200等),2或更大值可以显示警告和其他信息。
-V显示版本号并退出。
-w以HTML表的格式输出结果。默认时,它是白色背景的两列宽度的一张表。
-i执行HEAD请求,而不是GET。
-x设置属性的字符串。
-X对请求使用代理服务器。
-y设置属性的字符串。
-z设置属性的字符串。
-C对请求附加一个Cookie:行。其典型形式是name=value的一个参数对,此参数可以重复。
-H对请求附加额外的头信息。此参数的典型形式是一个有效的头信息行,其中包含了以冒号分隔的字段和值的对(如,“Accept-Encoding:zip/zop;8bit”)。
-A对服务器提供BASIC认证信任。用户名和密码由一个:隔开,并以base64编码形式发送。无论服务器是否需要(即,是否发送了401认证需求代码),此字符串都会被发送。
-h显示使用方法。
-d不显示"percentage served within XX [ms] table"的消息(为以前的版本提供支持)。
-e产生一个以逗号分隔的(CSV)文件,其中包含了处理每个相应百分比的请求所需要(从1%到100%)的相应百分比的(以微妙为单位)时间。由于这种格式已经“二进制化”,所以比’gnuplot’格式更有用。
-g把所有测试结果写入一个’gnuplot’或者TSV(以Tab分隔的)文件。此文件可以方便地导入到Gnuplot,IDL,Mathematica,Igor甚至Excel中。其中的第一行为标题。
-i执行HEAD请求,而不是GET。
-k启用HTTP KeepAlive功能,即在一个HTTP会话中执行多个请求。默认时,不启用KeepAlive功能。
-q如果处理的请求数大于150,ab每处理大约10%或者100个请求时,会在stderr输出一个进度计数。此-q标记可以抑制这些信息。
-r在遇到socket接收错误后,不退出测试

yum 安装

如果没安装这个工具,可执行下面的命令

yum -y install httpd-tools #这样安装使其不能支持大于20000的并发数

yum -y install httpd-tools

源码安装

yum -y install gcc gcc-c++ automake apr apr-util pcre apr-devel apr-util-devel pcre-devel		#安装httpd依赖
wget https://mirror.bit.edu.cn/apache//httpd/httpd-2.4.43.tar.gz		#下载httpd包
tar -zxvf httpd-2.4.43.tar.gz -C /usr/src		#解压httpd包
cd /usr/src/httpd-2.4.43						#切换目录到httpd包所在
./configure --prefix=/usr/local/httpd			#编译
make && make install							#安装
ln -s /usr/local/httpd/bin/* /usr/bin			#做软链接
ulimit -n 65535									#修改同时最大打开的文件数,此为临时性的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值