laravel/lumen 使用技巧

获取目录

storage_path();
base_path();
app_path();
public_path();

异常响应

有两种异常处理方式:

  • 以 json 形式返回的 Restful 接口结果
  • 以 html 页面形式返回结果

异常响应入口:app/Exceptions/Handler.php
对异常的输出是在 render 方法中实现:

// 默认的实现
public function render($request, Throwable $exception)
{
    return parent::render($request, $exception);
}

增强的逻辑就是在 render 里将响应逻辑分流:

public function render($request, Throwable $exception)
{
    if ($this->shouldRenderAsHtml($exception)) {
        return $this->renderAsHtml($request, $exception);
    }
    else {
        return $this->renderAsJson($request, $exception);
    }
}

protected function shouldRenderAsHtml(Throwable $e)
{
    switch (true) {
    case $e instanceof UserNotLoginException:
        return true;
    default:
        return false;
    }
}

添加额外的 PDO 初始化参数

config/database.php 中,增加 options 项,配置 PDO 初始化的数值。

return [
    'default' => 'demo',
    'connections' => [
        'demo' => [
            'driver' => 'mysql',
            'options' => [
                PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
                PDO::ATTR_CASE               => PDO::CASE_LOWER,
                PDO::ATTR_ORACLE_NULLS       => PDO::NULL_TO_STRING,
                PDO::ATTR_EMULATE_PREPARES   => false,
            ] 
        ],
    ],
];

特别注意:PDO::ATTR_DEFAULT_FETCH_MODE 在这里设置是无效的,laravel 会重置这个属性,正确的修改方式请参考以下的章节「让数据库查询结果返回数组」。

让数据库查询结果返回数组

laravel 数据库查询结果默认是 stdClass 类型,并且在 connection 创建时,会主动设置为 PDO::FETCH_OBJ。
这个行为会覆盖 config/database.php 中 'options' => [PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC] 的设置。
唯一可行的方式是 listen Illuminate\Database\Events\StatementPrepared 事件,在 event handler 中再把 fetch mode 给置回 FETCH_ASSOC:

use PDO;
use Illuminate\Support\Facades\Event;
use Illuminate\Database\Events\StatementPrepared;

class EventServiceProvider extends ServiceProvider
{
    public function register()
    {
        Event::listen(StatementPrepared::class, function ($event) {
            $event->statement->setFetchMode(PDO::FETCH_ASSOC);
        });
    }
}

特别注意 use StatementPrepared, 这里就算不 use,php 也不会报错,但是注册到 dispatcher 里的 event name 就不对了,导致真正的事件响应不到。

最后别忘记在 boostrap/app.php 中注册 EventServiceProvider:

$app->register(App\Providers\EventServiceProvider::class);

单元测试

测试库只在开发时才会 autoload, 配置类型要放在 autoload-dev 下

"autoload": {
      ......
},
"autoload-dev": {
    "psr-4": {
        "Workhours\\Tests\\": "tests/"
    }
},
posted @ 2022-04-05 11:37  汽酒吧  阅读(176)  评论(0)    收藏  举报