简体   繁体   English

PHP / MSSQL 连接故障排除

[英]Troubleshoot PHP / MSSQL connection

I have php script that is sending values given to it to an MSSQL database.我有 php 脚本,它将给它的值发送到 MSSQL 数据库。 It works about 70% of the time (there should be ~100 records, I'll see ~70).它大约有 70% 的时间有效(应该有大约 100 条记录,我会看到大约 70 条记录)。 There is no pattern, that I can see.没有模式,我可以看到。 I am not looking for help going over the logs I already have;我不是在寻求帮助查看我已经拥有的日志; I need to know where I should look to find errors.我需要知道我应该在哪里寻找错误。 The php is simple, using mssql_query, mssql_num_rows, and mssql_fetch_array. php 很简单,使用 mssql_query、mssql_num_rows 和 mssql_fetch_array。 Timeout in php.ini has not changed from default 60s, although I have just now set it to 240s (if this fixes everything, I will update the post). php.ini 中的超时没有从默认的 60 秒更改,尽管我刚刚将其设置为 240 秒(如果这可以解决所有问题,我将更新帖子)。 I am not able to return anything once the script has been called;调用脚本后,我无法返回任何内容; every response, whether there is an error or not, must be the same.每个响应,无论是否有错误,都必须相同。 Can I somehow log details of the mssql_query function?我可以以某种方式记录 mssql_query function 的详细信息吗? Or is there a response from the SQL server I can listen for?或者是否有来自我可以收听的 SQL 服务器的响应? I've read the manual and havent seen anything like this.我已经阅读了手册,并没有看到类似的东西。 Any help would be appreciated.任何帮助,将不胜感激。 I need this taken care of asap.我需要尽快解决这个问题。

edit - I can't run mssql_showlastmessage, because I can't return anything but, as things will break.编辑 - 我无法运行 mssql_showlastmessage,因为我不能返回任何东西,因为事情会中断。 Below is the entire code.下面是整个代码。

<?php
//request xml cdr from switchvox
error_reporting(E_ALL);

//include switchvox libraries
require_once("SwitchvoxRequest.php");

//define sql connection stuff
$db_host = "dbhost";
$db_user = "dbuser";
$db_pass = "dbsecret";
$db = "db";
$table_sr = "tblsr";
$table_cd = "tblcmrd";
$link = mssql_connect($db_host, $db_user, $db_pass);
$err = "";

//make sure we can connect
if (!$link || !mssql_select_db($db, $link))
        {
            die("<response></response>");
        }

//define pbx connection stuff
$sv_host = "pbx";
$sv_user = "user";
$sv_pass = "secret";

//get the extension from the pbx and format it
$ext = $_GET['ext'];
$ext2 = $_GET['ext2'];
$jobid = $_GET['jobid'];
$et = $_GET['et'];

if(!$ext2)
        {
        $ext = substr($ext,-4,4);
        }

if(strlen($ext) > 4)
        {
        if(strlen($ext2) > 4)
                {
                die("<response></response>");
                }
        $ext = $ext2;
        }

//query the sr table to find the account ID of the extension we are referencing
$acid_sql = "SELECT * FROM $table_sr WHERE ext=$ext";
$acid_res = mssql_query($acid_sql);
$acida = mssql_fetch_array($acid_res, MSSQL_BOTH);
$acid = $acida['pbx_accountid'];

if (!$acid_res) 
        {
            die("<response></response>");
        }

//make sure there is a salesrep for the extension making the call
if (!$acid)
        {
            die("<response></response>");
        }

//get and format the time and date as YYYY-MM-DD
$date = date('Y') . "-" . date('m') . "-" . date('d');

//format the time as HH:MM:SS
$time = date('H') . ":" . date('i') . ":" . date('s');

//create a new request
$req = new SwitchvoxRequest($sv_host, $sv_user, $sv_pass);
$reqpar = array
        (
        'account_ids' => array
                (
                'account_id' => array
                        (
                        $acid
                        )
                ),
            'start_date' => array
                (
                $date . " " . "00:00:00"
                ),
        'end_date' =>  array
                (
                $date . " " . $time
                ),
        'sort_field' => array
                (
                ),
        'sort_order' => array
                (
                'DESC'
                )
        );
$res = $req -> send("switchvox.callLogs.search", $reqpar);
$result = $res->getResult();
$calls = $result['calls']['total_items'];

//check that there were calls to/from this account today
if(!$calls)
        {
        die("<response></response>");
        }

$latest = $result['calls']['call']['0'];
$callid = $latest['id'];

//check to see if the call has already been logged
$id_sql = "SELECT * FROM $table_cd WHERE callID='$callid'";
$id_res = mssql_query($id_sql);
$exid = mssql_fetch_array($id_res, MSSQL_ASSOC);

if (!$id_res) 
        {
    die("<response></response>");
        }

if($exid['callID'])
        {
        die("<response></response>");
        }

//define variables to be sent to the table
$from = $latest['from_number'];
$to = $latest['to_number'];
$durat = $latest['talk_duration'];
$start = $latest['start_time'];
$callid = $latest['id'];
$calltype = $latest['origination'];

//check the length of the cid/ext strings and swap if needed
if (strlen($from) > strlen($to))
        {
        $extension = $to;
        $phonenumber = $from;
        }
        else
        {
        $extension = $from;
        $phonenumber = $to;
        }

//insert the data into the table
$fi_sql = "INSERT INTO $table_cd (extension, phonenumber, calldatetime, duration, callID, calltype)     VALUES ($extension, $phonenumber, '$start', '$durat', '$callid', '$calltype')";
$fi_res = mssql_query($fi_sql);

if (!$fi_res) 
{
    die("<response></response>");
}

$sv_res = "<response></response>";

echo $sv_res;
?>

I realize this is open to sql injections.我意识到这对 sql 注射开放。 That's ok.没关系。

edit -编辑 -

I looked through the logs on the database;我查看了数据库上的日志; there are no errors for when I would expect there to have been data inserted, nothing even indicating that it tried.当我期望插入数据时没有错误,甚至没有表明它尝试过。 I am going to look at something that will log messages to syslog or something from php.我将看一些将消息记录到 syslog 或来自 php 的东西。 suggestions are welcome.欢迎提出建议。

In general, you are free to execute this on MySQL一般来说,您可以在 MySQL 上自由执行此操作

EXPLAIN SELECT ...

to get a description of a SELECT statement .获取SELECT 语句的描述 This feature basically explains, how MySQL's query analyzer sees your query and how it would be executed.此功能基本上解释了 MySQL 的查询分析器如何查看您的查询以及如何执行它。 For example, EXPLAIN describes, if MySQL is about to perform costly table-scans or may use an index and if so, which one.例如, EXPLAIN描述了,如果 MySQL 即将执行昂贵的表扫描,或者可能使用索引,如果是,那么是哪一个。

Are you sure, that MySQL is causing the problem?您确定是 MySQL 导致了问题吗? Or might PHP force problems?或者 PHP 可能会出现问题?

Do you check mysql_error() after each query?你在每次查询后检查mysql_error()吗?

Is $ext probably not numeric? $ext 可能不是数字吗? In this case, $ext should get quoted (sorry, don't like variable substitution inside of string):在这种情况下, $ext 应该被引用(对不起,不喜欢字符串内的变量替换):

$acid_sql = "SELECT * FROM " .  $table_sr . " WHERE ext='" . $ext . "'";

Since you return XML and if the client of this routine behaves well, why not insert a new element inside of response like this:既然您返回 XML 并且如果此例程的客户端表现良好,为什么不在响应中插入一个新元素,如下所示:

<response>
   ... other elements ...
  <sysInfo>
    Failed to perform...
  </sysInfo>
</response>

A well-behaving XML client should only read known elements and thus skip additional elements.表现良好的 XML 客户端应该只读取已知元素,从而跳过其他元素。 Adding such a logic return code always useful.添加这样的逻辑返回码总是有用的。

PS: Although the above code might just be a sample, let me remark, that it is attackable by sql-injections . PS:虽然上面的代码可能只是一个示例,让我说一下,它可以被sql-injections攻击。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM