在调用DB :: select时,为什么会出现"连接已重置"消息?

Dav*_*ogo 7 postgresql laravel laravel-5

在我的Laravel 5.5应用程序中,对Postgresql数据库运行select查询的DB :: select调用失败,而不显示Apache或Laravel错误日志中的任何错误,并触发"连接已重置"消息.此代码示例按预期运行,因为该函数get_users_with_roles存在.

public function missing_function(Request $request) {
        try{
           $all = DB::select('SELECT * from get_users_with_roles()', []);
        }catch(Illuminate\Database\QueryException $qe){
            return json_encode($qe->getMessage());
        }
        return json_encode($all);
}
Run Code Online (Sandbox Code Playgroud)

但是,如果我用不存在的函数替换该SQL字符串:

public function missing_function(Request $request) {
        try{
           $all = DB::select('SELECT * from test()', []);
        }catch(Illuminate\Database\QueryException $qe){
            return json_encode($qe->getMessage());
        }
        return json_encode($all);
}
Run Code Online (Sandbox Code Playgroud)

连接被重置,我在日志中看不到任何错误.如果我在本机Postgresql环境中运行此错误查询:

SELECT * from test();
Run Code Online (Sandbox Code Playgroud)

我收到一条明确的错误消息:

    ERROR:  function test() does not exist
LINE 1: select * from test()
                      ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
Run Code Online (Sandbox Code Playgroud)

这特别奇怪,因为这个问题并不一致.try块有时会捕获QueryException并将Postgresql错误消息显示为例外.

我试过添加

php_flag xcache.cacher Off 
php_flag xcache.size 0 
php_flag xcache.stat Off
Run Code Online (Sandbox Code Playgroud)

到.htaccess文件但无济于事.

我需要能够使用DB :: select方法,因为我在应用程序中严重依赖Postgresql用户定义的SQL和plpgsql函数.我有一个构造相关SQL的函数,并以编程方式将它传递给DB :: select方法,因此我需要能够捕获SQL中出现错误时抛出的异常,例如函数丢失时.

UPDATE

这个问题似乎与DB :: select处理任何SQL错误的方式有关.我刚用一个存在但抛出SQL错误的函数尝试了这个.同样,它不是允许我在PHP中使用try/catch块捕获它,而是重置连接并且不会在Laravel日志或Apache日志中记录错误.

这个问题没有任何启示.那里接受的答案是指预期的行为.在我的环境中,不会抛出或捕获QueryException.

bis*_*hop 4

其中棘手的部分是浏览器顽固地拒绝透露任何形式的错误消息。当发生这种情况时,我喜欢进入命令行并尝试它,从而消除 Web 服务器作为变量。

从聊天中,我们了解到命令行按预期显示了错误,但没有正常执行:输出了错误,并且脚本被停止。这是一场严重的崩溃,与网络服务器无关。

随着 的引入\Throwable,PHP死机的场景越来越少。因此,为了让 PHP 垂死挣扎,我们实现了一个register_shutdown_function方法error_get_last,试图找出在爆炸之前所说的内容(如果有的话)。

这简单地揭示了浏览器中的错误消息(这次使用不同的浏览器)。然而,这是不可重复的。此时的见解是缓存:composer dump-autoload解决了问题!

我怀疑发生的事情是这样的:

  • Eloquent抛出异常
  • PHP 通过 Laravel 的异常处理类将其冒泡
  • 在某些时候,PHP 尝试加载一个不在自动加载器中的类
  • PHP 严重崩溃(这是 PHP 7.0 崩溃的情况之一)

通过运行composer dump-autoload,所有“丢失”的类都被带入自动加载器的权限范围内,并且当再次尝试时,会出现正确的代码序列。