PHP oci_connect()卡住/没有超时

时间:2018-04-06 14:48:06

标签: php laravel lumen oci

我们正在使用Lumen 5.2.x(Laravel)应用程序从Oracle数据库获取数据。因此,我们使用oci_connect()连接到数据库。 (额外信息:我们使用Oracle instantclient)

由于某个未知原因,应用程序没有响应,也不会返回任何数据。经过大量的小时调试,我们发现它陷入了同样的方法:oci_connect()。显然,该功能没有返回“超时”消息或任何类似的消息。

后来,似乎数据库移动到另一台主机,这就是它无法连接的原因。但是,我们预计会出现错误,而不是大量的等待。

这就是我们试图强制设定超时的原因,直到现在还没有成功。

我们尝试过的事情:

  • 将此添加到连接字符串:(CONNECT_TIMEOUT=10)(RETRY_COUNT=3),完全被忽略。
  • max_execution_timeset_time_limit设为1
  • 使用设置添加sqlnet.ora

    TCP.CONNECT_TIMEOUT = 10

    SQLNET.INBOUND_CONNECT_TIMEOUT = 10

    SQLNET.OUTBOUND_CONNECT_TIMEOUT = 10

我们尝试的一切都失败了,有谁知道如何解决这个错误?任何帮助表示赞赏!

修改 : 系统信息: Windows Server 2012 R2,IIS 8,PHP 5.6

5 个答案:

答案 0 :(得分:3)

下面是用于oracle的laravel包,你可以试试这个,

laravel package for oracle

答案 1 :(得分:1)

我将oracle数据从oracle.php复制到了database.php配置文件中,问题已经消失。

我的oracle.php文件的内容:

return [
'oracle' => [
    'driver'   => 'oracle',
    'tns'      => env('DB_TNS', ''),
    'host'     => env('DB_HOST', 'localhost'),
    'port'     => env('DB_PORT', '1521'),
    'database' => env('DB_DATABASE', ''),
    'username' => env('DB_USERNAME', ''),
    'password' => env('DB_PASSWORD', ''),
    'charset'  => env('DB_CHARSET', 'AL32UTF8'),
    'prefix'   => env('DB_PREFIX', ''),
],
];

答案 2 :(得分:1)

不幸的是,oci_connect 已经是一个太高级的函数,无法允许超时控制 - OSI 模型第 5 层,如果您认为它可以为以下内容建立会话。我建议您在端口 1521,级别 4 上尝试 fsockopen,第 5 个参数以秒为单位设置超时。如果fsockopen()返回有效资源,则继续oci_connect(),否则报错/抛出异常。

我今天检查了它,这是在与各种远程站点建立四个 Oracle 连接时“预检评估”的一部分。超时秒后它实际上放弃了!

答案 3 :(得分:0)

你尝试了几种方法,这很棒。 max_execution_time是个好人。您可以注册关闭功能,以便您可以记录错误 - 或者做任何您需要的事情。

<?php 
function shutdown(){ 
     $error=error_get_last(); 
     if(is_null($error))   
         echo "No errors"; //or do nothing
     else 
         print_r($a); //or log it properly

 } 

register_shutdown_function('shutdown'); 

ini_set('max_execution_time',3 );//max 3 seconds

sleep(5); //just for test it out

在任何情况下,根据网站(例如:"don't loose your head, move to Linux"),您应该尝试使用Linux在使用Oracle连接时运行您的网络服务器,如果可能的话< / em>的)。

(我知道,在某些时候,Linux和Windows People之间存在很大的争议。但如果操作系统更适合某些用例,为什么还要使用其他用例呢)

答案 4 :(得分:0)

来自文档:

&#34;从PHP访问时,Oracle有时不会清理影子进程。为避免这种情况,请检查您的 Oracle Client目录中的$ ORACLE_HOME / network / admin / tnsnames.ora文件,如果已设置,则删除(SERVER = DEDICATED)标记。

要让Oracle在超时时删除影子进程,请在$ ORACLE_HOME / network / admin / sqlnet.ora中添加以下行 在您的ORACLE Server目录中找到:

SQLNET.EXPIRE_TIME = n

哪里&#39; n&#39;是连接空闲的分钟数,用于关闭它们。&#34;

你们有没有试过这个?