jhq0113/roach

v1.0.2 2020-07-24 13:01 UTC

This package is auto-updated.

Last update: 2020-10-25 13:28:55 UTC


README

roach是一个基于composer开发的一个基础工具库,可以嵌入到任何php语言开发的项目当中。

roach使用简单,精简,整个代码库纯代码大小为60K

8.0K    ./src/exceptions
 28K    ./src/extensions
 16K    ./src/http
8.0K    ./src/events

我的官方网站

https://404.360tryst.com/

安装方式

composer require jhq0113/roach

目录

容器

创建如下app\model\User

<?php
namespace app\model;

/**
 * Class User
 * @datetime 2020/7/2 11:23 PM
 * @author roach
 * @email jhq0113@163.com
 */
class User
{
    /**
     * @var string
     * @datetime 2020/7/2 11:22 PM
     * @author roach
     * @email jhq0113@163.com
     */
    public $userName;

    /**
     * @var string
     * @datetime 2020/7/2 11:22 PM
     * @author roach
     * @email jhq0113@163.com
     */
    public $password;

    /**
     * @var int
     * @datetime 2020/7/2 11:24 PM
     * @author roach
     * @email jhq0113@163.com
     */
    protected $_currentTime;

    /**
     * User constructor.
     * @param string $userName
     */
    public function __construct($userName = '')
    {
        $this->userName = $userName;
    }

     /**
     * @datetime 2020/7/6 10:49 上午
     * @author   roach
     * @email    jhq0113@163.com
     */
    public function init()
    {
        $this->_currentTime = time();
    }

    /**
     * @param int $time
     * @datetime 2020/7/3 1:40 下午
     * @author   roach
     * @email    jhq0113@163.com
     */
    public function setTime($time)
    {
        $this->_currentTime = $time;
    }

    /**
     * @return int
     * @datetime 2020/7/2 11:24 PM
     * @author roach
     * @email jhq0113@163.com
     */
    public function getCurrentTime()
    {
        return $this->_currentTime;
    }
}

依赖注入

Container通过createRoach实现依赖注入,createRoach方法每次运行都会根据配置创建一个全新的对象。

  • 属性注入
<?php
/**
 * @var app\model\User $user
 */
$user = Container::createRoach([
    'class' => 'app\model\User',
    'userName' => 'lao zhou',
    'password' => hash('sha1', '123456')
]);

echo json_encode([
    'userName'    => $user->userName,
    'password'    => $user->password,
], JSON_UNESCAPED_UNICODE).PHP_EOL;

以上例程输出

{"userName":"lao zhou", "password":"7c4a8d09ca3762af61e59520943dc26494f8941b"}
  • 通过calls配置进行构造函数注入
<?php
/**
 * @var app\model\User $user
 */
$user = Container::createRoach([
    'class' => 'app\model\User',
    'calls' => [
        '__construct' => ['xiao mage']
    ],
]);

exit(json_encode([
    'userName'    => $user->userName,
    'password'    => $user->password,
], JSON_UNESCAPED_UNICODE).PHP_EOL);

以上例程输出

{"userName":"xiao mage", "password":null}
  • 通过calls进行方法注入

无参数方法注入

<?php
/**
 * @var \app\model\User $user2
 */
$user2 = Container::createRoach([
    'class' => 'app\model\User',
    'calls' => [
        'init'
    ],
]);

echo json_encode([
    'currentTime'    => $user2->getCurrentTime()
], JSON_UNESCAPED_UNICODE).PHP_EOL;

以上例程会调用一次init方法,运行输出

{"currentTime":1593735048}

有参数方法注入

<?php
/**
 * @var \app\model\User $user2
 */
$user2 = Container::createRoach([
    'class' => 'app\model\User',
    'calls' => [
        '__construct' => ['boss zhou'],
        'setTime'     => [ time() ],
    ],
]);

echo json_encode([
    'userName'    => $user2->userName,
    'currentTime'    => $user2->getCurrentTime(),
], JSON_UNESCAPED_UNICODE).PHP_EOL;

以上例程输出

{"userName":"boss zhou", "currentTime":1593755048}

调用队列

<?php
/**
 * @var \app\model\User $user3
 */
$user3 = Container::createRoach([
    'class' => 'app\model\User',
    'calls' => [
        '__construct' => ['boss zhou'],
        [
            'method' => 'setTime',
            'params' => [ time() ],
        ],
        [
            'method' => 'setTime',
            'params' => [ time() ],
        ],
    ],
]);

echo json_encode([
    'userName'       => $user3->userName,
    'currentTime'    => $user3->getCurrentTime(),
], JSON_UNESCAPED_UNICODE).PHP_EOL;

以上例程,会先调用构造函数,然后调用两次setTime方法,以上例程输出

{"userName":"boss zhou", "currentTime":1593756048}

回到目录

依赖注入容器

当向容器中放入一个包含class节点的数组时,容器会在调用get方法时根据数组配置实例化对象。

<?php
//将app\model\User放入容器,app\model\User对象并未创建
Container::set('user', [
    'class' => 'app\model\User',
    'userName' => 'platform',
    'password' => hash_hmac('md5', 'roach', uniqid()),
    'calls'    => [
        'setTime' => [ time() ]
    ]
]);

/**
 * @var User $singleUser
 */
$singleUser = Container::get('user');
echo json_encode([
        'userName'    => $singleUser->userName,
        'password'    => $singleUser->password,
        'currentTime' => $singleUser->getCurrentTime()
    ], JSON_UNESCAPED_UNICODE).PHP_EOL;

$singleUser->userName = 'single';

/**
 * @var User $reGetUser
 */
$reGetUser = Container::get('user');
echo json_encode([
        'userName'    => $reGetUser->userName,
        'password'    => $reGetUser->password,
        'currentTime' => $reGetUser->getCurrentTime()
    ], JSON_UNESCAPED_UNICODE).PHP_EOL;

以上例程输出

{"userName":"platform","password":"f66d715da660911d2d618cb36c24d30b","currentTime":1593755260}
{"userName":"single","password":"f66d715da660911d2d618cb36c24d30b","currentTime":1593755260}
  • 1.依赖注入容器的对象是懒加载的,只有在调用get方法的时候才会真正的创建对象
  • 2.依赖注入容器创建的对象是单例

回到目录

变量容器

当容器中放入一个非包含class节点数组的任意其他值时,容器只是一个存储变量的容器,且只有一份。

<?php
Container::set('startTime', time());
Container::set('config', [
   'appName' => 'roach',
   'version' => '1.0.0'
]);
Container::set('user1', new User());

echo Container::get('startTime').PHP_EOL;
echo json_encode(Container::get('config'), JSON_UNESCAPED_UNICODE).PHP_EOL;
echo json_encode(Container::get('user1'), JSON_UNESCAPED_UNICODE).PHP_EOL;

以上例程输出

1593705970
{"appName":"roach","version":"1.0.0"}
{"userName":null,"password":null}

回到目录

通用异常错误处理

使用roach\exceptions\ErrorHandler处理通用异常与错误

<?php
use roach\Container;

//注入异常处理handler
Container::set('errorHandler', [
    'class' => 'roach\exceptions\ErrorHandler',
    //当捕获未被try...catch捕获的异常,会交由此handler处理
    'handler' => function(\Throwable $exception) {
        //打日志
        //报警。。。
        exit(json_encode([
            'code' => $exception->getCode(),
            'file' => $exception->getFile(),
            'line' => $exception->getLine(),
            'message' => $exception->getMessage(),
        ],JSON_UNESCAPED_UNICODE).PHP_EOL);
    }
]);

/**
 * @var \roach\exceptions\ErrorHandler $errorHandler
 */
$errorHandler = Container::get('errorHandler');
//注册通用异常处理
$errorHandler->run();

//出发调用未定义方法错误
fun();
//$a =5/0;

以上例程输出

{"code":0,
"file":"...\/roach\/src\/test\/exception.php",
"line":25,
"message":"Call to undefined function fun()"}

回到目录

使用事件

事件是通过roach\events\Event实现的,是个trait类型,这样任何一个类只要use了该trait都可以支持事件机制。

  • 1.为对象绑定事件,使用on方法,on方法第二个参数是个callable类型,该callable会默认附带一个参数,参数类型为roach\events\EventObject

  • 2.触发对象事件,使用trigger方法触发事件,如果对象没有绑定事件,事件不会触发。

使用案例

<?php
use roach\Container;
use roach\extensions\ECli;

require __DIR__.'/bootstrap.php';

/**
 * Class LoginServer
 * @datetime 2020/7/3 2:13 下午
 * @author   roach
 * @email    jhq0113@163.com
 */
class Login
{
    /**
     * 使用事件特性
     */
    use \roach\events\Event;

    const EVENT_LOGIN_BEFORE   = 'before';
    const EVENT_LOGIN_SUCCESS  = 'success';
    const EVENT_LOGIN_FAILED   = 'failed';

    /**
     * @param int    $phone
     * @param string $code
     * @return bool
     * @datetime 2020/7/3 2:12 下午
     * @author   roach
     * @email    jhq0113@163.com
     */
    public function loginByPhone($phone, $code)
    {
        $this->trigger(self::EVENT_LOGIN_BEFORE);

        if($phone == 13000000000 && $code === '123456') {

            $afterLoginEvent = Container::createRoach([
                'class' => 'roach\events\EventObject',
                'sender' => $this,
                'data'   => [
                    'userId' => time()
                ]
            ]);

            $this->trigger(self::EVENT_LOGIN_SUCCESS, $afterLoginEvent);
            return true;
        }

        $this->trigger(self::EVENT_LOGIN_FAILED);

        return false;
    }
}

/**
 * @var Login $login
 */
$login = Container::createRoach([
    'class' => Login::class
]);

$login->on(Login::EVENT_LOGIN_BEFORE, function (\roach\events\EventObject $event) {
    ECli::warn('start login');
});

$login->on(Login::EVENT_LOGIN_FAILED, function (\roach\events\EventObject $event) {
    ECli::error('login failed');
});

$login->on(Login::EVENT_LOGIN_SUCCESS, function (\roach\events\EventObject $event) {
    ECli::info('login success:'.$event->data['userId']);
});

$login->loginByPhone(1233333, '343434');
$login->loginByPhone(13000000000, '123456');

以上例程输出

[2020-07-03 06:23:55]   warn:[ start login ]
[2020-07-03 06:23:55]   error:[ login failed ]
[2020-07-03 06:23:55]   warn:[ start login ]
[2020-07-03 06:23:55]   info:[ login success:1593757435 ]

回到目录

发送HTTP请求

发送HTTP请求需要通过roach\http\Request类去发送,该类会自动识别httphttps协议请求。

连贯操作发送请求

<?php
$res = (new Request())
        ->setUrl('https://www.baidu.com')
        ->setTimeout(3)
        ->setParams([
            'userName' => 'sdfafd'
        ])
        ->post();
\roach\extensions\ECli::error($res->getBody());

以上例程输出

[2020-07-03 06:44:44]   error:[ <html>
<head><title>302 Found</title></head>
<body bgcolor="white">
<center><h1>302 Found</h1></center>
<hr><center>nginx</center>
</body>
</html>
 ]

回到目录

通过容器发送请求

/**
 * @var Request $request
 */
$request = Container::createRoach([
    'class'  => 'roach\http\Request',
    'url'    => 'https://www.baidu.com',
    'params' => [
        'from' => time()
    ]
]);

$response = $request->get();
\roach\extensions\ECli::info($response->getBody());

以上例程输出

[2020-07-03 06:44:44]   info:[ <!DOCTYPE html><!--STATUS OK-->
<html>
<head>
        <meta http-equiv="content-type" content="text/html;charset=utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=Edge">
        <link rel="dns-prefetch" href="//s1.bdstatic.com"/>
...

回到目录

并行发送多个请求

并行发送多个请求可以通过调用roach\http\Request的静态方法multiRequest实现,参数类型为roach\http\Request,参数个数是动态的,multiRequest方法会按照参数传入的顺序返回请求结果。

$req1 = Container::createRoach([
    'class'  => 'roach\http\Request',
    'url'    => 'https://www.360.cn',
]);

$req2 = Container::createRoach([
    'class'  => 'roach\http\Request',
    'url'    => 'http://www.sina.com',
    'params' => [
        'from' => time()
    ]
]);

$req3 = Container::createRoach([
    'class'  => 'roach\http\Request',
    'url'    => 'https://www.baidu.com',
    'params' => [
        'from' => time()
    ]
]);

$respList = Request::multiRequest($req1, $req2, $req3);
\roach\extensions\ECli::info($respList[0]->get('url'));
\roach\extensions\ECli::info($respList[1]->get('url'));
\roach\extensions\ECli::info($respList[2]->get('url'));

以上例程输出

[2020-07-03 07:00:14]   info:[ https://www.360.cn ]
[2020-07-03 07:00:14]   info:[ http://www.sina.com?from=1593759614 ]
[2020-07-03 07:00:14]   info:[ https://www.baidu.com?from=1593759614 ]

回到目录

我的主页

image

image

公众号及QQ群

image

image