Skip to content
一个基于 swoole 的服务端MVC框架
PHP
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
Src
.gitignore
README.md
composer.json
composer.lock

README.md

MorePHP

一个基于 swoole 的服务端MVC框架

安装

composer require roki/more

特性

  • 常驻进程,支持协程( Context 管理)
  • 简单的依赖注入容器
  • MVC,简单的路由(支持 RESTful 风格)
  • 对象池
  • MySQL ORM
  • 基于对象池+协程 Context 管理器实现协程连接池
  • 使用 laravel blade 模板引擎

框架使用要求

  • swoole4.x
  • PHP7.x
  • 面向对象,尽量避免过多使用全局变量、类静态变量

开发计划

  • Facade
  • Middleware
  • RPC

配置

{projectroot}/Config/app.conf.php

```php
<?php
return array(

    // 服务配置
    'swooleServer' => [
        // 服务类型
        'type' => \More\Src\Core\Swoole\ServerManager::TYPE_WEB_SOCKET,
        'port' => 9501,
        'host' => '0.0.0.0',
        'mode' => SWOOLE_PROCESS,
        'sockType' => SWOOLE_TCP,
        'setting' => [
            //'task_worker_num' => 8, //异步任务进程
            //'task_max_request' => 10,
            'max_request' => 5000,  // worker最大处理请求数
            'worker_num' => 8,      // worker数量
            'enable_coroutine' => true,     // 开启协程
        ]
    ],

    'log' => [
        'level' => \More\Src\Core\Log\Logger::LEVEL_DEBUG,
        'dateFormat' => "Y-m-d H:i:s"
    ],

    'database' => [
        'default' => [
            'driver'    => 'mysql',
            'host'      => '192.168.99.100',
            'database'  => 'test',
            'username'  => 'root',
            'password'  => '123456a.',
            'charset'   => 'utf8mb4',
            'collation' => 'utf8mb4_general_ci',
            //'unix_socket' => '/var/lib/mysql/mysql.sock',
            'prefix'    => 't_',
            'port'      => 3306,
            'getConnectionTimeout' => 1,    // 获取连接最多等待秒数
            'poolSize' => 20,
            'debug' => true,                 // 调试模式,打印sql
            'resultType' => \More\Src\Lib\Database\Model::RESULT_TYPE_ARRAY
        ]
    ],

    'redis' => [
        'host' => '192.168.99.100',
        'port' => 6379,
        'password' => '123456a.',
        'index' => 1,
        'poolSize' => 20,
        'connectTimeout' => 2,          // 连接超时时间($redis->connect()超时时间)
        'getConnectionTimeout' => 1,    // 从池中获取连接最多等待秒数($pool->pop()操作超时时间)
    ],

    'cache' => [
        'expire' => 86400,
        'prefix' => 'cache_'
    ],

    'session' => [
        'expire' => 86400,
        'prefix' => 'session_'
    ],

    // 是否开启路由缓存
    'routeCache' => true,
    // 路由缓存内存表大小
    'routeTableSize' => 1024,
    // 路由缓存表名称 (Container 中的 key)
    'routeTableName' => '__routeTable',

    // 临时文件夹
    'tempDir' => PROJECT_ROOT . '/temp',

    'timezone' => 'Asia/Shanghai',

    'providers' => [
        /** Framework Service Providers **/
        \More\Src\Core\Swoole\ServerManagerServiceProvider::class,
        /** HTTP Service Providers **/
        \More\Src\Core\Http\HttpServiceProvider::class,
        \More\Src\Core\Route\RouteServiceProvider::class,
        /** WebSocket Service Providers **/
        \More\Src\Core\WebSocket\WebSocketServiceProvider::class,
        /** Database Service Providers **/
        \More\Src\Lib\Database\DatabaseServiceProvider::class,
        \More\Src\Lib\Pool\PoolServiceProvider::class,
        \More\Src\Lib\Redis\RedisServiceProvider::class,

        \More\Src\Core\Log\LogServiceProvider::class,
        \More\Src\Lib\Cache\CacheServiceProvider::class,
    ],
);

示例

启动服务

运行 {projectroot}/Weekii/Bin/server.php 文件

# php server.php

路由

{projectroot}/App/Http/Routes/*.php

<?php
use \More\Src\Core\Route\RouteRule;
// 路由到闭包
RouteRule::get('/', function (\More\Src\Core\Http\Request $request, \More\Src\Core\Http\Response $response, \duncan3dc\Laravel\BladeInstance $view) {
    $response->redirect('/hello/' . $request->get('name'));
});

// 路由到控制器,支持路由变量,使用:key形式注册路由变量,可在控制器中通过 `request` 获取路由变量参数值
RouteRule::get('/hello/:name', \App\Http\Controller\IndexController::class . '@hello');
RouteRule::get('/view/:name', \App\Http\Controller\IndexController::class . '@view');
RouteRule::get('/db', \App\Http\Controller\IndexController::class . '@db');
RouteRule::get('/container/:id', \App\Http\Controller\IndexController::class . '@container');

控制器

Http 控制器位于 {projectroot}/App/Http/Controller 目录 命名方式为 IndexController.php 需要继承 \More\Src\Core\Http\Controller

<?php
namespace App\Http\Controller;

use App\Model\Member;
use \More\Src\Core\Http\Controller;

class IndexController extends Controller
{
    // 返回普通字符串
    public function hello()
    {
        $name = $this->request()->get('name');
        $this->write("<h1>Hello! {$name}</h1>");
    }

    // 返回 view 模板页面
    public function view()
    {
        $name = $this->request->get('name');
        $this->assign('name', $name);
        $this->fetch('index');
    }

    // 返回 json 格式数据
    public function json()
    {
        // 注意:在 writeJson 方法与 write 方法不要在一次 response 中同时使用,否则会破坏数据的 json 格式
        $this->writeJson([
            'msg' => '获取json成功',
            'code' => 2,
            'data' => 'json'
        ], 200);
    }

    // Model
    public function db()
    {
        $memberModel = new Member();

        $data = $memberModel->find(340);

        //$data = $memberModel->where('signature', 'LIKE', '%一批%')->first();

        var_dump($data->signature);

        $this->writeJson([
            'msg' => '获取json成功',
            'code' => 2,
            'data' => $data->signature
        ], 200);
    }

    // 依赖注入(只支持对象依赖注入)
    public function container(Member $member)
    {
        $data = $member->find($this->request()->get('id'));

        $this->writeJson([
            'msg' => '获取json成功',
            'code' => 2,
            'data' => $data->id
        ], 200);
    }
    
    // 协程
    public function coroutine(Member $member, Shop $shop)
    {
        $data = [];
        $userId = $this->request()->get('id');
        go(function () use ($member, &$data, $userId) {
            $data['member'] = $member->find($userId);
        });
        
        go(function () use ($shop, &$data, $userId) {
            $data['shop'] = $shop->where('user_id', $userId)->first();
        });
    
        $this->writeJson([
            'msg' => '获取json成功',
            'code' => 2,
            'data' => $data
        ], 200);
    }
    
    public function model(Member $memberModel)
    {
        $memberModel->find(1);
        $memberModel->name = '小余';
        $memberModel->save();
   
        $data = $memberModel->count('id');
   
        $data2 = $memberModel->with('card', ['*'], function ($row, Builder $card) {
            $card->where('title', $row['name']);
        })->get();
   
        $this->writeJson([
            'msg' => '获取json成功',
            'code' => 2,
            'data' => $data,
            'data2' => $data2
        ], 200);
    }
    
    public function join(Member $memberModel)
    {
        /*$memberModel->where('t_user.id', 2)->leftJoin('card', 't_user.id', '=', 't_card.user_id')
            ->first();*/
    
        $memberModel->where('t_user.id', 1)->leftJoin('card', function (Builder $builder) {
            $builder->on('t_user.id', '=', 't_card.user_id')
                ->where('t_card.id', 1);
        })->first();
    
        $this->writeJson([
            'msg' => '获取json成功',
            'code' => 2,
            'data' => $memberModel->title
        ], 200);
    }
        
    public function redis()
    {
        $cache = $this->app->cache;
        $result = $cache->set('name', 'Weekii');
    
        $this->writeJson([
            'msg' => '获取json成功',
            'code' => 2,
            'data' => [
                'result' => $result,
                'cache' => $cache->get('name')
            ]
        ], 200);
    }
}

模型

TestController.php

public function model(Member $memberModel)
    {
        // 获取主键为340的记录
        $memberModel->find(340);
        
        // 通过当前数据对象(主键为340的记录)修改数据
        $memberModel->signature = '帅的一批的人';
        $data = $memberModel->save();
        
        // 通过键值对数组修改数据
        $memberModel->where('type', 1)->update(['signature' => '帅的一批的人']);
        
        // 通过当前数据对象添加数据
        $memberModel = new Member();
        $memberModel->signature = '帅的一批的人';
        $memberModel->add();
        
        
        // 通过键值对数组添加数据
        $memberModel->insert(['signature' => '帅的一批的人']);
    }

其他用法请参照框架源码~

You can’t perform that action at this time.