0

wordpress サイトで使用されている xml ファイルがあり、誰かが投稿を表示するたびに投稿 ID で更新されます。

ファイル構造は次のようになります…</p>

  <?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 ずつ更新されます。

私が抱えている問題は、時々ファイルが正しく書き込まれず、ファイルが破損して次のようになることです (エラーは常にファイルの最後にあります)…</p>

  <?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 ファイルに書き込むスクリプトの問題でしょうか? 私が書いたスクリプトは以下のとおりです…</p>

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

?>
4

1 に答える 1

0

投稿 ID がファイルにない場合、誰かが投稿を表示するたびに、新しいノードが追加されます。存在する場合は、現在の値が 1 ずつ更新されます。

これが複数の同時実行によって引き起こされていることは間違いありません。そのファイルへのアクセスをロックしていますか? 2 人のユーザーが同時に投稿を表示するとどうなりますか?

(長期的には) この情報をデータベースなどに保存したほうがよいと思います。一般的な XML ファイルへの書き込みが拡張されるとは思いません。

于 2013-01-04T10:16:50.607 に答える