2013-01-04 97 views
0

我有一個xml文件正在我們的wordpress網站上使用,每次有人查看帖子時都會使用帖子ID更新。XML文件似乎是隨機破壞,無法弄清楚

文件結構看起來像這樣...

<?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 

?> 
+0

這不是由於併發嗎?兩個(或更多)訪問者訪問一個帖子,從而同時寫入該文件?結束兩個(或更多)文件的一半。 –

回答

0

每當有人觀看後,如果帖子ID不是在文件中它 增加了一個新的節點,或者如果它存在,它更新由1的電流值。

我敢打賭,這是由多個同時執行造成的。你是否鎖定對該文件的訪問?如果兩個人同時查看帖子會發生什麼?

我認爲(更長期的),你會更好地將這些信息存儲在數據庫或類似的地方。我不認爲寫入一個通用的XML文件將會擴展。

+0

嗨Brian, 會鎖定文件短期解決問題。 我認爲你是對的,數據庫存儲將是更好的方式,但目前的XML文件工作正常,除了錯誤:-) –

相關問題