PHPackages                             tigerb/easy-php - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. tigerb/easy-php

ActiveFramework[Database &amp; ORM](/categories/database)

tigerb/easy-php
===============

A Faster Lightweight Full-Stack PHP Framework

0.8.6(7y ago)770280131[1 issues](https://github.com/TIGERB/easy-php/issues)[24 PRs](https://github.com/TIGERB/easy-php/pulls)MITPHP

Since May 15Pushed 3y ago41 watchersCompare

[ Source](https://github.com/TIGERB/easy-php)[ Packagist](https://packagist.org/packages/tigerb/easy-php)[ Docs](http://easy-php.tigerb.cn/)[ RSS](/packages/tigerb-easy-php/feed)WikiDiscussions master Synced 3d ago

READMEChangelog (9)Dependencies (3)Versions (37)Used By (0)

[![](https://camo.githubusercontent.com/a117e66e32fd792926908194ed8901eb89ec5caf6e3e3ee3d8276ab9b023c30f/687474703a2f2f626c6f672d313235313031393936322e636f732e61702d6265696a696e672e6d7971636c6f75642e636f6d2f71696e69755f696d675f323032322f6c6f676f2e706e67)](https://camo.githubusercontent.com/a117e66e32fd792926908194ed8901eb89ec5caf6e3e3ee3d8276ab9b023c30f/687474703a2f2f626c6f672d313235313031393936322e636f732e61702d6265696a696e672e6d7971636c6f75642e636f6d2f71696e69755f696d675f323032322f6c6f676f2e706e67)

[![Build Status](https://camo.githubusercontent.com/01ab94bfee38ef5f187b8eb57774a53dbd286c11185d4af79ed7bbf328f6384b/68747470733a2f2f6170692e7472617669732d63692e6f72672f5449474552422f656173792d7068702e7376673f6272616e63683d6d6173746572)](https://github.com/TIGERB/easy-php/releases)[![Code Coverage](https://camo.githubusercontent.com/4bebb3190ef02df3498a3056980bdb21dd4126a79cd853c6d26079d70c9c07c9/68747470733a2f2f636f6465636f762e696f2f67682f5449474552422f656173792d7068702f6272616e63682f6d61737465722f67726170682f62616467652e737667)](https://github.com/TIGERB/easy-php/releases)[![Version](https://camo.githubusercontent.com/a8aee9e48cf2f18992341cd6ebf14abb58289d403452368edb81d8da7c401de7/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f76657273696f6e2d302e382e362d6c69676874677265792e737667)](https://github.com/TIGERB/easy-php/releases)[![PHP Version](https://camo.githubusercontent.com/581d3b86ad2a67effa63792b85b18395acbbc26aae6ab4a453ed555677b8761c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f7068702d352e342532422d626c75652e737667)](https://github.com/TIGERB/easy-php/releases)[![Docker env](https://camo.githubusercontent.com/d0e225bdf00db58f2cb1e7cec667243f69c6ec40cb59c134eb7dc51e75ed3a04/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f646f636b6572253230656e762d737570706f72742d677265656e2e737667)](https://easy-framework.github.io/easy-env/)[![License](https://camo.githubusercontent.com/e613ab3c2d83fd60009d0a4f2d2a7493048d63e7ddf28730e2825721b80bf7aa/68747470733a2f2f696d672e736869656c64732e696f2f636f636f61706f64732f6c2f41464e6574776f726b696e672e737667)](https://opensource.org/licenses/MIT)

 A Faster Lightweight Full-Stack PHP Framework

 [![](https://camo.githubusercontent.com/b1d4b80fd193ba5a5dabea6e4379412ea6d50afa41e3bb208be4cc7a73651c58/687474703a2f2f626c6f672d313235313031393936322e636f732e61702d6265696a696e672e6d7971636c6f75642e636f6d2f71696e69755f696d675f323032322f7765636861742d626c6f672d7172636f64652e6a70673f696d6167654d6f6772322f7468756d626e61696c2f32363078323630212f666f726d61742f776562702f626c75722f3178302f7175616c6974792f39307c696d616765736c696d)](https://camo.githubusercontent.com/b1d4b80fd193ba5a5dabea6e4379412ea6d50afa41e3bb208be4cc7a73651c58/687474703a2f2f626c6f672d313235313031393936322e636f732e61702d6265696a696e672e6d7971636c6f75642e636f6d2f71696e69755f696d675f323032322f7765636861742d626c6f672d7172636f64652e6a70673f696d6167654d6f6772322f7468756d626e61696c2f32363078323630212f666f726d61742f776562702f626c75722f3178302f7175616c6974792f39307c696d616765736c696d)

 [中文版](./README-CN.md)

Docker env
==========

[](#docker-env)

> Just one command to build all env for the easy-php

[![easy-env](https://camo.githubusercontent.com/f40306ca37b7e80e31f3c9cec2bb5a50e4fdf58dd7944fd4efb1fa6c607cf406/68747470733a2f2f61736369696e656d612e6f72672f612f3231393931312e737667)](https://asciinema.org/a/219911?autoplay=1)

How to build a PHP framework by ourself ?
=========================================

[](#how-to-build-a-php-framework-by-ourself-)

Why do we need to build a PHP framework by ourself? Maybe the most of people will say "There have so many PHP frameworks be provided, but we still made a wheel?". My point is "Made a wheel is not our purpose, we will get a few of knowledge when making a wheel which is our really purpose".

Then, how to build a PHP framework by ourself? General process as follows:

```
Entry file ----> Register autoload function
           ----> Register error(and exception) function
           ----> Load config file
           ----> Request
           ----> Router
           ----> (Controller  Model)
           ----> Response
           ----> Json
           ----> View

```

In addition, unit test, nosql support, api documents and some auxiliary scripts, e.g. Finnally, My framework directory as follows:

Project Directory Structure
===========================

[](#project-directory-structure)

```
app                             [application backend directory]
├── demo                        [module directory]
│   ├── controllers             [controller directory]
│   │       └── Index.php       [default controller class file]
│   ├── logics                  [logic directory]
│   │   ├── exceptions          [exception directory]
│   │   ├── gateway          　　[a gateway example]
│   │   ├── tools               [tool class directory]
│   │   └── UserDefinedCase.php [register user defined handle before framework loading router]
│   └── models                  [model directory]
│       └── TestTable.php       [model class file]
├── config                      [config folder]
│    ├── demo                   [module config folder]
│    │   ├── config.php         [module-defined config]
│    │   └── route.php          [module-defined router]
│    ├── common.php             [common config]
│    ├── database.php           [database config]
│    ├── swoole.php             [swoole config]
│    └── nosql.php              [nosql config]
docs                            [api document directory]
├── apib                        [Api Blueprint]
│    └── demo.apib              [api doc example file]
├── swagger                     [swagger]
framework                       [easy-php framework directory]
├── exceptions                  [core exception class]
│      ├── CoreHttpException.php[http exception]
├── handles                     [handle class file be used by app run]
│      ├── Handle.php           [handle interface]
│      ├── ErrorHandle.php      [error handle class]
│      ├── ExceptionHandle.php  [exception handle class]
│      ├── ConfigHandle.php     [config handle class]
│      ├── NosqlHandle.php      [nosql handle class]
│      ├── LogHandle.php        [log handle class]
│      ├── UserDefinedHandle.php[user defined handle class]
│      ├── RouterSwooleHan...   [router handle class for swoole mode]
│      └── RouterHandle.php     [router handle class]
├── orm                         [datebase object relation map class directory]
│      ├── Interpreter.php      [sql Interpreter class]
│      ├── DB.php               [database operation class]
│      ├── Model.php            [data model]
│      └── db                   [db type directory]
│          └── Mysql.php        [mysql class file]
├── router                      [router strategy]
│      ├── RouterInterface.php  [router strategy interface]
│      ├── General.php          [general strategy class]
│      ├── Pathinfo.php         [pathinfo strategy class]
│      ├── Userdefined.php      [userdefined strategy class]
│      ├── Micromonomer.php     [micromonomer strategy class]
│      ├── Job.php              [job strategy class]
│      ├── EasySwooleRouter.php [router strategy entrance class for swoole mode]
│      └── EasyRouter.php       [router strategy entrance class]
├── nosql                       [nosql directory]
│    ├── Memcahed.php           [memcahed class file]
│    ├── MongoDB.php            [mongoDB class file]
│    └── Redis.php              [redis class file]
├── App.php                     [this application class file]
├── Container.php               [container class file]
├── Helper.php                  [helper class file]
├── Load.php                    [autoload class file]
├── Request.php                 [request object class file]
├── Response.php                [response object class file]
├── run.php                     [run this application script file]
├── swoole.php                  [init the framework && swoole server]
frontend                        [application frontend source code directory]
├── src                         [source folder]
│    ├── components             [vue components]
│    ├── views                  [vue views]
│    ├── images                 [images folder]
│    ├── ...
├── app.js                      [vue root js]
├── app.vue                     [vue root component]
├── index.template.html         [frontend entrance template file]
├── store.js                    [vuex store file]
├── .babelrc                    [babel　config file]
├── webpack.config.js           [webpack config file]
├── yarn.lock                   [yarn　lock file]
jobs                            [Jobs folder, where write you business script]
├── demo                        [Module folder]
│    ├── Demo.php               [Job script example file]
│    ├── ...
public                          [this is a resource directory to expose service resource]
├── dist                        [frontend source file after build]
│    └── ...
├── index.html                  [entrance html file]
├── index.php                   [entrance php script file]
├── server.php                  [init the server with swoole]
runtime                         [temporary file such as log]
├── logs                        [log directory]
├── build                       [phar directory build by build script]
tests                           [unit test directory]
├── demo                        [module name]
│      └── DemoTest.php         [test class file]
├── TestCase.php                [phpunit test case class file]
vendor                          [composer vendor directory]
.git-hooks                      [git hooks directory]
├── pre-commit                  [git pre-commit example file]
├── commit-msg                  [git commit-msg example file]
bin                             [the auto script folder]
├── build                       [build php code to phar file script]
├── cli                         [run this framework with the php cli mode]
├── run                         [quick start script]
.env.example                    [the environment variables example file]
.gitignore                      [git ignore config file]
.travis.yml                     [travis-ci config file]
LICENSE                         [lincese　file]
logo.png                        [logo picture]
composer.json                   [composer file]
composer.lock                   [composer lock file]
package.json                    [dependence file for frontend]
phpunit.xml                     [phpunit config file]
README-CN.md                    [readme file chinese]
README.md                       [readme file]

```

Life Cycle
==========

[](#life-cycle)

[![](https://camo.githubusercontent.com/f75987a60955746cbd3feb7a3a32cd0d572f55afcb9af26eab2c67c9627efe76/687474703a2f2f626c6f672d313235313031393936322e636f732e61702d6265696a696e672e6d7971636c6f75642e636f6d2f71696e69755f696d675f323032322f656173792d7068702d656e2e706e67)](https://camo.githubusercontent.com/f75987a60955746cbd3feb7a3a32cd0d572f55afcb9af26eab2c67c9627efe76/687474703a2f2f626c6f672d313235313031393936322e636f732e61702d6265696a696e672e6d7971636c6f75642e636f6d2f71696e69755f696d675f323032322f656173792d7068702d656e2e706e67)

Framework Module Description:
=============================

[](#framework-module-description)

Entrance file
-------------

[](#entrance-file)

Defined a entrance file that provide a uniform file for user visit, which hide the complex logic like the enterprise service bus.

```
// require the application run file
require('../framework/run.php');

```

\[[file: public/index.php](https://github.com/TIGERB/easy-php/blob/master/public/index.php)\]

Autoload Module
---------------

[](#autoload-module)

Register a autoload function in the \_\_autoload queue by used spl\_autoload\_register, after that, we can use a class by namespace and keyword 'use'.

\[[file: framework/Load.php](https://github.com/TIGERB/easy-php/blob/master/framework/Load.php)\]

Error&amp;Exception Handle Module
---------------------------------

[](#errorexception-handle-module)

- Catch error:

Register a function by used set\_error\_handler to handle error, but it can't handle the following error, E\_ERROR, E\_PARSE, E\_CORE\_ERROR, E\_CORE\_WARNING, E\_COMPILE\_ERROR, E\_COMPILE\_WARNING and the E\_STRICT produced by the file which called set\_error\_handler function. So, we need use register\_shutdown\_function and error\_get\_last to handle this finally error which set\_error\_handler can't handle. When the framework running, we can handle the error by ourself, such as, give a friendly error messge for client.

\[[file: framework/hanles/ErrorHandle.php](https://github.com/TIGERB/easy-php/blob/master/framework/handles/ErrorHandle.php)\]

- Catch exception:

Register a function by used set\_exception\_handler to handle the exception which is not be catched, which can give a friendly error messge for client.

\[[file: framework/hanles/ExceptionHandle.php](https://github.com/TIGERB/easy-php/blob/master/framework/handles/ExceptionHandle.php)\]

Config Handle Module
--------------------

[](#config-handle-module)

Loading framework-defined and user-defined config files.

For example，the master-salve database config：

```
[database]
dbtype   = mysqldb
dbprefix = easy
dbname   = easyphp
dbhost   = localhost
username = easyphp
password = easyphp
slave    = 0,1

[database-slave-0]
dbname   = easyphp
dbhost   = localhost
username = easyphp
password = easyphp

[database-slave-1]
dbname   = easyphp
dbhost   = localhost
username = easyphp
password = easyphp

```

\[[file: framework/hanles/ConfigHandle.php](https://github.com/TIGERB/easy-php/blob/master/framework/handles/ConfigHandle.php)\]

Request&amp;Response Module
---------------------------

[](#requestresponse-module)

- Request Object: contains all the requested information.
- Response Object: contains all the response information.

All output is json in the framework, neithor framework's core error or business logic's output, beacuse I think is friendly.

##### Request param check, Support require/length/number check at present. Use as follows:

[](#request-param-check-support-requirelengthnumber-check-at-present-use-as-follows)

```
$request = App::$container->get('request');
$request->check('username', 'require');
$request->check('password', 'length', 12);
$request->check('code', 'number');

```

\[[file: framework/Request.php](https://github.com/TIGERB/easy-php/blob/master/framework/Request.php)\]

\[[file: framework/Response.php](https://github.com/TIGERB/easy-php/blob/master/framework/Response.php)\]

Route Handle Module
-------------------

[](#route-handle-module)

```
├── router                      [datebase object relation map class directory]
      ├── RouterInterface.php   [router strategy interface]
      ├── General.php           [general strategy class]
      ├── Pathinfo.php          [pathinfo strategy class]
      ├── Userdefined.php       [userdefined strategy class]
      ├── Micromonomer.php      [micromonomer strategy class]
      ├── Job.php               [job strategy class]
      └── EasyRouter.php        [router strategy entrance class]

```

Execute the target controller's function by the router parse the url information.Is composed of four types of:

**tradition router**

```
domain/index.php?module=Demo&contoller=Index&action=test&username=test

```

**pathinfo router**

```
domain/demo/index/modelExample

```

**user-defined router**

```
// config/moduleName/route.php, this 'this' point to RouterHandle instance
$this->get('v1/user/info', function (Framework\App $app) {
    return 'Hello Get Router';
});

```

**micro monolith router**

What's the micro monolith router? There are a lot of teams are moving in the SOA service structure or micro service structure, I think it is difficult for a small team. So the micro monolith was born, what's this? In my opinion, this is a SOA process for a monolith application.For example:

```
app
├── UserService     [user service module]
├── ContentService  [content service module]
├── OrderService    [order service module]
├── CartService     [cart service module]
├── PayService      [pay service module]
├── GoodsService    [goods service module]
└── CustomService   [custom service module]

```

As above, we implemented a easy micro monolith structure.But how these module to communicate with each other? As follows:

```
App::$app->get('demo/index/hello', [
    'user' => 'TIGERB'
]);

```

So we can resolve this problem loose coupling. In the meantime, we can exchange our application to the SOA structure easily, beacuse we only need to change the method get implementing way in the App class, the way contain RPC, REST. etc.

\[[file: framework/hanles/RouterHandle.php](https://github.com/TIGERB/easy-php/blob/master/framework/handles/RouterHandle.php)\]

MVC To MCL
----------

[](#mvc-to-mcl)

The tradition MVC pattern includes the model,view,controller layer. In general, you always write the business logic in the controller or model layer. But you will feel the code is difficult to read, maintain, expand after a long time. So I add a logic layer in the framework forcefully where you can implement the business logic by yourself. You can not only implement a tool class but also implement your business logic in a new subfolder, what's more, you can implement a gateway based on the pattern of responsibility (I provided a example).

In the end, the structure as follows:

- M: models, the map of database's table where define the curd operation.
- C: controllers, where expose the business resourse
- L: logics, where implement the business logic flexiblly

**Logics layer**

A gateway example：

I built a gateway in the logics folder, structure as follows：

```
gateway                     [gateway directory in logics]
  ├── Check.php             [interface]
  ├── CheckAppkey.php       [check app key]
  ├── CheckArguments.php    [check require arguments]
  ├── CheckAuthority.php    [check auth]
  ├── CheckFrequent.php     [check call frequent]
  ├── CheckRouter.php       [router]
  ├── CheckSign.php         [check sign]
  └── Entrance.php          [entrance file]

```

The gateway entrance class code as follows:

```
// init：gateway common arguments must be not empty check
$checkArguments   =  new CheckArguments();
// init：app key check
$checkAppkey      =  new CheckAppkey();
// init：call frequent check
$checkFrequent    =  new CheckFrequent();
// init：sign check
$checkSign        =  new CheckSign();
// init：auth check
$checkAuthority   =  new CheckAuthority();
// init：gateway's router
$checkRouter      =  new CheckRouter();

// build object chain
$checkArguments->setNext($checkAppkey)
               ->setNext($checkFrequent)
               ->setNext($checkSign)
               ->setNext($checkAuthority)
               ->setNext($checkRouter);

// start gateway
$checkArguments->start(
    APP::$container->get('request')
);

```

After the gateway be implemented, how to use this in the framework?I provide a user-defined's class, we just register this in the UserDefinedCase class. for example:

```
/**
 * register user-defined behavior
 *
 * @var array
 */
private $map = [
    //　for example, loading user-defined gateway
    'App\Demo\Logics\Gateway\Entrance'
];

```

So, the gateway is running.But what's the UserDefinedCase that can be loading before RouterHandle.

Where is the view layer?I abandon it, beacuse I chose the SPA for frontend, detail as follows.

\[[file: app/\*](https://github.com/TIGERB/easy-php/tree/master/app/demo)\]

Using Vue For View
------------------

[](#using-vue-for-view)

**source code folder**

The separate-frontend-and-backend and two-way data binding, modular is so popular.In the meantime, I moved the project [easy-vue](http://vue.tigerb.cn/) that built by myself to the framework as the view layer. The frontend source code folder as follows:

```
frontend                        [application frontend source code directory]
├── src                         [source folder]
│    ├── components             [vue components]
│    ├── views                  [vue views]
│    ├── images                 [images folder]
│    ├── ...
├── app.js                      [vue root js]
├── app.vue                     [vue root component]
├── index.template.html         [frontend entrance template file]
├── store.js                    [vuex store file]

```

**Build Step**

```
yarn install

DOMAIN=http://yourdomain npm run dev

```

**After build**

After built success, there made dist folder and index.html in the public. This file will be ignore when this branch is not the release branch.

```
public                          [this is a resource directory to expose service resource]
├── dist                        [frontend source file after build]
│    └── ...
├── index.html                  [entrance html file]

```

\[[file: frontend/\*](https://github.com/TIGERB/easy-php/tree/master/frontend)\]

ORM
---

[](#orm)

What's the ORM(Object Relation Map)? In my opinion, ORM is a thought that build a relationship of object and the abstract things.The model is the database's table and the model's instance is a operation for the table."Why do you do that, use the sql directly is not good?", my answer:you can do what you like to do, everything is flexable, but it's not be suggested from a perspective of a framework's **reusable, maintainable and extensible**.

On the market for the implemention of the ORM, such as: Active Record in thinkphp and yii, Eloquent in laravel, then we call the ORM here is "ORM" simply. The "ORM" structure in the framework as follows:

```
├── orm
│      ├── Interpreter.php      [sql Interpreter]
│      ├── DB.php               [database operate class]
│      ├── Model.php            [base model class]
│      └── db
│          └── Mysql.php        [mysql class]

```

**DB example**

```
/**
 * DB operation example
 *
 * findAll
 *
 * @return void
 */
public function dbFindAllDemo()
{
    $where = [
        'id'   => ['>=', 2],
    ];
    $instance = DB::table('user');
    $res      = $instance->where($where)
                         ->orderBy('id asc')
                         ->limit(5)
                         ->findAll(['id','create_at']);
    $sql      = $instance->sql;

    return $res;
}

```

**Model example**

```
// controller
/**
 * model example
 *
 * @return mixed
 */
public function modelExample()
{
    try {

        DB::beginTransaction();
        $testTableModel = new TestTable();

        // find one data
        $testTableModel->modelFindOneDemo();
        // find all data
        $testTableModel->modelFindAllDemo();
        // save data
        $testTableModel->modelSaveDemo();
        // delete data
        $testTableModel->modelDeleteDemo();
        // update data
        $testTableModel->modelUpdateDemo([
               'nickname' => 'easy-php'
            ]);
        // count data
        $testTableModel->modelCountDemo();

        DB::commit();
        return 'success';

    } catch (Exception $e) {
        DB::rollBack();
        return 'fail';
    }
}

//TestTable model
/**
 * Model example
 *
 * findAll
 *
 * @return void
 */
public function modelFindAllDemo()
{
    $where = [
        'id'   => ['>=', 2],
    ];
    $res = $this->where($where)
                ->orderBy('id asc')
                ->limit(5)
                ->findAll(['id','create_at']);
    $sql = $this->sql;

    return $res;
}

```

\[[file: framework/orm/\*](https://github.com/TIGERB/easy-php/tree/master/framework/orm)\]

Service Container
-----------------

[](#service-container)

What's the service container?

Service container is difficultly understand, I think it just a third party class, which can inject the class and instance. we can get the instance in the container very simple.

The meaning of the service container?

According to the design patterns: we need make our code "highly cohesive, loosely coupled". As the result of "highly cohesive" is "single principle", As the result of "single principle" is the class rely on each other. General way that handle the dependency as follows:

```
class Demo
{
    public function __construct ()
    {
        // the demo directly dependent on RelyClassName
        $instance = new RelyClassName ();
    }
}

```

The above code is no problem, but is not conform to the design pattern of "The least kown principle", beacuse it has a direct dependence. We bring a third class in the framework, which can new a class or get a instance. So, the third party class is the service container, which like the role of 'middleware' in the architecture of the system.

After implements a service container, I put the Rquest, Config and other instances are injected into service in the singleton container, when we need to use can be obtained from the container, is very convenient.Use the following:

```
// Inject the single instance
App::$container->setSingle('alias', 'object/closure/class name');

// Such as，Inject Request instance
App::$container->setSingle('request', function () {
    // closure function lazy load
    return new Request();
});
// get Request instance
App::$container->get('request');

```

\[[file: framework/Container](https://github.com/TIGERB/easy-php/blob/master/framework/Container.php)\]

Nosql Support
-------------

[](#nosql-support)

Inject the nosql's single instance in service container when the framework loading, you can decide what nosql you need use whit the configuration. At present we support redis/memcahed/mongodb.

Some example:

```
// get redis instance
App::$container->getSingle('redis');
// get memcahed instance
App::$container->getSingle('memcahed');
// get mongodb instance
App::$container->getSingle('mongodb');

```

\[[file: framework/nosql/\*](https://github.com/TIGERB/easy-php/tree/master/framework/nosql)\]

Log
---

[](#log)

I make the log class like a third part module that be used by composer, the project link

How to use? as follows:

```
// env config
[log]
path = /runtime/logs/
name = easy-php
size = 512
level= debug

// How to use in your logic
Log::debug('EASY PHP');
Log::notice('EASY PHP');
Log::warning('EASY PHP');
Log::error('EASY PHP');

```

\[[file: framework/handles/LogHandle.php](https://github.com/TIGERB/easy-php/blob/master/framework/handles/LogHandle.php)\]

Swoole Support
--------------

[](#swoole-support)

This framework support swoole mode with the php extension swoole, just:

```
cd public && php server.php

```

\[[file: framework/swoole.php](https://github.com/TIGERB/easy-php/tree/master/framework/swoole.php)\]

Job Support
-----------

[](#job-support)

You can do some job in the jobs folder directly as follows:

```
jobs                            [Jobs folder, where write you business script]
├── demo                        [Module folder]
│    ├── Demo.php               [Job script example file]
│    ├── ...

```

Job demo file:

```
