zoukankan      html  css  js  c++  java
  • 面试之后才知道,swoole完美支持TP5?!

    协程是什么

    协程可以理解为纯用户态的线程,其通过协作而不是抢占来进行切换,相对于进程或者线程,协程所有的操作都可以在用户态完成,创建和切换的消耗更低,Swoole 可以为每一个请求创建对应的协程,根据 IO 的状态来合理的调度协程。

    在 Swoole 4.x 中,协程(Coroutine)取代了异步回调,成为 Swoole 官方推荐的编程方式。Swoole 协程解决了异步回调编程困难的问题,使用协程可以以传统同步编程的方法编写代码,底层自动切换为异步 IO,既保证了编程的简单性,又可借助异步 IO,提升系统的并发能力。

    完美支持TP5,首先开启swoole的http服务

    开启swoole的http服务并设置提供给url访问页面的文件的根目录,

    代码如下。这样在浏览器只能访问…static下面的文件,而无法访问其他目录下的文件。

    http.server

    <?php
    //开启http server
    $http = new swoole_http_server("0.0.0.0", 9905);
    $http->set(
        [
            'enable_static_handler' => true,
            'document_root' => "/usr/local/openresty/nginx/html/swoole/LiveRadio/public/static",
            'worker_num' => 5
        ]
    );
    $http->on('request', function($request, $response) {
        $response->end("sss". json_encode($request->get));
    });
    
    $http->start();
    

    swoole有一个事件回调函数onWorkStart,此事件在Worker进程/Task进程启动时发生。这里创建的对象可以在进程生命周期内使用。

    原型:

    function onWorkerStart(swoole_server $server, int workerid);

    (1)onWorkerStart/onStart是并发执行的,没有先后顺序;

    (2)可以通过server->taskworker属性来判断当前是Worker进程还是Task进程;

    (3)设置了worker_num和task_worker_num超过1时,每个进程都会触发一次onWorkerStart事件,可通过判断$worker_id区分不同的工作进程;

    (4)由 worker 进程向 task 进程发送任务,task 进程处理完全部任务之后通过onFinish回调函数通知worker 进程。

    例如,我们在后台操作向十万个用户群发通知邮件,操作完成后操作的状态显示为发送中,这时我们可以继续其他操作。等邮件群发完毕后,操作的状态自动改为已发送。

    在onWorkerStart中加载框架的核心文件后:

    (1)不用每次请求都加载框架核心文件,提高性能;

    (2)可以在后续的回调事件中继续使用框架的核心文件或者类库。

    项目目录下的public文件夹下的index.php是入口文件,源码如下:

    <?php
    // [ 应用入口文件 ]
    // 定义应用目录
    define('APP_PATH', __DIR__ . '/../application/');
    // 加载框架引导文件
    require __DIR__ . '/../thinkphp/start.php';
    

    这个文件加载了…thinkphp/start.php’,start.php加载了一个核心文件base.php,所以我们需要把base.php文件加载到onWorkStart回调函数里面,每个worker进程都会触发一次onWorkerStart事件,因此ThinkPHP框架内的入口文件等内容就能加载入我们的项目。

    修改http.server如下:

    <?php
    //开启http server
    $http = new swoole_http_server("0.0.0.0", 9906);
    $http->set(
        [
            'enable_static_handler' => true,
            'document_root' => "/usr/local/openresty/nginx/html/swoole/LiveRadio/public/static",
            'worker_num' => 5  //设置worker进程数
        ]
    );
    
    $http->on('WorkerStart', function (swoole_server $server, $worker_id){
        //定义应用目录
        define('APP_PATH', __DIR__ . '/../application/');
        // 加载基础文件
        //这里不直接加载start.php的原因是start.php中的代码会直接执行,也就是applicationindexcontrollerIndex.php文件(框架的默认首页)
        /*
         * Container::get('app', [defined('APP_PATH') ? APP_PATH : ''])
        ->run()
        ->send();
        */
        require __DIR__ . '/../thinkphp/base.php';
    });
    
    $http->on('request', function($request, $response){
        //适配
        /*
         *由于swoole http提供的API和原生php代码是有所不同的,比如原生php中获取get参数为直接从全局数组_GET中获取,而swoole http中是通过$request->get()的方式获取,因此要转换成原生的
         * */
    
        $_SERVER = [];
        if(isset($request->server)){
            foreach($request->header as $k => $v){
                $_SERVER[strtoupper($k)] = $v;
            }
        }
        $_GET = [];
        if(isset($request->get)){
            foreach($request->get as $k => $v){
                $_GET[$k] = $v;
            }
        }
        $_POST = [];
        if(isset($request->post)){
            foreach($request->post as $k => $v){
                $_POST[$k] = $v;
            }
        }
    
        //..其余参数用到的继续往后写
    
        ob_start();
        // 执行应用并响应
        try {
            thinkContainer::get('app', [APP_PATH])
                ->run()
                ->send();
        }catch (Exception $e){
            //todo
        }
        $res = ob_get_contents();
        ob_end_clean();
        $response->end($res);
    });
    
    $http->start();
    

    此时,用浏览器访问 http://ip:port/?s=index/index/index 可以看到ThinkPHP的默认首页,但是发现访问不到http://ip:port/?s=index/index/hello?name=world页面。

    可以打印出路由看看。在项目目录 hinkphplibrary hinkApp.php文件中的routeCheck接口,打印path变量,可以看到url改变后path变量并没有改变。这是因为onWorkerStart进程加载框架的时候就复用了类成员变量。

        /**
         * URL路由检测(根据PATH_INFO)
         * @access public
         * @return Dispatch
         */
        public function routeCheck()
        {
            $path = $this->request->path();
            echo "path:".$path."<br/>";
    //        var_dump($this->request);
            $depr = $this->config('app.pathinfo_depr');
    
            // 路由检测
            $files = scandir($this->routePath);
            foreach ($files as $file) {
                if (strpos($file, '.php')) {
                    $filename = $this->routePath . DIRECTORY_SEPARATOR . $file;
                    // 导入路由配置
                    $rules = include $filename;
                    if (is_array($rules)) {
                        $this->route->import($rules);
                    }
                }
            }
    
            // 是否强制路由模式
            $must = !is_null($this->routeMust) ? $this->routeMust : $this->config('app.url_route_must');
    
            // 路由检测 返回一个Dispatch对象
            return $this->route->check($path, $depr, $must, $this->config('app.route_complete_match'));
        }
    

    修改:

    进入 项目目录 hinkphplibrary hinkRequest.php中

    (1)找到function path() { },注销判断,不再复用类成员变量 $ this->path。

    (2)找到function pathinfo() { },注销判断,不再复用类成员变量$this->pathinfo。

    (3)使其支持pathinfo路由,在function pathinfo() { }中添加代码

    if (isset($_SERVER['PATH_INFO']) && $_SERVER['PATH_INFO'] != '/') {
        return ltrim($_SERVER['PATH_INFO'], '/');
    }
    

    在这里插入图片描述

    此时用浏览器访问:
    在这里插入图片描述

    在这里插入图片描述

    点关注,不迷路

    好了各位,以上就是这篇文章的全部内容了,能看到这里的人呀,都是人才。之前说过,PHP方面的技术点很多,也是因为太多了,实在是写不过来,写过来了大家也不会看的太多,所以我这里把它整理成了PDF和文档,如果有需要的可以

    点击进入暗号: PHP+「平台」

    在这里插入图片描述

    在这里插入图片描述


    更多学习内容可以访问【对标大厂】精品PHP架构师教程目录大全,只要你能看完保证薪资上升一个台阶(持续更新)

    以上内容希望帮助到大家,很多PHPer在进阶的时候总会遇到一些问题和瓶颈,业务代码写多了没有方向感,不知道该从那里入手去提升,对此我整理了一些资料,包括但不限于:分布式架构、高可扩展、高性能、高并发、服务器性能调优、TP6,laravel,YII2,Redis,Swoole、Swoft、Kafka、Mysql优化、shell脚本、Docker、微服务、Nginx等多个知识点高级进阶干货需要的可以免费分享给大家,需要的可以加入我的 PHP技术交流群

  • 相关阅读:
    golang并发编程:通道
    golang并发编程:并发同步概述
    java网络通信:TCP协议
    Java基础:GC机制
    Java基础:内存模型
    Java基础:泛型
    Java基础:异常机制
    JavaWEB开发框架:Shiro
    Spring:与Redis的集成
    Spring:面向切片编程
  • 原文地址:https://www.cnblogs.com/it-abu/p/14203710.html
Copyright © 2011-2022 走看看