XML文件似乎是随机破坏的,无法弄清楚

时间:2013-01-04 10:14:10

标签: php xml simplexml

我在wordpress网站上使用了一个xml文件,每次有人查看帖子时都会使用帖子ID进行更新。

文件结构如下所示......

  <?xml version="1.0"?>
  <posts>
     <refresh>
        <datetime>2013-01-04 08:48:21</datetime>
     </refresh>
     <post id="21931">
        <postviews>5</postviews>
     </post>
     <post id="25420">
        <postviews>18</postviews>
     </post>
     <post id="17770">
        <postviews>25</postviews>
     </post>
     <post id="24925">
        <postviews>4</postviews>
     </post>
  </posts>

如果有人查看帖子,如果帖子ID不在文件中,则会添加新节点,如果存在,则将当前值更新为1.

我遇到的问题是,有时文件没有被正确写入,并且最终被破坏并且看起来如下(错误始终位于文件的底部)...

  <?xml version="1.0"?>
  <posts>
     <refresh>
        <datetime>2013-01-04 08:48:21</datetime>
     </refresh>
     <post id="21931">
        <postviews>5</postviews>
     </post>
     <post id="25420">
        <postviews>18</postviews>
     </post>
     <post id="17770">
        <postviews>25</postviews>
     </post>
   </posts>         
   id="24925">
        <postviews>4</postviews>
     </post>
  </posts>

我已经与我们的托管公司进行了交谈,但问题并未显示为服务器错误。我的脚本写入XML文件会有问题吗?我写的剧本如下......

<?php

 // echo get_the_ID();

if($post->post_status != "publish" || is_user_logged_in()) { 

    //Get the wordpress postID
$postID = get_the_ID();

$postData = get_post($postID);  

// Don't do anything if the post isn't published or being viewed by logged in users - will give a false impression
// echo $postID.'<br />'.$postData->post_title.'<br />'.$postData->post_date_gmt.'<br />';

} else { 

//Get the wordpress postID
$postID = get_the_ID();

$postData = get_post($postID);  

// echo $postID.'<br />'.$postData->post_title.'<br />'.$postData->post_date_gmt.'<br />';

$xmlFile = get_stylesheet_directory().'/most-read/most-read-posts.xml';

// load the document
$xml = simplexml_load_file($xmlFile);


// Get the server time
$serverTime = date('Y-m-d H:i:s');

// Is their a refresh node with an entry of datetime?
$refreshNodeExists = $xml->xpath("//refresh");

// Count it if 
$countrefreshNodeExists = count($refreshNodeExists);

// If it does exists
if($countrefreshNodeExists != 0) { // If the ID is already in the file

    $xmlRefresh = $xml->refresh->datetime;

    // echo 'Refresh time is already set<br /><br />';

} else {

    // echo 'Refresh time is not set<br /><br />';

    $refreshNode = $xml->addChild('refresh');

    $refreshNode->addChild('datetime', $serverTime);

}

// Check the time elapsed between the server time and the refreshNode

// Get and format the refreshNode
$to_time = strtotime($xmlRefresh);

// Get and format the server time
$from_time = strtotime($serverTime);

// Calculate the time elapsed
$refreshTimeElapsed = round(abs($to_time - $from_time) / 60,2);

// How long do we want to have between file refreshing - in minutes?
$refreshInterval = 120;

// Check if the time elapsed is more or less than $refreshInterval
if ($refreshTimeElapsed > $refreshInterval) {

    // FOR TESTING ONLY - Show the time elapsed
    // echo 'Ooops were over the refresh limit. It\'s currently at: '.$refreshTimeElapsed.' minutes.<br /><br />';

    $fh = fopen($xmlFile, 'w') or die("can't open file");

    $stringData = '<?xml version="1.0"?><posts><refresh><datetime>'.date('Y-m-d H:i:s').'</datetime></refresh></posts>';

    fwrite($fh, $stringData);

    fclose($fh);

                /*$test = $xml->xpath("//post");

                if (!empty($test)) {

                    echo 'Houston, we have posts';

                } else {

                    echo 'That\'s a negative Houston, we have no posts here';

                }*/

    // Reset the datetime node with the current datetime to start the refresh loop again.
    $xml->refresh->datetime = date('Y-m-d H:i:s');

} else { // Don't need to do anything here really

    // FOR TESTING ONLY - show how much time has elapsed
    // echo 'No need to change the refresh node. It\'s only at '.$refreshTimeElapsed.' minutes.<br /><br />';

    // Check to see if the post id is already in the xml file - has it already been set?
    $nodeExists = $xml->xpath("//post[@id=".$postID."]");

    //Count the results
    $countNodeExists = count($nodeExists);

    if($countNodeExists > 0) { // If the ID is already in the file

        // echo 'ID already here';

        // get the correct node
        $result = $xml->xpath("//post[@id=".$postID."]/postviews");

        // heres the trick - the first result of xpath, and the node value (stored in [0])
        $result[0][0] = $result[0][0]+1;

    } else { // If the ID isn;'t there, add a new entry in the xml file for the post

        //echo 'ID added';

        $postNode = $xml->addChild('post'); // adding a new <post> to the top level node
        $postNode->addAttribute('id', $postID); // adding a <postid> inside the new <post>
        $postNode->addChild('postviews', 1); // adding a postviews inside the new <post>
    }

    // save the updated document and format it using the DOMDocument class

    //$xml->asXML($xmlFile);
    $dom = new DOMDocument('1.0');
    $dom->preserveWhiteSpace = false;
    $dom->formatOutput = true;
    $dom->loadXML($xml->asXML());
    $dom->save($xmlFile);

} // End if ($refreshTimeElapsed > $refreshInterval) {

} // End if logged in or not published

?>

1 个答案:

答案 0 :(得分:0)

  

如果帖子ID不在文件中,每次有人查看帖子时   添加一个新节点,如果存在,则将当前值更新为1。

我愿意打赌这是由多个同时执行引起的。您是否锁定对该文件的访问权限?如果两个人同时查看帖子会怎样?

我认为(长期而言)您最好将此信息存储在数据库或类似数据库中。我不认为写一个通用的XML文件会扩展。