1

これが私がこれまでに持っているものです、私は日付/時刻ログをxmlファイルに追加したいと思います。

   <?php

       // Load the XML file we want to write to
          $visitors  = simplexml_load_file("data.xml");

       // Set e-mail xml search
          $search_id = htmlentities($_POST['email']);
          $visitors = $visitors->xpath("visitor[email='$search_id']");

       // If we have a search result, email already exists in xml file
          if(isset($visitors[0])){
           $visitor = $visitors[0];
           $email = (string) $visitor->email;

           // ********** Need to add date/time for each visit here.
           // So, I guess I need to search for e-mail address, then append to it.
           // Help required here... and again below to confirm formatting for multiple
           // dates. 

          } else {
           $xml = simplexml_load_file("data.xml");
           $sxe = new SimpleXMLElement($xml->asXML());
           $search_id = preg_replace('/[^(\x20-\x7F)]*/','', $search_id);

            $visitor = $sxe->addChild("visitor");
            $visitor->addChild("email", $search_id);

            // ******** Not sure this is the correct xml formatting.  
               $date = $visitor->addChild('date');
               $date->addChild("email", date("Y-m-d H:i:s"));

           $sxe->asXML("data.xml");
          } // if(isset($visitors[0])){

       } // if(isset($data)){ ?>

生成する

<?xml version="1.0" encoding="utf-8"?>
<visitors>
 <visitor>
  <email>jon.doe@aol.com</email>
  </visitor>
</visitors>

私がやりたいのは、訪問ごとに日付ログ(増分/追加)を追加することです。

したがって、結果は次のようになります(フォーマットが正しいかどうかはわかりませんが、もちろん問題にはなりません)。日付/時刻のPHPについて心配する必要はありません。

<?xml version="1.0" encoding="utf-8"?>
<visitors>
 <visitor>
  <email>jon.doe@aol.com</email>
  <date>2012-11-01 11:00:00</date>
  <date>2012-11-02 14:00:00</date>
  </visitor>
</visitors>
4

2 に答える 2

3

ここでは正しい方向に進んでいると思います。主なことは、asXML('data.xml')の呼び出しがELSEブロック内にあるため、ファイルが最初から作成されている場合(つまり、ファイルがファイルに書き込まれる場合のみ)です。 search_idが見つかりません)。

主にフォローしやすくするために、いくつかの変更を加えました。今後のさらなる変更!:

<?php

// Load the XML file we want to write to
$xmlFile  = simplexml_load_file("data.xml");

// Set e-mail xml search
$search_id = 'jon.doe@aol.com';
$results = $xmlFile->xpath("visitor[email='$search_id']");

// If we have a search result, email already exists in xml file
if(isset($results[0]))
{
    $visitor = $results[0];
    $email = (string) $visitor->email;

    echo "Found Email: " . $email . "\n";
    echo "Date: " . $visitor->date . "\n";
    // ********** Need to add date/time for each visit here.
    // So, I guess I need to search for e-mail address, then append to it.
    // Help required here... and again below to confirm formatting for multiple
    // dates.
    echo "Adding new date";
    $visitor->addChild('date', date('Y-m-d H:i:s'));

    echo "New XML: " . $xmlFile->asXML();

    $xmlFile->asXML('data.xml');

} else {
    $sxe = new SimpleXMLElement($xmlFile->asXML());
    $search_id = preg_replace('/[^(\x20-\x7F)]*/','', $search_id);

    $visitor = $sxe->addChild("visitor");
    $visitor->addChild("email", $search_id);

    // ******** Not sure this is the correct xml formatting.
    $date = $visitor->addChild('date', date('Y-m-d H:i:s'));

    $sxe->asXML("data.xml");

}
?>

このスクリプトを数回実行した後、次のようになりました。

<?xml version="1.0"?>
<visitors>
        <visitor>
                <email>jon.doe@aol.com</email>
                <date>2012-11-03 02:13:28</date>
                <date>2012-11-03 02:20:20</date>
                <date>2012-11-03 02:22:07</date>
                <date>2012-11-03 02:22:10</date>
                <date>2012-11-03 02:22:13</date>
        </visitor>
</visitors>

どちらが欲しいと思いますか?これは役に立ちますか?

編集:

それが正しいXML形式であるかどうかについてのあなたの言及に関して。排他的な正解はないと思います。個々の電子メールアドレス/日付のセットをそれぞれの訪問者タグで区切ることを忘れない限り、この形式は問題ないと思います。

それを行うには、おそらくそのようなものが必要になるでしょう(テストされていません):

$newVisitor = $xmlFile->addChild('visitor');
$newVisitor->addChild('email', $newEmail);
$newVisotor->addChild('date', $newDate);
$xmlFile->asXML('data.xml');

編集2:

私が過去に使用した最後の1つは、次のコードです。XMLをより適切にフォーマットし、保存中に問題が発生した場合(または少なくともバックアップを提供する場合)に元のXMLファイルの破損を防ぎます。個人的には、ファイルに書き込むときはいつでも、このような一時ファイルを使用する習慣をつけています。

もちろん、これを追加してから、次の呼び出しを置き換えます。

  • $ xmlFile-> asXML('data.xml');
  • $ sxe-> asXML( "data.xml");

と:

  • writeXML('data.xml'、$ xmlFile);
  • writeXML('data.xml'、$ sxe);

そして、それはうまくいくはずです。

//Writes final version of the SimpleXML object to file.
//Includes writing to a temp file for safety.
//This way is safer because if the code crashes mid-write it won't garble the original file.
function writeXML($fileName, $xmlObject)
{
        //Sanity check before copy, prevent any visible errors:
        if (file_exists($fileName))
                copy($fileName, $fileName . '.backup');

        //Write to temp file first in-case something kills the write; don't want to corrupt the original.
        $tmpName = $fileName . '~$.' . microtime();
        $handle = fopen($tmpName, 'w');
        fwrite($handle, formatXML($xmlObject));
        fclose($handle);
        copy($tmpName, $fileName);
        unlink($tmpName);
}

//asXML does no indentation formatting, so we'll do it here instead. This is called by WriteXML so that we're writing formatted XML to file.
function formatXML($xmlObject)
{
        $dom = new DOMDocument('1.0');
        $dom->preserveWhiteSpace = false;
        $dom->formatOutput = true;
        $dom->loadXML($xmlObject->asXML());
        return $dom->saveXML();
}
于 2012-11-02T15:26:18.643 に答える
1

これは@Geekmansの回答への追加です

あなたのコードはあまり遠くに見えません。ただし、大幅に改善できるため、ここに別の回答を追加してください(通常、@ Geekmansの回答を編集していましたが、すでに非常に大きいです)。

改善点はプログラムフローにあります。メールが見つからない場合は、新しい要素SimpleXMLElementを作成する必要はありません。新しい要素を作成するだけで済みます<visitor><date>次に、要素の追加とファイルの出力は、どちらの場合も実際には同じです。これにより、重複するコードを削除できます。

// Specify the XML file we want to write to
$inFile = "data.xml";

// Set e-mail xml search and insert id
$search_id = 'jon.doe@aol.com';
$insert_id = preg_replace('/[^(\x20-\x7F)]*/', '', $search_id);

// Load the XML file we want to write to
$xmlFile = simplexml_load_file($inFile);
$results = $xmlFile->xpath("visitor[email='$search_id']");

// If we have a search result, email already exists in xml file
if ($results) {
    $visitor = $results[0];
    echo "Found Visitor: ", $visitor->email, "\n",
    "First Date: ", $visitor->date, "\n";
} else {
    echo "Adding new Visitor: ", $insert_id, "\n";
    $visitor = $xmlFile->addChild("visitor");
    $visitor->addChild("email", $insert_id);
}

echo "Adding new Date: ", $date = date('Y-m-d H:i:s'), "\n";
$visitor->addChild('date', $date);

echo "Changed XML: \n" . simplexml_pretty_print($xmlFile);
$xmlFile->asXML($inFile);


/**
 * @param SimpleXMLElement $simplexml
 * @link https://stackoverflow.com/a/798986/367456
 */
function simplexml_pretty_print(SimpleXMLElement $simplexml) {
    $dom                     = new DOMDocument();
    $dom->preserveWhiteSpace = false;
    $dom->formatOutput       = true;
    $dom->loadXML($simplexml->asXML());
    return $dom->saveXML();
}

ボーナスとしてsimplexml_pretty_print、より良い方法で出力する機能を追加しました。

の出力jon.doe@aol.com

Found Visitor: jon.doe@aol.com
First Date: 2012-11-01 11:00:00
Adding new Date: 2012-11-03 10:48:05
Changed XML: 
<?xml version="1.0" encoding="utf-8"?>
<visitors>
  <visitor>
    <email>jon.doe@aol.com</email>
    <date>2012-11-01 11:00:00</date>
    <date>2012-11-02 14:00:00</date>
    <date>2012-11-03 10:48:05</date>
  </visitor>
</visitors>

の出力info@example.com

Adding new Visitor: info@example.com
Adding new Date: 2012-11-03 10:52:09
Changed XML: 
<?xml version="1.0" encoding="utf-8"?>
<visitors>
  <visitor>
    <email>jon.doe@aol.com</email>
    <date>2012-11-01 11:00:00</date>
    <date>2012-11-02 14:00:00</date>
  </visitor>
  <visitor>
    <email>info@example.com</email>
    <date>2012-11-03 10:52:09</date>
  </visitor>
</visitors>

ヒント:重複するコードを見つけた場合は、それをはるかに単純な形式で記述する方法がよくあります。

于 2012-11-03T09:53:23.980 に答える