sidorkinalex/multiphp 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

sidorkinalex/multiphp

Composer 安装命令:

composer require sidorkinalex/multiphp

包简介

multithreading in php by means of php-cli and Redis

README 文档

README

Latest Stable Version Total Downloads Latest Unstable Version License

this package is designed to quickly run background php-cli scripts with the ability to wait for the result of their execution in the main thread.

Inslall and including in project

Install

You can install the package via the compositor by running the command:

composer require sidorkinalex/multiphp

Or you can download the current version from github and connect 3 files to the core of your project

require_once 'src/Guidv4.php';
require_once 'src/Thread.php';
require_once 'src/ThreadInterface.php';

Include

To connect in your project, you must create a class that inherits from the Thread class and override the following variables:

namespace App;

use SidorkinAlex\Multiphp\Thread;

class CustomThread extends Thread
{
    public static $php_worker_path = "/var/www/html/exec.php"; //path to the script that starts the thread(with the initialized core of your project)
    public static $redis_host = "127.0.0.1";// can be a host, or the path to a unix domain socket from Redis
    public static $redis_port = 6379; // Redis port
    public static $redis_timeout = 0.0; // timeout from Redis value in seconds (optional, default is 0.0 meaning unlimited)
    public static $redis_reserved = null; //should be null if $retry_interval is specified from Redis
    public static $redis_retry_interval = 0; //retry interval in milliseconds from Redis.
    public static $cache_timeout = "1200"; // seconds lifetime of stream data in the Redis database

}

you also need to create an entry point to the application to run through the console(php-cli) in the current example, this is /var/www/html/exec.php

in the file for execution from the console, you need to put the code to start the execution of the stream, as the parameter will pass the key to get the stream data.

include 'vendor/autoload.php'; 
$key=$argv[1]; //
SidorkinAlex\Multiphp\Thread::shell_start($key);

include 'vendor/autoload.php'; If the package is installed via the composer or if downloaded from github, connect the 3 files listed above.

$argv[1] a unique thread key that is generated when the thread is started and passed as a parameter to the php-cli script. Depending on the framework, this variable may change.

SidorkinAlex\Multiphp\Thread::shell_start($key); calling a static method that starts the execution of the function passed to the thread.

Examples install from Symfony

https://github.com/SidorkinAlex/symfony-website-skeleton-multithreading_php/pull/1/files

Example code

Example 1 (parallel execution)


  $paramsFromThread = 3;
        $test = new CThread($paramsFromThread,function ($n){
            for ($i = 0; $i<$n; $i++){
                $pid=getmypid();
                file_put_contents('test1.log', $i." my pid is {$pid} \n", FILE_APPEND);
                sleep(3);
            }
            return 'test1';
        });
        $test->start();

        $test2 = new CThread($paramsFromThread,function ($n){
            for ($i = 0; $i<$n; $i++){
                $pid=getmypid();
                file_put_contents('test2.log', $i." my pid is {$pid} \n", FILE_APPEND);
                sleep(3);
            }
            return 'test2';
        });
        $test2->start();
        $result1 = $test->getCyclicalResult();
        $result2 = $test2->getCyclicalResult();

In the example, we see the creation of two threads, which are passed the function of iterating through arrays with a son at the end of each step for 3 seconds. if we would execute them sequentially, the script execution time would be 18 seconds, when running them in parallel threads, the script execution time is 9 seconds.

Example 2 (background thread)

public function testpars(Request $request): Response
    {
        $userIds=$request->request->get('users');
        if(!is_array($userIds)){
            throw new \Exception('post[users] is not array');
        }
        $EmailSendlerThread = new CThread($users,function ($users){
            foreach ($users as $user_id){

                $transport = \Symfony\Component\Mailer\Transport::fromDsn('smtp://localhost');
                $mailer = new \Symfony\Component\Mailer\Mailer($transport);

                $userObj = new \App\Service\User();
                $userObj->retrieve($user_id);
                if(!empty($userObj->email)){
                    $email = (new Email())
                        ->from(\App\Service\Email::getSelfEmail())
                        ->to($userObj->email)
                        //->cc('cc@example.com')
                        //->bcc('bcc@example.com')
                        //->replyTo('fabien@example.com')
                        //->priority(Email::PRIORITY_HIGH)
                        ->subject(\App\Service\Email::get_first_email_subject())
                        ->text(\App\Service\Email::get_first_email_text())
                        ->html(\App\Service\Email::get_first_email_html());

                    $mailer->send($email);
                }
            }
        });
        $EmailSendlerThread->start();

        return new JsonResponse(['status' =>"ok"]);
    }

Example 2 shows the code that implements the start of sending emails. the execution of the testpars method is completed by running the $EmailSendlerThread thread and does not wait for its execution.

Therefore, the response to such a request will be very fast, the main thread will not wait for the $EmailSendlerThread thread to finish, but will simply return {"status" : "ok"} to the initiator.

Многопоточность на PHP с помошбю Redis + php-cli

Этот пакет предназначен для быстрого запуска фоновых php-cli скриптов с возможностью ожидания результата их выполнения в основном потоке.

Установка и включение в проект

Установить

Вы можете установить пакет через компоновщик, выполнив команду:

composer require sidorkinalex/multiphp

Или вы можете загрузить текущую версию с github и подключить 3 файла к ядру вашего проекта

require_once 'src/Guidv4.php';
require_once 'src/Thread.php';
require_once 'src/ThreadInterface.php';

Подключение к проекту

Чтобы включить его в свой проект, необходимо создать класс, который наследуется от класса Thread, и переопределить следующие переменные:

namespace App;

use SidorkinAlex\Multiphp\Thread;

class CustomThread extends Thread
{
    public static $php_worker_path = "/var/www/html/exec.php"; //path to the script that starts the thread(with the initialized core of your project)
    public static $redis_host = "127.0.0.1";// can be a host, or the path to a unix domain socket from Redis
    public static $redis_port = 6379; // Redis port
    public static $redis_timeout = 0.0; // timeout from Redis value in seconds (optional, default is 0.0 meaning unlimited)
    public static $redis_reserved = null; //should be null if $retry_interval is specified from Redis
    public static $redis_retry_interval = 0; //retry interval in milliseconds from Redis.
    public static $cache_timeout = "1200"; // seconds lifetime of stream data in the Redis database

}

вам также необходимо создать точку входа в приложение для запуска через консоль(php-cli) в текущем примере это /var/www/html/exec.php

в файл для выполнения из консоли нужно поместить код для запуска выполнения потока, так как параметр передаст ключ для получения данных потока.

include 'vendor/autoload.php'; 
$key=$argv[1]; //
SidorkinAlex\Multiphp\Thread::shell_start($key);

include 'vendor/autoload.php'; Если пакет установлен через composer. Eсли загружен с github, подключите 3 файла, перечисленные выше.

$argv[1] уникальный ключ потока, который генерируется при запуске потока и передается в качестве параметра скрипту php-cli. В зависимости от структуры эта переменная может изменяться.

SidorkinAlex\Multi php\Thread::she'will_start($key); вызов статического метода, который запускает выполнение функции, переданной потоку.

Примеры установки для Symfony

https://github.com/SidorkinAlex/symfony-website-skeleton-multithreading_php/pull/1/files

Примеры кода

Пример 1 (паралельное выполнение)


  $paramsFromThread = 3;
        $test = new CThread($paramsFromThread,function ($n){
            for ($i = 0; $i<$n; $i++){
                $pid=getmypid();
                file_put_contents('test1.log', $i." my pid is {$pid} \n", FILE_APPEND);
                sleep(3);
            }
            return 'test1';
        });
        $test->start();

        $test2 = new CThread($paramsFromThread,function ($n){
            for ($i = 0; $i<$n; $i++){
                $pid=getmypid();
                file_put_contents('test2.log', $i." my pid is {$pid} \n", FILE_APPEND);
                sleep(3);
            }
            return 'test2';
        });
        $test2->start();
        $result1 = $test->getCyclicalResult();
        $result2 = $test2->getCyclicalResult();

В примере мы видим создание двух потоков, в котрые передается вункция перебора массивов с сном вконце каждого шага на 3 секунды. если мы бы выполняли их последовательно, то время выполнения скрипта было бы 18 секунд, при запуске их паралельными потоками время выполнения скрипта составляет 9 секунд.

Пример 2 (фоновый поток)

public function testpars(Request $request): Response
    {
        $userIds=$request->request->get('users');
        if(!is_array($userIds)){
            throw new \Exception('post[users] is not array');
        }
        $EmailSendlerThread = new CThread($users,function ($users){
            foreach ($users as $user_id){

                $transport = \Symfony\Component\Mailer\Transport::fromDsn('smtp://localhost');
                $mailer = new \Symfony\Component\Mailer\Mailer($transport);

                $userObj = new \App\Service\User();
                $userObj->retrieve($user_id);
                if(!empty($userObj->email)){
                    $email = (new Email())
                        ->from(\App\Service\Email::getSelfEmail())
                        ->to($userObj->email)
                        //->cc('cc@example.com')
                        //->bcc('bcc@example.com')
                        //->replyTo('fabien@example.com')
                        //->priority(Email::PRIORITY_HIGH)
                        ->subject(\App\Service\Email::get_first_email_subject())
                        ->text(\App\Service\Email::get_first_email_text())
                        ->html(\App\Service\Email::get_first_email_html());

                    $mailer->send($email);
                }
            }
        });
        $EmailSendlerThread->start();

        return new JsonResponse(['status' =>"ok"]);
    }

В примере 2 представлен код который реализует запуск отправки писем. выполнение метода testpars завершается запуском потока $EmailSendlerThread и не ждет его выполнения.

Поэтому ответ на подобный запрос будет очень быстрым основной поток не будет ждать завершения работы потока $EmailSendlerThread а просто вернет {"status" : "ok"} инициатору.

sidorkinalex/multiphp 适用场景与选型建议

sidorkinalex/multiphp 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 4.83k 次下载、GitHub Stars 达 9, 最近一次更新时间为 2021 年 05 月 07 日, 在 PHP 生态内属于活跃度较高的组件。

它主要适用于以下技术方向: 「cli」 「php-cli」 「multithreading」 「multithreading php」 等业务场景。在实际项目中,围绕这些方向常见需要落地的问题包括:接口对接、性能调优、并发安全、与既有框架(Laravel / ThinkPHP / Yii / Webman 等)的兼容适配,以及生产环境的日志埋点与稳定性保障。

我们在过去多个企业项目中使用过 sidorkinalex/multiphp 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 sidorkinalex/multiphp 我们能提供哪些服务?
定制开发 / 二次开发

基于 sidorkinalex/multiphp 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 4.83k
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 9
  • 点击次数: 16
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 9
  • Watchers: 1
  • Forks: 1
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2021-05-07