Home > PHP Framework > Laravel > body text

Try how to change Laravel to Swoole version

藏色散人
Release: 2022-12-02 16:29:02
forward
1191 people have browsed it

This article will give you relevant knowledge about Laravel and Swoole. The main content is to teach you how to change Laravel to the Swoole version (try to learn, it is not recommended to change the existing project). Let’s take a look together. I hope it will be helpful to everyone. Helped!

Preface

It is not recommended to use in production environment

Create a new laravel project

laravel new swoole-laravel
Copy after login

Change Laravel to Swoole version

Create a swoole_server.php file in the root directory of Laravel, and then copy the code in public/index.php over [Recommended learning: laravel video tutorial

<?php
use Illuminate\Contracts\Http\Kernel;
use Illuminate\Http\Request;
define(&#39;LARAVEL_START&#39;, microtime(true));
require __DIR__.&#39;/../vendor/autoload.php&#39;;
$app = require_once __DIR__.&#39;/../bootstrap/app.php&#39;;
$kernel = $app->make(Kernel::class);
$response = $kernel->handle(
    $request = Request::capture()
)->send();
$kernel->terminate($request, $response);
Copy after login

In the first step, the loading of the framework file is certain, and it should be loaded in the main process. There is no need for sub-processes or coroutines to load it repeatedly. Therefore, the require above does not need to be touched.

The second step is to start an HTTP Swoole service. This has been mentioned many times before. Note that in onRequest, we should put the $kernel related code in it.

$http = new Swoole\Http\Server(&#39;0.0.0.0&#39;, 9501);
$http->on(&#39;Request&#39;, function ($req, $res) use($app) {
    try {
        $kernel = $app->make(Kernel::class);
        $response = $kernel->handle(
            $request = Request::capture()
        )->send();
        $kernel->terminate($request, $response);
    }catch(\Exception $e){
        print_r($e->getMessage());
    }
});
echo "服务启动", PHP_EOL;
$http->start();
Copy after login

Is this enough? Why don't you give it a try first. Under normal circumstances, you may not be able to obtain any input or output. Why is this?

The third step is to solve the input problem. In fact, super global variables do not work in Swoole, so variables such as $_GET will become invalid, and Request-related objects in Laravel will not be able to obtain data. What to do about this? We just get this data from the parameters of onRequest and then put it back into $_GET in the current process coroutine.

$http->on(&#39;Request&#39;, function ($req, $res) use($app) {
    $_SERVER = [];
    if(isset($req->server)){
        foreach($req->server as $k => $v){
            $_SERVER[strtoupper($k)] = $v;
        }
    }
    $_GET = [];
    if(isset($req->get)){
        foreach ($req->get as $k => $v){
            $_GET[$k] = $v;
        }
    }
    $_POST = [];
    if(isset($req->post)){
        foreach ($req->post as $k => $v){
            $_POST[$k] = $v;
        }
    }
    try {
        $kernel = $app->make(Kernel::class);
        $response = $kernel->handle(
            $request = Request::capture()
        )->send();
        $kernel->terminate($request, $response);
    }catch(\Exception $e){
        print_r($e->getMessage());
    }
});
Copy after login

The above three pieces of code solve the problems of $_SERVER, $_GET and $_POST respectively. Now if you try again, the parameters can be received, but why is the output printed on the console?

The fourth step is to solve the output problem, put all the output in the frame into the output buffer, and then use Swoole's Response to return.

$http->on(&#39;Request&#39;, function ($req, $res) use($app) {
    $_SERVER = [];
    if(isset($req->server)){
        foreach($req->server as $k => $v){
            $_SERVER[strtoupper($k)] = $v;
        }
    }
    $_GET = [];
    if(isset($req->get)){
        foreach ($req->get as $k => $v){
            $_GET[$k] = $v;
        }
    }
    $_POST = [];
    if(isset($req->post)){
        foreach ($req->post as $k => $v){
            $_POST[$k] = $v;
        }
    }
    //把返回放到一个缓冲区里
    ob_start();
    try {
        $kernel = $app->make(Kernel::class);
        $response = $kernel->handle(
            $request = Request::capture()
        )->send();
        $kernel->terminate($request, $response);
    }catch(\Exception $e){
        print_r($e->getMessage());
    }
    $ob = ob_get_contents();
    ob_end_clean();
    $res->end($ob);
});
Copy after login

The last ob_start () content is also what we have studied before, so we won’t explain it further.

All code

start();
Copy after login

At this point, our simplest framework transformation is completed, let’s try the effect quickly.

Run

php swoole_server.php
Copy after login

Access

http://47.113.xxx.xx:9501/
Copy after login

Try the coroutine effect

First define a route. Or we can directly modify the default route.

Route::get(&#39;/&#39;, function () {
    echo Swoole\Coroutine::getCid(), "<br/>";
    print_r(Swoole\Coroutine::stats());
    Swoole\Coroutine::sleep(10);
    echo "<br/>";
    echo getmypid(), "<br/>";
//    return view(&#39;welcome&#39;);
});
Copy after login

Printed a bunch of things, but they should all be familiar. The first two are the output of coroutine ID and coroutine information, and then we Swoole\Coroutine::sleep () for 10 seconds, and then print Here is the process ID.

Then we open the browser and prepare to access the two tabs together.

// 第一个访问的页面
1
Array
(
    [event_num] => 2
    [signal_listener_num] => 0
    [aio_task_num] => 0
    [aio_worker_num] => 0
    [aio_queue_size] => 0
    [c_stack_size] => 2097152
    [coroutine_num] => 1
    [coroutine_peak_num] => 1
    [coroutine_last_cid] => 1
)
1468
// 第二个访问的页面
2
Array
(
    [event_num] => 2
    [signal_listener_num] => 0
    [aio_task_num] => 0
    [aio_worker_num] => 0
    [aio_queue_size] => 0
    [c_stack_size] => 2097152
    [coroutine_num] => 2
    [coroutine_peak_num] => 2
    [coroutine_last_cid] => 2
)
1468
Copy after login

Do you see it? Each onRequest event actually opens a new coroutine to handle the request, so their coroutine IDs are different. At the same time, the second request will not wait until 20 seconds to return because the first request is blocked. Finally, in the coroutine status, we also see that there are two coroutine_nums displayed in the second request, indicating that there are currently two coroutines processing tasks. In the end, the processes are the same, they all follow the same process.

Try the multi-process effect

By default, the above code is a main process and a Worker process, and then uses the coroutine capability. In fact, this effect can instantly kill the ordinary PHP-FPM effect. But we need to make full use of the performance of multi-core machines, that is to say, we enable multi-processes and use the super-powerful processing mode of multi-processes and multi-coroutines. The simplest way is to directly set the number of process workers for the HTTP service.

$http->set(array(
    &#39;worker_num&#39; => 4,
      // &#39;worker_num&#39; => 1,单进程
));
Copy after login

Now run the server and you can see several more processes. Then we create a new test route

Route::get(&#39;/a&#39;, function () {
    echo Swoole\Coroutine::getCid(), "<br/>";
    print_r(Swoole\Coroutine::stats());
    echo "<br/>";
    echo getmypid(), "<br/>";
});
Copy after login

Now visit the homepage and this /a page again.

// 首页一
1
Array
(
    [event_num] => 2
    [signal_listener_num] => 0
    [aio_task_num] => 0
    [aio_worker_num] => 0
    [aio_queue_size] => 0
    [c_stack_size] => 2097152
    [coroutine_num] => 1
    [coroutine_peak_num] => 1
    [coroutine_last_cid] => 1
)
1562
// 首页二
1
Array
(
    [event_num] => 2
    [signal_listener_num] => 0
    [aio_task_num] => 0
    [aio_worker_num] => 0
    [aio_queue_size] => 0
    [c_stack_size] => 2097152
    [coroutine_num] => 1
    [coroutine_peak_num] => 1
    [coroutine_last_cid] => 1
)
1563
// /a 页面
1
Array
(
    [event_num] => 2
    [signal_listener_num] => 0
    [aio_task_num] => 0
    [aio_worker_num] => 0
    [aio_queue_size] => 0
    [c_stack_size] => 2097152
    [coroutine_num] => 1
    [coroutine_peak_num] => 1
    [coroutine_last_cid] => 1
)
1564
Copy after login

I found no, and their process IDs are all different. If there is no blocking, the process will be switched first. If all processes are blocked, the coroutine will be created in a loop for in-process processing.

The above is the detailed content of Try how to change Laravel to Swoole version. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:learnku.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!