简体   繁体   English

为什么这个PHP代码挂起调用mysql_query()?

[英]Why does this PHP code hang on calls to mysql_query()?

I'm having trouble with this PHP script where I get the error 我遇到了这个PHP脚本的问题,我得到了错误

Fatal error : Maximum execution time of 30 seconds exceeded in /var/www/vhosts/richmondcondo411.com/httpdocs/places.php on line 77 致命错误 :第77/var/www/vhosts/richmondcondo411.com/httpdocs/places.php超过30秒的最长执行时间

The code hangs here: 代码挂在这里:

function getLocationsFromTable($table){

    $query = "SELECT * FROM `$table`";
    if( ! $queryResult = mysql_query($query)) return null;

    return mysql_fetch_array($queryResult, MYSQL_ASSOC);

}

and here (so far): 在这里(到目前为止):

function hasCoordinates($houseNumber, $streetName){

    $query = "SELECT lat,lng FROM geocache WHERE House = '$houseNumber' AND StreetName = '$streetName'";
    $row = mysql_fetch_array(mysql_query($query), MYSQL_ASSOC);
    return ($row) ? true : false;

}

both on the line with the mysql_query() call. 两者都在mysql_query()调用的行上。

I know I use different styles for each code snippet, it's because I've been playing with the first one trying to isolate the issue. 我知道我为每个代码片段使用不同的样式,这是因为我一直在玩第一个尝试隔离问题的代码片段。

The $table in the first example is 'school' which is a table which definitely exists. 第一个例子中的$table是'school',它是一个绝对存在的表。 I just don't know why it sits there and waits to time out instead of throwing an error back at me. 我只是不知道为什么它坐在那里等待超时而不是向我抛出错误。

The mysql queries from the rest of the site are working properly. 来自网站其余部分的mysql查询工作正常。 I tried making sure I was connected like this 我试着确保我这样连接

//connection was opened like this:
//$GLOBALS['dbh']=mysql_connect ($db_host, $db_user, $db_pswd) or die ('I cannot connect to the database because: ' . mysql_error());

if( ! $GLOBALS['dbh']) return null;

and it made it past that fine. 它让它过去那么好。 Any ideas? 有任何想法吗?

Update 更新


It's not the size of the tables. 这不是桌子的大小。 I tried getting only five records and it still timed out. 我尝试只获得五个记录,但它仍然超时。 Also, with this line: 另外,用这一行:

$query = "SELECT lat,lng FROM geocache WHERE House = '$houseNumber' AND StreetName = '$streetName'";

it is only looking for one specific record and this is where it's hanging now. 它只是寻找一个特定的记录,这就是它现在悬挂的地方。

It sounds like MySQL is busy transmitting valid data back to PHP, but there's so much of it that there isn't time to finish the process before Apache shuts down the PHP process for exceeding its maximum execution time. 听起来MySQL正在忙着将有效数据传回PHP,但是在Apache关闭PHP进程超过其最大执行时间之前,没有时间完成这个过程。

Is it really necessary to select everything from that table? 是否真的有必要从该表中选择所有内容 How much data is it? 它有多少数据? Are there BLOB or TEXT columns that would account for particular lag? BLOBTEXT列是否会导致特定滞后?

Analyzing what's being selected and what you really need would be a good place to start. 分析正在选择的内容以及您真正需要的内容将是一个很好的起点。

Time spent waiting for mysql queries to return data does not count towards the execution time. 等待mysql查询返回数据所花费的时间不计入执行时间。 See here. 看这里。

The problem is most likely somewhere else in the code - the functions that you are blaming are possibly called in an infinite loop. 问题很可能在代码中的其他地方 - 你所指责的函数可能在无限循环中被调用。 Try commenting out the mysql code to see if I'm right. 尝试注释掉mysql代码,看看我是否正确。

Does your code timeout trying to connect or does it connect and hang on the query? 您的代码是否超时尝试连接或连接并挂起查询?

If your code actually gets past the mysql_query call (even if it has to wait a long time to timeout) then you can use the mysql_error function to determine what happened: 如果您的代码实际上超过了mysql_query调用(即使它必须等待很长时间才能超时),那么您可以使用mysql_error函数来确定发生了什么:

mysql_query("SELECT * FROM table");
echo mysql_errno($GLOBALS['dbh']) . ": " . mysql_error($GLOBALS['dbh']) . "\n";

Then, you can use the error number to determine the detailed reason for the error: MySQL error codes 然后,您可以使用错误号来确定错误的详细原因: MySQL错误代码

If your code is hanging on the query, you might try describing and running the query in a mysql command line client to see if it's a data size issue. 如果您的代码挂在查询上,您可以尝试在mysql命令行客户端中描述和运行查询,以查看它是否是数据大小问题。 You can also increase the maximum execution time to allow the query to complete and see what's happening: 您还可以增加最长执行时间以允许查询完成并查看发生的情况:

ini_set('max_execution_time', 300); // Allow 5 minutes for execution

I don't know about the size of your table, but try using LIMIT 10 and see if still hangs. 我不知道你的桌子的大小,但尝试使用LIMIT 10 ,看看是否仍然挂起。

It might be that your table is just to big to fetch it in one query. 可能是您的表只是在一个查询中获取它。

Unless the parameters $houseNumber and $streetName for hasCoordinates() are already sanitized for the MySQL query (very unlikely) you need to treat them with mysql_real_escape_string() to prevent (intentional or unintentional) sql injections. 除非hasQordinates()的参数$ houseNumber和$ streetName已经为MySQL查询清理(非常不可能),否则你需要使用mysql_real_escape_string()处理它们以防止(有意或无意)sql注入。 For mysql_real_escape_string() to work properly (eg if you have changed the charset via mysql_set_charset ) you should also pass the MySQL connection resource to the function. 要使mysql_real_escape_string()正常工作(例如,如果您通过mysql_set_charset更改了charset),您还应该将MySQL连接资源传递给该函数。

Is the error reporting set to E_ALL and do you look at the error.log of the webserver (or have set display_erorrs=On)? 错误报告是否设置为E_ALL,您是否查看了网络服务器的error.log(或设置了display_erorrs = On)?

Try this 尝试这个

function hasCoordinates($houseNumber, $streetName) {
  $houseNumber = mysql_real_escape_string($houseNumber);
  $streetName = mysql_real_escape_string($streetName);
  $query = "
    EXPLAIN SELECT
      lat,lng
    FROM
      geocache
    WHERE
      House='$houseNumber'
      AND StreetName='$streetName'
  ";
  $result = mysql_query($query) or die(mysql_error());
  while ( false!==($row=mysql_fetch_array($result, MYSQL_ASSOC)) ) {
    echo htmlspecialchars(join(' | ', $row)), "<br />\n";
  }
  die;
}

and refer to http://dev.mysql.com/doc/refman/5.0/en/using-explain.html to interpret the output. 并参考http://dev.mysql.com/doc/refman/5.0/en/using-explain.html来解释输出。

-If you upped the execution time to 300 and it still went through that 300 seconds, I think that by definition you've got something like an infinite loop going. - 如果你将执行时间提高到300并且它仍然经历了300秒,我认为根据定义,你会得到类似无限循环的东西。

-My first suspect would be your php code since mysql is used to dealing with large sets of data, so definitely make sure that you're actually reaching the mysql query in question (die right before it with an error message or something). - 我首先怀疑是你的php代码,因为mysql用于处理大量数据集,所以一定要确保你实际上已经到达了有问题的mysql查询(在它之前死了,带有错误信息或其他东西)。

-If that works, then try actually running that query with known data on your database via some database gui or via the command line access to the database if you have that, or replacing the code with known good numbers if you don't. - 如果有效,那么尝试通过某些数据库gui或通过命令行访问数据库实际运行数据库中的已知数据(如果有的话),或者如果不这样,则用已知的良好数字替换代码。

-If the query works on it's own, then I would check for accidental sql injection coming from with the $houseNumber or $streetName variables, as VolkerK mentioned. - 如果查询是自己的,那么我会检查来自$ houseNumber或$ streetName变量的意外sql注入,如VolkerK所述。

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

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