GithubHelp home page GithubHelp logo

bingcool / swoolefy Goto Github PK

View Code? Open in Web Editor NEW
514.0 28.0 80.0 8.08 MB

swoolefy是一个基于swoole实现的协程级、轻量级、高性能、开放性的API应用服务框架

License: MIT License

PHP 99.74% Shell 0.26%
swoole swoolefy php ioc mvc

swoolefy's Introduction

swoolefy

  ______                                _           _ _ _ _
 /  ____|                              | |         |  _ _ _|  _   _
|  (__     __      __   ___     ___    | |   ___   | |       | | | |
 \___  \   \ \ /\ / /  / _ \   / _ \   | |  / _ \  | |_ _ _  | | | |
 ____)  |   \ V  V /  | (_) | | (_) |  | | | ___/  |  _ _ _| | |_| |
|_____ /     \_/\_/    \___/   \___/   |_|  \___|  | |        \__, |
                                                   |_|           | |
                                                              __ / |
                                                             |_ _ /

swoolefy是一个基于swoole实现的轻量级高性能的常驻内存型的协程级应用服务框架, 高度支持httpApi,websocket,udp服务器,以及基于tcp实现可扩展的rpc服务,worker多进程消费模型
同时支持composer包方式安装部署项目。基于实用主义设计出发,swoolefy抽象Event事件处理类, 实现与底层的回调的解耦,支持协程单例调度,同步|异步调用,全局事件注册,心跳检查,异步任务,多进程(池),连接池等, 内置log、session、mysql、pgsql、redis、mongodb、kafka、amqp等常用组件等.

建议版本

swoolefy-5.0+ 版本:
目前主分支,最低要求php8.0+,swoole5.0+(或者swoole-cli-v5.0+), 或者也可以使用swoole-cli-v4.8+, 因为其内置php8.1+

swoolefy-4.8-lts 版本:
长期维护分支,最低要求php >= php7.3 && php < php8.0, 推荐直接swoole-v4.8+,需要通过源码编译安装swoole

选择哪个版本?
1、如果确定项目是使用php8+的,那么直接选择 swoole-v5.0+, 以上源码来编译安装或者直接使用swoole-cli-v5.0,然后选择 bingcool/swoolefy:~5.0.14 作为项目分支

2、如果确定项目是使用 php7.3 ~ php7.4 的,那么选择 swoole-v4.8+ 版本来进行编译安装(不能直接使用 swoole-cli-v4.8+ 了, 因为其内置的是php8.1,与你的项目的php7不符合) 所有只能通过编译swoole源码的方式来生成swoole扩展,然后选择 bingcool/swoolefy:^4.8.14 作为项目分支

实现的功能特性

基础特性

  • 支持架手脚一键创建项目
  • 支持分组路由, 路由middleware, 前置路由组件, 后置路由组件,多模块应用
  • 支持自定义注册不同根命名空间,快速多项目部署
  • 支持httpServer,实用轻量Api接口开发
  • 支持多协议websocketServer、udpServer、mqttServer
  • 支持基于tcp实现的rpc服务,开放式的系统接口,可自定义协议数据格式,并提供rpc-client协程组件
  • 支持DI容器,组件IOC、配置化,Channel公共组件池
  • 支持协程单例注册,协程上下文变量寄存
  • 支持mysql、postgreSql、redis协程组件
  • 支持全局logger组件、trace链路追踪
  • 支持mysql协程连接池
  • 支持redis协程池
  • 支持curl协程池
  • 支持protobuf buffer的数据接口结构验证,压缩传输等
  • 支持异步务管理TaskManager
  • 定时器管理TickManager
  • 内存表管理TableManager
  • 支持自定义进程管理ProcessManager,进程池管理PoolsManger
  • 支持底层异常错误的所有日志捕捉,支持全局日志,包括debug、info、notice、warning、error等级
  • 支持自定义进程的redis,rabbitmq,kafka的订阅发布,消息队列等
  • 支持热更新reload worker 监控以及更新
  • 支持定时的系统信息采集,并以订阅发布,udp等方式收集至存贮端
  • 支持命令行形式高度封装启动|停止控制的脚本,简单命令即可管理整个框架

高级特性

  • 支持crontab的local调用和fork独立进程的计划任务

    支持方式 说明
    local 自定义进程内定时执行代码
    fork 自定义进程定时拉起一个新的进程,由新的进程去支持任务,可异步
    url 自定义进程定时发起远程url请求,可设置callback回调处理结果
  • 支持worker下后台daemon模式的多进程协程消费模型,包括进程自动拉起,进程数动态调整,进程健康状态监控

  • 支持console终端脚本模式,跑完脚本自动退出,可用于修复数据、数据迁移等临时脚本功能

  • 支持分布式服务注册(zk,etcd)

适配协程环境组件

组件名称 安装 说明
predis composer require predis/predis:~1.1.7 predis组件、或者Phpredis扩展
mongodb composer require mongodb/mongodb:~1.3 mongodb组件,需要使用mongodb必须安装此组件
rpc-client composer require bingcool/rpc-client:dev-master swoolefy的rpc客户端组件,当与rpc服务端通信时,需要安装此组件,支持在php-fpm中使用
cron-expression composer require dragonmantank/cron-expression:~3.3.0 crontab计划任务组件,类似Linux的crobtab
redis lock composer require malkusch/lock Redis锁组件
amqp composer require php-amqplib/php-amqplib:~3.5.0 amqp php原生实现amqp协议客户端
ffmpeg composer require php-ffmpeg/php-ffmpeg:~1.1.0 php proc-open 调用ffmpeg处理音视频
validate composer require vlucas/valitron validate数据校验组件
guzzlehttp composer require guzzlehttp/guzzle guzzlehttp 组件
oauth 2.0 composer require league/oauth2-server oauth 2.0 授权认证组件
bingcool/library composer require bingcool/library library组件库

bingcool/library 是swoolefy require 内置库,专为swoole协程实现的组件库

实现了包括:

  • Db ORM Model 组件(支持mysql、 postSql、 sqlite、 Oracle)
  • DB Query Builder 链式操作查询组件
  • Kafka Producer Consumer组件
  • Rabbitmq Queue组件
  • Rabbitmq Delay Queue 死信延迟队列组件
  • Redis Cache组件
  • Redis Queue队列组件
  • Redis Delay Queue延迟队列组件
  • RedisLock锁组件
  • RateLimit限流组件
  • Redis Public Subscribe组件
  • Db、Redis、 Curl协程连接池组件
  • UUid 分布式自增id组件
  • Curl基础组件
  • Jwt 组件
  • Validate组件

github: https://github.com/bingcool/library

一、安装

1、先配置环境变量

// 独立物理机或者云主机配置系统环境变量
vi /etc/profile
在/etc/profile末尾添加一行标识环境,下面是支持的4个环境,框架将通过这个环境变量区分环境,加载不同的配置
export SWOOLEFY_CLI_ENV='dev'  // 开发环境
export SWOOLEFY_CLI_ENV='test' // 测试环境
export SWOOLEFY_CLI_ENV='gra'  // 灰度环境
export SWOOLEFY_CLI_ENV='prd'  // 生产环境
// 最后是配置生效
source /etc/profile

// 如果是通过dockerfile 创建容器的, 可以根据不同环境生成的内置环境变量不同镜像,每个不同的环境镜像可以用在不同环境,代码将通过这个环境变量区分环境,加载不同的配置
ENV SWOOLEFY_CLI_ENV dev

2、创建项目

// 下载代码到到你的自定义目录,这里定义为myproject
composer create-project bingcool/swoolefy:~5.0 myproject

二、添加项目入口启动文件cli.php,并定义你的项目目录,命名为App

<?php
// 在myproject目录下添加cli.php, 这个是启动项目的入口文件
include './vendor/autoload.php';

define('IS_DAEMON_SERVICE', 0);
define('IS_CRON_SERVICE', 0);
define('IS_CLI_SCRIPT', 0);
// 应用父目录
defined('ROOT_PATH') or define('ROOT_PATH', __DIR__);
// 启动目录
defined('START_DIR_ROOT') or define('START_DIR_ROOT', __DIR__);

date_default_timezone_set('Asia/Shanghai');

define('APP_NAMES', [
     // 你的项目命名为App,对应协议为http协议服务器,支持多个项目的,只需要在这里添加好项目名称与对应的协议即可
    'App' => 'http', 
    'Test' => 'http
]);

// 启动前处理,比如加载.env
$beforeFunc = function () {
    
};

include './swoolefy';

三、执行创建你定义的App项目

// 你定义的项目目录是App, 在myproject目录下执行下面命令行

swoole-cli cli.php create App 
或者    
php cli.php create App   

// 执行完上面命令行后,将会自动生成App项目目录以及内部子目录
myproject
|—— App  // 应用项目目录
|     |── Config       // 应用配置
|     |   |__ component // 协程单例组件
|     |      |—— database.php //数据库相关组件
|     |      |—— log.php     // 日志相关组件
|     |      |—— cache.php   // 缓存组件,可以继续添加其他组件,命名自由 
|     │   ├── dc.php   //环境配置项
|     │   └── constants.php
|     |   |—— config.php    // 应用层配置
|     |
|     ├── Controller
|     │   └── IndexController.php // 控制器层
|     ├── Model
|     │   └── ClientModel.php
|     ├── Module        // 模块层
|     ├── Protocol      // 协议配置
|     │   ├── conf.php  // 全局配置
|     │
|     ├── Router
|     │   └── Api.php  // 路由文件,不同模块定义不同文件即可
|     |—— Storage
|     |   |—— Logs  // 日志文件目录
|     |   |—— Sql   // sql日志目录
|     |__ .env     // 自动生成环境变量文件
|     │—— autoloader.php // 自定义项目自动加载
|     |—— Event.php      // 事件实现类
|     |—— HttpServer.php // http server
|    
|——— src //源码
|——— cli.php // http应用启动入口文件
|——— cron.php // 定时worker任务的多进程启动入口文件
|——— daemon.php // 守护进程worker的多进程启动入口文件
|——— script.php // 脚本启动入口文件

四、启动应用项目

// 终端启动 ctl+c 停止进程
php cli.php start App
或者    
swoole-cli cli.php start App

// 守护进程方式启动,添加-D参数控制
php cli.php start App --daemon=1
或者  
swooole-cli cli.php start App --daemon=1

// 停止进程
php cli.php stop App
或者   
swooole-cli cli.php stop App --force=1

// 查看进程状态
swooole-cli cli.php status App

五、访问

默认端口是9502,可以通过 http://localhost:9502 访问默认控制器

<?php
namespace App\Controller;

use Swoolefy\Core\Application;
use Swoolefy\Core\Controller\BController;

// 默认生成的IndexController
class IndexController extends BController {

    public function index() {
        Application::getApp()->response->write('<h1>Hello, Welcome to Swoolefy Framework! <h1>');
    }
}

至此一个最简单的http的服务就创建完成了,更多例子请参考项目下Test的demo

定义组件

应用层配置文件: Config/config.php

<?php

return [

    // db|redis连接池
    'enable_component_pools' => [
        // 取components的`DB`组件名称相对应
        'db' => [
            'max_pool_num' => 5, // db实例数
            'max_push_timeout' => 2, // db实例进入channel池最长等待时间,单位s
            'max_pop_timeout' => 1, // db实例出channel池最长等待时间,单位s.在规定时间内获取不到db对象,将降级为实时创建db实例
            'max_life_timeout' => 10, // db实例的有效期,单位s.过期后将被掉弃,重新创建新DB实例
            'enable_tick_clear_pool' => 0 // 是否每分钟定时清空pool,防止长时间一直占用链接,max_pool_num设置很大的时候需要设置,否则不需要设置
        ],
    
        // 取components的`redis`组件名称相对应
        'redis' => [
            'max_pool_num' => 5,
            'max_push_timeout' => 2,
            'max_pop_timeout' => 1,
            'max_life_timeout' => 10,
            'enable_tick_clear_pool' => 0 // 是否每分钟定时清空pool,防止长时间一直占用链接,max_pool_num设置很大的时候需要设置,否则不需要设置
        ]
    ],
    
     // default_db
    'default_db' => 'db',

    // 加载组件配置
    'components' => \Swoolefy\Core\SystemEnv::loadComponent()
    
    // 其他配置
    ......
]

组件Component.php:


$dc = \Swoolefy\Core\SystemEnv::loadDcEnv();

return [
    // 用户行为记录的日志
    'log' => function($name) {
        $logger = new Log($name);
        $logger->setChannel('application');
        if(SystemEnv::isDaemonService()) {
            $logFilePath = LOG_PATH.'/daemon/info.log';
        }else if (SystemEnv::isScriptService()) {
            $logFilePath = LOG_PATH.'/script/info.log';
        }else if (SystemEnv::isCronService()) {
            $logFilePath = LOG_PATH.'/cron/info.log';
        } else {
            $logFilePath = LOG_PATH.'/cli/info.log';
        }
        $logger->setLogFilePath($logFilePath);
        return $logger;
    },

    // 用户行为记录错误日志
    'error_log' => function($name) {
        $logger = new Log($name);
        $logger->setChannel('application');
        if(SystemEnv::isDaemonService()) {
            $logFilePath = LOG_PATH.'/daemon/error.log';
        }else if (SystemEnv::isScriptService()) {
            $logFilePath = LOG_PATH.'/script/error.log';
        }else if (SystemEnv::isCronService()) {
            $logFilePath = LOG_PATH.'/cron/error.log';
        } else {
            $logFilePath = LOG_PATH.'/cli/error.log';
        }
        $logger->setLogFilePath($logFilePath);
        return $logger;
    },

    // 系统捕捉抛出异常错误日志
    'system_error_log' => function($name) {
        $logger = new \Swoolefy\Util\Log($name);
        $logger->setChannel('application');
        if(SystemEnv::isDaemonService()) {
            $logFilePath = LOG_PATH.'/daemon/system_error.log';
        }else if (SystemEnv::isScriptService()) {
            $logFilePath = LOG_PATH.'/script/system_error.log';
        }else if (SystemEnv::isCronService()) {
            $logFilePath = LOG_PATH.'/cron/system_error.log';
        } else {
            $logFilePath = LOG_PATH.'/cli/system_error.log';
        }
        $logger->setLogFilePath($logFilePath);
        return $logger;
    }
    
    // Redis Cache
    'redis' => function() use($dc) {
        $redis = new \Common\Library\Redis\Redis();
        $redis->connect($dc['redis']['host'], $dc['redis']['port']);
        return $redis;
    },
    
    // Predis Cache
    'predis' => function() use($dc) {
        $predis = new \Common\Library\Redis\predis([
            'scheme' => $dc['predis']['scheme'],
            'host'   => $dc['predis']['host'],
            'port'   => $dc['predis']['port'],
        ]);
        return $predis;
    }
    

使用组件

use Swoolefy\Core\Application;

class TestController extends BController {
    /**
    * 控制器
    */
    public function test() {
        // 获取组件,组件就是配置回调中定义的组件
        $redis = Application::getApp()->redis;
        //或者通过get指明组件名获取(推荐)
        // $redis = Application::getApp()->get('redis');

        // swoole hook 特性,这个过程会发生协程调度
        $redis->set('name', swoolefy);

        // predis组件
        $predis = Application::getApp()->predis;
        //或者通过get指明组件名获取(推荐)
        // $predis = Application::getApp()->get('predis');
        
        // 这个过程会发生协程调度
        $predis->set('predis','this is a predis instance');
        $predis->get('predis');
        
        // PDO的mysql实例,这个过程会发生协程调度
        $db = Application::getApp()->db;
        // 或者
        // $mysql = Application::getApp()->get('db');
        // 添加一条数据
        $sql = "INSERT INTO `user` (`username` ,`sex`) VALUES (:username, :sex)"; 
        $numRows = $db->createCommand($sql)->insert([
            ':username'=>'bingcool-test',
            ':sex' => 1
        ]);
        var_dump($numRows)
        
        // DB Query查询
         $db = Application::getApp()->db;
         $db->newQuery()->table('user')->where([
            'user_id' => 10000
         ])->select()
         
         // DB 插入单条数据
         $data = [
            'username'=>'bingcool-test',
            'sex' => 1
         ]
         $db = Application::getApp()->db;
         $db->newQuery()->table('user')->insert($data);
         
         // DB 插入多条数据
         $data = 
         [
            [
                'username'=>'bingcool-test1111',
                'sex' => 1
            ],
            [
                'username'=>'bingcool-test2222',
                'sex' => 1
            ]
         ]
         $db = Application::getApp()->db;
         $db->newQuery()->table('user')->insertAll($data);
         
         
        // 查询
        $result = $db->createCommand('select * from user where id>:id')->queryOne([':id'=>100]);
        var_dump($result);    

        // pg实例    
        $pg = Application::getApp()->get('pg');   
        // 添加一条数据   
        $sql = "INSERT INTO `user` (username ,sex) VALUES (:username, :sex)"; 
        $pg->createCommand($sql)->insert([
            ':username'=>'bingcool-test',
            ':sex' => 1
        ]);
    }
}

默认协议层全局配置文件 Protocol/conf.php

开发者可以根据实际使用适当调整配置项

$dc = \Swoolefy\Core\SystemEnv::loadDcEnv();

<?php

return [
    // 应用层配置
    'app_conf'                 => \Swoolefy\Core\SystemEnv::loadAppConf(), // 应用层配置
    'application_index'        => '',
    'event_handler'            => \Test\Event::class,
    'exception_handler'        => \Test\Exception\ExceptionHandle::class,
    'response_formatter'       => \Swoolefy\Core\ResponseFormatter::class,
    'master_process_name'      => 'php-swoolefy-http-master',
    'manager_process_name'     => 'php-swoolefy-http-manager',
    'worker_process_name'      => 'php-swoolefy-http-worker',
    'www_user'                 => '',
    'host'                     => '0.0.0.0',
    'port'                     => '9501',
    'time_zone'                => 'PRC',
    'swoole_process_mode'      => SWOOLE_PROCESS,
    'include_files'            => [],
    'runtime_enable_coroutine' => true,

    // swoole setting
	'setting' => [
        'admin_server'           => '0.0.0.0:9503',
        'reactor_num'            => 1,
        'worker_num'             => 4,
        'max_request'            => 10000,
        'task_worker_num'        => 2,
        'task_tmpdir'            => '/dev/shm',
        'daemonize'              => 0,
        'dispatch_mode'          => 3,
        'reload_async'           => true,
        'enable_coroutine'       => 1,
        'task_enable_coroutine'  => 1,
        // 压缩
        'http_compression'       => true,
        // $level 压缩等级,范围是 1-9,等级越高压缩后的尺寸越小,但 CPU 消耗更多。默认为 1, 最高为 9
        'http_compression_level' => 1,
        'log_file'               => \Swoolefy\Core\SystemEnv::loadLogFile('/tmp/' . APP_NAME . '/swoole_log.txt'),
        'pid_file'               => \Swoolefy\Core\SystemEnv::loadPidFile('/data/' . APP_NAME . '/log/server.pid'),
	],

    'coroutine_setting' => [
        'max_coroutine' => 50000
    ],

    // 是否内存化线上实时任务
    'enable_table_tick_task' => true,

    // 内存表定义
    'table' => [
        'table_process' => [
             // 内存表建立的行数,取决于建立的process进程数,最小值64
             'size' => 64,
              // 定义字段
              'fields'=> [
                     ['pid','int', 10],
                     ['process_name','string', 56],
                  ]
               ]
     ],

    // 依赖于EnableSysCollector = true,否则设置没有意义,不生效
    'enable_pv_collector'  => false,
    'enable_sys_collector' => true,
    'sys_collector_conf' => [
        'type'           => SWOOLEFY_SYS_COLLECTOR_UDP,
        'host'           => '127.0.0.1',
        'port'           => 9504,
        'from_service'   => 'http-app',
        'target_service' => 'collectorService/system',
        'event'          => 'collect',
        'tick_time'      => 2,
        'callback'       => function () {
            $sysCollector = new \Swoolefy\Core\SysCollector\SysCollector();
            return $sysCollector->test();
        }
    ],

    // 热更新
    'reload_conf'=> [
        'enable_reload'     => false, // 是否启用热文件更新功能       
        'after_seconds'     => 3, // 检测到只要有文件更新,3s内不在检测,等待重启既可     
        'monitor_path'      => APP_PATH, // 开发者自己定义目录
        'reload_file_types' => ['.php', '.html', '.js'],
        'ignore_dirs'       => [],
        'callback'          => function () {}
    ]
];

路由文件(类似laravel路由)

Router/api.php

<?php

use Swoolefy\Http\Route;
use Swoolefy\Http\RequestInput;

// 直接路由-不分组
Route::get('/index/index', [
    'beforeHandle' => function(RequestInput $requestInput) {
        Context::set('name', 'bingcool');
        $name = $requestInput->getPostParams('name');
    },

    // 这里需要替换长对应的控制器命名空间
    'dispatch_route' => [\Test\Controller\IndexController::class, 'index'],

    'afterHandle' => function(RequestInput $requestInput) {

    },
    'afterHandle1' => function(RequestInput $requestInput) {

    },
]);

// 分组路由
Route::group([
    // 路由前缀
    'prefix' => 'api',
    // 路由中间件,多个按顺序执行
    'middleware' => [
        \Test\Middleware\Route\ValidLoginMiddleware::class,
    ]
], function () {

    Route::get('/', [
        // 前置路由,闭包函数形式
        'beforeHandle' => function(RequestInput $requestInput) {
            var_dump('beforeHandle');
        },

        // 前置路由,中间件类形式(推荐)
        'beforeHandle2' => \Test\Middleware\Route\ValidLoginMiddleware::class,

        // 前置路由,中间件数组类形式(推荐)
        'beforeHandle3' => [
            \Test\Middleware\Route\ValidLoginMiddleware::class,
            \Test\Middleware\Route\ValidLoginMiddleware::class,
        ],

        // 控制器action
        'dispatch_route' => [\Test\Controller\IndexController::class, 'index'],

        // 后置路由
        'afterHandle1' => function(RequestInput $requestInput) {
            var_dump('afterHandle');
        },

        // 前置路由,中间件类形式(推荐)
        'afterHandle2' => \Test\Middleware\Route\ValidLoginMiddleware::class,

        // 前置路由,中间件数组类形式(推荐)
        'afterHandle3' => [
            \Test\Middleware\Route\ValidLoginMiddleware::class,
            \Test\Middleware\Route\ValidLoginMiddleware::class
        ],
    ]);
});

数据库操作


$db = Application::getApp()->get('db');
// 插入单条数据
$db->newQuery()->table('tbl_users')->insert([
            'user_name' => '李四-'.rand(1,9999),
            'sex' => 0,
            'birthday' => '1991-07-08',
            'phone' => 12345678
    ]);

// 批量插入
$db->newQuery()->table('tbl_users')->insertAll([
            [
                'user_name' => '李四-'.rand(1,9999),
                'sex' => 0,
                'birthday' => '1991-07-08',
                'phone' => 12345678
            ],
            [
                'user_name' => '李四-'.rand(1,9999),
                'sex' => 0,
                'birthday' => '1991-07-08',
                'phone' => 12345678
            ]
    ]);


// 查询列表
$db->newQuery()->table('tbl_users')->where('id','>', 1)->field(['id', 'user_name'])->limit(0,10)->select();

// 查询单条
$db->newQuery()->table('tbl_users')->where(['id', '=', 100])->field(['id', 'user_name'])->find();

.....还有很多其他链式操作

协程单例,协程并发

// 协程单例使用goApp直接调用创建, 每个协程的DB,redis,kafka,mq的socket对象相互隔离,互不影响,代码通用

goApp(function() {
    $db = Application::getApp()->get('db');
    // 查询列表
    $db->newQuery()->table('tbl_users')->where('id','>', 1)->field(['id', 'user_name'])->limit(0,10)->select();
    // redis
    $redis = Application::getApp()->get('redis');
    $redis->set('name','bingcool')
})



// 协程并发-协程并发迭代数组处理数据(针对数据量大,无需关注返回数据)

$list = [
    [
        'name' => ’name-1'
    ],
    [
        'name' =>  ’name-2'
    ],
    [
        'name' =>  ’name-3'
    ],
    [
        'name' =>  ’name-4'
    ],
    [
        'name' =>  ’name-5'
    ]
];

// 并发2个协程-循环迭代数组-回调函数处理
Parallel::run(2, $list, function ($item) {
    var_dump($item['name']);
}, 0.01);



// 协程并发-协程并发处理并等待结果(针对并发量少,并且需要返回数据的)

$parallel = new Parallel();
$parallel->add(function () {
    sleep(2);
    return "阿里巴巴";
},'ali');

$parallel->add(function () {
    sleep(2);
    return "腾讯";
},'tengxu');

$parallel->add(function () {
    sleep(2);
    return "百度";
},'baidu');

$parallel->add(function () {
    sleep(5);
    return "字节跳动";
},'zijie');

// 并发等待返回数据
$result = $parallel->runWait(10);
array(4) {
  ["ali"]=>
  string(12) "阿里巴巴"
  ["tengxu"]=>
  string(6) "腾讯"
  ["baidu"]=>
  string(6) "百度"
  ["zijie"]=>
  string(12) "字节跳动"
}


License

MIT
Copyright (c) 2017-2024 zengbing huang

swoolefy's People

Contributors

bingcool avatar ohuolo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

swoolefy's Issues

按照文档一步步操作就 报错了

文档 :
https://www.kancloud.cn/bingcoolhuang/php-swoole-swoolefy/587504

php 7.2.18
swoole 4.4.12

composer update 安装完成之后 按照文档创建

报错:
[root@none swoolefy]# php swoolefy create App
#! /usr/bin/php
PHP Warning: require(/data/www/swoolefy/vendor/composer/../bingcool/swoolefy/score/core/Func/function.php): failed to open stream: No such file or directory in /data/www/swoolefy/vendor/composer/autoload_real.php on line 66

Warning: require(/data/www/swoolefy/vendor/composer/../bingcool/swoolefy/score/core/Func/function.php): failed to open stream: No such file or directory in /data/www/swoolefy/vendor/composer/autoload_real.php on line 66
PHP Fatal error: require(): Failed opening required '/data/www/swoolefy/vendor/composer/../bingcool/swoolefy/score/core/Func/function.php' (include_path='.:/data/server/php/lib/php') in /data/www/swoolefy/vendor/composer/autoload_real.php on line 66

Fatal error: require(): Failed opening required '/data/www/swoolefy/vendor/composer/../bingcool/swoolefy/score/core/Func/function.php' (include_path='.:/data/server/php/lib/php') in /data/www/swoolefy/vendor/composer/autoload_real.php on line 66

开源不易,且行且珍惜。感谢不断奋斗在开源路上的人。

其实一直想吐槽 php 几点:

  1. 拓展安装麻烦:我们之前开源了一套 php 框架,结果很多人死在拓展安装上,要么 phpize 要么 pecl 。。。windows 系统的也各种麻烦。
    而node 版本的, npm install 都好了。
  2. 很多 phper —— 培训班水平,composer 都不会用。
  3. swoole 生态不健全,对于企业来说,成本太高。

这个项目还是让我看到了 swoole 的希望~

可惜我们最后还是从 php 转向了 node ~

初始化兼容问题

在不使用docker的情况下,mac系统不能兼容swoolefy的初始化安装(php swoolefy start App -dev);
会报一些错,比如:mac系统的进程是不能重命名的,所以swoole_set_process_name的就需要判断一下系统才能执行,不然会报错;
又比如:不能在/dev/目录下创建新目录(我直接sudo mkdir也不可以创建),执行开始命令时也会报错;
docker没去尝试过,不知道以后有时间能不能尝试做下兼容(嘿嘿,刚觉swoolefy挺适合swoole初学者的);
另外请教下,我是swoole新手,网上各类文章和例子都看了不少,也在一些php框架尝试使用了基础功能,但是总觉得缺少一些什么(感觉是在实际项目中要怎么嵌入swoole的使用,具体是什么挺模糊的,不知道兄弟们能明白我的这种感受吗?哈哈哈)
感谢指教!!!

有视频或者QQ群吗

有视频或者QQ群吗?看云的手册和,这里的不一样啊,应该看那个手册啊。

Centos 下大小写问题 bingcool/swoolefy-zipkin/src/ZipkinTracer.php

[linjinyu@localhost project]$ php swoolefy start http PHP Fatal error: Class 'whitemerry\phpkin\tracer' not found in /mnt1t/__source_code__/__swoole__/project/vendor/bingcool/swoolefy-zipkin/src/ZipkinTracer.php on line 7

`<?php
namespace zipkin;

use whitemerry\phpkin\tracer;
use whitemerry\phpkin\TracerInfo;

class ZipkinTracer extends tracer {

/**
 * Save trace
 */
public function trace($is_async = false)
{
    if (!TracerInfo::isSampled()) {
        return;
    }

    $unsetParentId = true;
    if ($this->profile === static::BACKEND && !$this->unsetParentIdForBackend) {
        $unsetParentId = false;
    }

    $this->addTraceSpan($unsetParentId);

    if($is_async) {
    	$this->logger->asyncTrace($this->spans);
    }else {
    	$this->logger->trace($this->spans);
    }
}

}`

use whitemerry\phpkin\tracer;
2
use whitemerry\phpkin\Tracer;

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.