0

我有这个问题,cron 每 5 分钟运行一次 php 脚本来更新列表。

但是,列表有 5% 的时间无法更新,并且列表最终为空白。我不相信它与 cron 有关,因为我认为在 100 次尝试中我未能手动生成列表两次。

我认为这与网站上有 50 多人有关时,它将无法生成,可能与服务器繁忙有关。我添加了一个检查以确保不是 MySQL 没有返回行(这似乎是不可能的),但它仍然让我相信 fwrite 失败了。

<?      
$fileHandle = fopen("latest.html", 'w');
    $links = array();   

$query1 = $db_conn -> query("SELECT * FROM `views` ORDER BY `date` DESC LIMIT 0,20");
while ($result1 = $db_conn -> fetch_row($query1))
{
    $result2 = $db_conn -> fetch_query("SELECT * FROM `title` WHERE `id` = '" . $result1['id'] . "'");

    array_push($links, "<a href='/title/" . $result2['title'] . "'>" . $result2['title'] . "</a>");
}

if (count($links) > 0)
    fwrite($fileHandle, implode(" • ", $links));
else
    echo "Didn't work!";    

fclose($fileHandle);
?>

该文件是否有可能正在使用中,因此最终无法正常工作并写入空白列表?

4

3 回答 3

1

$fileHandle = "latest.html", 'w');

我假设你的意思是

$fileHandle = fopen("latest.html", 'w');

这里的“w”打开文件,将光标放在开头并将文件截断为零长度。

如果您在执行此操作之前检查 count($links),那么当没有任何内容可写入文件时,您将不会截断文件。

<?php
$links = "QUERY HERE AND HANDLE THE RESULTS (REMOVED)";  
if (count($links) > 0)
{  
    $fileHandle = fopen("latest.html", 'w');  
    fwrite($fileHandle, implode(" • ", $links));
    fclose($fileHandle);
}
else
{
    echo "Didn't work!";
}
?>
于 2012-04-16T17:59:01.723 回答
1

该文件是否有可能正在使用中,因此最终无法正常工作并写入空白列表?

嗯,是。我们不知道您运行了哪些其他代码来操作 latest.html,因此我们无法真正对其进行分析。

以下是一些建议:

  1. 修复文件处理程序创建中的语法错误
  2. 您可以获取 fopen('w') 处理程序来处理现有 fopen('r') 进程正在进行的文件,因此请确保在写入文件时使用 PHP 的,以确保其他进程不会破坏您的列表
  3. 检查您的日志必须说什么
  4. 写入一个字符串,然后 fwrite 整个字符串,因此您在打开文件处理程序的情况下在内部循环中花费的时间更少(特别是在这种情况下,字符串不会那么长 - 链接列表)
  5. 尝试将您的链接(带有日期标记)输出到除 latest.html 之外的单独文件;在失败的 5% 的机会中,回顾时间戳链接,看看它们是如何比较的。您还可以在该文件中包含您的查询,以便您可以隔离问题是否与数据库有关或与写入 latest.html 相关 - 这在您的查询(不是显示)可能不返回任何结果。
于 2012-04-16T18:05:49.740 回答
1

我认为您对查询不返回任何数据的可能性持开放态度。您示例中的“已删除”逻辑可能有助于阐明正在发生的事情。解决这个问题的一个好方法是将一些内容写入日志文件,并在脚本的几十次迭代后检查该日志文件。为了在您的 latest.html 文件中包含某些内容,我会在您当前的代码上使用 file_put_contents。

<?php

$links = array();
$query = "SELECT links FROM tableA";
$result = mysql_query($links);
while ($row = mysql_fetch_row($result)) {
    $links[] = $row[0];
}

if (count($links) > 0) {
    file_put_contents('latest.html', implode(" * ", $links));
    file_put_contents('linkupdate.log', "got links: " . count($links) . "\n", FILE_APPEND);
} else {
    file_put_contents('linkupdate.log', "No links? [(" . mysql_errno() . ") " . mysql_error() . "]\n", FILE_APPEND);
}

?>

如果我们没有找到链接,我们不会覆盖之前的数据文件。如果我们遇到可能导致问题的 MySQL 错误,它将显示在日志输出中。

对文件的读取不应阻止写入,但切换到 file_put_contents 将有助于减少文件打开和清空的时间(在执行查询和获取结果时存在一些延迟)。

随意匿名化您的查询并将其发布 - 您肯定会对结果集有问题,因为您的代码看起来应该可以工作。

于 2012-04-16T18:10:45.363 回答