hyperf 四、控制器

文档地址:Hyperf

结合之前文章,路由和获取请求不再说明。

一、避免携程间数据混淆

根据文档:

Hyperf 内绝大部分的对象包括 Controller 都是以 单例(Singleton) 形式存在。

编写代码时请务必注意 不要 将单个请求相关的数据储存在类属性内,包括非静态属性。

实际使用的类仅仅是一个代理类,实际调用的都是从 协程上下文(Context) 中获取。

若必须存储,使用Hyperf\HttpServer\Contract\RequestInterface对应的 Hyperf\HttpServer\Requestyperf\HttpServer\Contract\ResponseInterface对应的 Hyperf\HttpServer\Response。

官网说的这点比较模糊。

1.1 单例模式

        单例模式定义:提供访问唯一对象的办法,可直接访问不用实例化。

class Use{
        private static $object = NULL;//初始化为NULL,没有对象 
        
        private function __construct()
        {
          //构造函数
        }
        
        public static function getInstance()
        {  
          //判断类内部的静态属性是否存在对象
           if(!(self::$object instanceof self)){   //当前保存的内容不是当前类的对象
               self::$object = new self();
            }
          //返回对象给外部
           return self::$object;
        }
}
$s1=Use::getSingleton();

我查代码,比如Hyperf\HttpServer\Contract\RequestInterface也不是单例类。

源码控制器里面继承的AbstractController为抽象类,但是php8之前对继承规范校验也不严格,所以意义不大。


declare (strict_types = 1);
/**
 * This file is part of Hyperf.
 *
 * @link     https://www.hyperf.io
 * @document https://hyperf.wiki
 * @contact  group@hyperf.io
 * @license  https://github.com/hyperf/hyperf/blob/master/LICENSE
 */
namespace App\Controller;

class IndexController extends AbstractController
{
    public function index()
    {
        $user = $this->request->input('user', 'Hyperf');
        $method = $this->request->getMethod();

        return [
            'method' => $method,
            'message' => "Hello {$user}.",
        ];
    }

    public function test()
    {
        $test = $this->request->post();
        var_dump($test);
    }
}

#App\Controller\AbstractController

abstract class AbstractController
{
    /**
     * @Inject
     * @var ContainerInterface
     */
    protected $container;

    /**
     * @Inject
     * @var RequestInterface
     */
    protected $request;

    /**
     * @Inject
     * @var ResponseInterface
     */
    protected $response;
}

      其他地方确实有静态类,但不一定像文档上说的这么多,所以设置类内变量做存储的影响还需要测试。

1.2 类内数据存储


declare (strict_types = 1);
namespace App\Controller;

use Hyperf\HttpServer\Annotation\AutoController;
use Hyperf\HttpServer\Contract\RequestInterface;

/**
 * @AutoController()
 */
class TestController extends AbstractController
{
    private $name;
    public function index1(RequestInterface $request)
    {
        $user = $request->input('user', 'Hyperf');
        $name = "name" . $user;
        $this->request->name = $name;
        $method = $this->request->getMethod();
        $this->getname();
        return [
            'method' => $method,
            'message' => "Hello {$name}.",
        ];
    }
    private function getname()
    {
        var_dump($this->name); //打印null
        var_dump($this->request->name);//nameHyperf
    }
}

证明类内数据存储使用$this->request或者$this->response。

其他类存储数据可以用以下代码存到上下文里。

public function __set($name, $value){
        return Context::set(__CLASS__ . ":" .$name, $value);
    }

    public function __get($name){
        return Context::get(__CLASS__ . ":" . $name);
    }

根据文章:

hyperf 协程数据混淆的思考和分析_hyper 解决 协成上下文数据共享问题_子非 。的博客-CSDN博客

混淆大概指类内成员值第一次请求正常,第二次请求修改,第三次请求获取为修改后的值。

用php-fpm肯定不会这样,因为每次请求是开一个线程。swoole是都在单个线程共享内存,一个客户端请求应该是在一个线程里,所以多次请求后,同一个客户端请求同一个值会有不同。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,我可以帮你解答这个问题。 要在 Kubernetes 上安装 Hyperf,需要进行以下步骤: 1. 创建一个 Kubernetes 集群,并确保你已经部署了 Kubernetes Dashboard。 2. 部署 MySQL 数据库和 Redis 缓存服务。你可以使用 Kubernetes 上的 StatefulSet 和 Service 对象来完成这项任务。 3. 部署 Hyperf 应用程序。你可以使用 Kubernetes 上的 Deployment 和 Service 对象来部署 Hyperf 应用程序。 4. 配置 Ingress 控制器。你可以使用 Kubernetes 上的 Ingress 对象来完成 Ingress 控制器的配置。 下面是一个简单的 YAML 文件示例,用于在 Kubernetes 上部署 Hyperf 应用程序: ``` apiVersion: apps/v1 kind: Deployment metadata: name: hyperf-app spec: replicas: 1 selector: matchLabels: app: hyperf-app template: metadata: labels: app: hyperf-app spec: containers: - name: hyperf-app image: your-hyperf-image ports: - containerPort: 9501 env: - name: DB_HOST value: mysql-service - name: DB_USERNAME value: your-db-username - name: DB_PASSWORD value: your-db-password - name: REDIS_HOST value: redis-service - name: REDIS_PORT value: "6379" --- apiVersion: v1 kind: Service metadata: name: hyperf-service spec: selector: app: hyperf-app ports: - name: http port: 80 targetPort: 9501 type: LoadBalancer --- apiVersion: extensions/v1beta1 kind: Ingress metadata: name: hyperf-ingress spec: rules: - host: your.domain.com http: paths: - path: / backend: serviceName: hyperf-service servicePort: http ``` 在这个 YAML 文件中,我们定义了一个名为 hyperf-app 的 Deployment 对象,用于部署 Hyperf 应用程序。我们还定义了一个名为 hyperf-service 的 Service 对象,用于将流量路由到 Hyperf 应用程序。最后,我们使用了一个名为 hyperf-ingress 的 Ingress 对象,用于配置 Ingress 控制器。 请注意,这只是一个简单的示例。在实际部署中,你需要根据你的具体需求进行更改和调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lsswear

感谢大佬打赏 q(≧▽≦q)

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值