<p><img src="https://img.php.cn/upload/article/000/887/227/169364887365792.jpg" alt="データ エクスポート: カスタマイズされたデータベース テーブル"></p>
<p>このシリーズの最初の記事で述べたように、カスタム データベース テーブルの主な問題の 1 つは、既存のインポートおよびエクスポート ハンドラーでは処理されないことです。この記事はこの問題に対処することを目的としていますが、現時点では完全に満足のいく解決策がないことに注意してください。 </p>
<p> 2 つの状況を考えてみましょう: </p>
<ol>
<li>カスタムテーブルはネイティブWordPressテーブルを参照します</li>
<li>カスタム テーブルはネイティブ テーブルから完全に独立しています</li>
</ol>
<p>「最悪のシナリオ」は最初のシナリオです。例として、ユーザーアクティビティログを保存するカスタムテーブルを考えてみましょう。ユーザー ID、オブジェクト ID、オブジェクト タイプを参照します。これらはすべて、ネイティブ WordPress テーブルに保存されているデータを参照します。ここで、誰かが WordPress Web サイトからすべてのデータを 2 番目の Web サイトにインポートしたいと考えていると想像してください。たとえば、投稿をインポートするときに、その ID を持つ投稿がすでに 2 番目のサイトに存在する可能性があるため、WordPress が新しい ID を割り当てる必要がある可能性は十分にあります。 </p>
<p>この場合、そのような変更を追跡し、テーブル内で参照される ID を更新する必要があります。これ自体はそれほど難しいことではありません。 <em>残念ながら</em>、他のWordPressサイトからのデータのインポートを処理するためのWordPress Importerプラグインには、これを実現するために必要なフックがありません。このコメントで示唆されているように、潜在的な回避策は、データをメタデータにも保存することです。残念ながら、これによりデータが重複し、データベースの正規化に違反します。一般的には良いアイデアではありません。結局のところ、実際に実現できるのはいくつかのユースケースのみです。 </p>
<p>2 番目のケースでは、この複雑さは回避されますが、それでもカスタムのインポートおよびエクスポート ハンドラーが必要です。この状況については、次の 2 つの記事で説明します。ただし、このシリーズの残りの部分との一貫性を保つために、これはケース (1) の例ではありますが、アクティビティ ログ テーブルをそのまま使用します。 </p>
<hr>
<h2>フォーマットを決定する</h2>
<p>まず、エクスポートするファイルの形式を決定する必要があります。最適な形式は、データの性質 (または「構造」) とその使用方法によって異なります。私の意見では、XML は 1 対多の関係を処理できるため、一般に優れています。ただし、データが表形式の場合、特にスプレッドシート アプリケーションとの統合が容易なため、CSV の方が好ましい場合があります。この例では XML を使用します。 </p>
<hr>
<h2>値上げ</h2>
<p>次のステップは、ユーザーがログ テーブルからデータをエクスポートできるようにする管理ページを作成することです。 「ツール」メニュー項目の下にページを追加するクラスを作成します。このページには、ユーザーにエクスポート ファイルのダウンロードを促すボタンのみが含まれています。このクラスは、フォームの送信をリッスンし、ファイルのダウンロードをトリガーするハンドラーも追加します。 </p>
<p>まずクラスの構造を見て、次にそのメソッドの詳細を埋めていきます。 </p>
リーリー
<p><code>WPTuts_Log_Export_Admin_Page::load()</code> クラスを初期化し、コールバックを適切な操作にフックします: </p>
<ul>
<li>
<code>add_submenu</code> – 「ツール」メニューにページを追加するメソッド。 </li>
<li>
<code>maybe_download</code> – このメソッドは、ダウンロード要求が送信されたかどうかをリッスンして確認します。これにより、権限と nonce もチェックされます。 </li>
</ul>
<p> これらのヘッダーは自分で設定するため、ヘッダーが送信される前にエクスポート リスナーを呼び出す必要があります。これを <code>init</code> にフックすることもできますが、管理ではエクスポート ファイルのダウンロードのみを許可しているため、ここでは <code>admin_init</code> の方が適切です。 </p>
<p>メニューにページを追加するのは簡単です。 「ツール」の下にページを追加するには、<code>add_management_page()</code> を呼び出すだけです。 </p>
リーリー
<p>ここで <code>$hook_suffix</code> は、ここで説明するさまざまな画面固有のフックに使用されるサフィックスです。ここでは使用しませんが、使用する場合は、その値をハードコーディングするよりも変数に格納することをお勧めします。 </p>
<p> 上記では、メソッド <code>display()</code> をページのコールバックとして設定し、それを定義します。
リーリー
</p>最後に、上記のフォームがいつ送信されるかを監視し、エクスポート ファイルのダウンロードをトリガーしたいと考えています。 <p>
リーリー
</p>残っているのは、.xml ファイルを作成して返す関数 <p>wptuts_export_logs()<code> を作成することだけです。 </code>
</p>
<hr>エクスポートファイルの作成<h2>
</h2>関数で最初に行うことは、ログを取得することです。存在する場合は、適切なヘッダーを設定し、XML 形式で出力する必要があります。ユーザーに XML ファイルをダウンロードしてもらいたいため、Content-Type を <p>text/xml<code> に設定し、Content-Description を </code>File Transfer<code> に設定します。ダウンロードしたファイルに適切な名前も生成します。最後に、いくつかのコメントを追加します。これらは完全にオプションですが、ダウンロードしたファイルをどう処理するかをユーザーに案内するのに役立ちます。 </code>
</p> このシリーズの前の部分でテーブルの API を作成したため、エクスポート ハンドラーはデータベースに直接アクセスする必要はありません。また、<p>$args<code> 配列をクリーンアップする必要もありません。これは </code> によって行われ、wptuts_get_logs()<code> によって処理されます。 </code>
<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbal:false;">function wptuts_export_logs( $args = array() ) {
/* Query logs */
$logs = wptuts_get_logs($args);
/* If there are no logs - abort */
if( !$logs )
return false;
/* Create a file name */
$sitename = sanitize_key( get_bloginfo( 'name' ) );
if ( ! empty($sitename) ) $sitename .= '.';
$filename = $sitename . 'wptuts-logs.' . date( 'Y-m-d' ) . '.xml';
/* Print header */
header( 'Content-Description: File Transfer' );
header( 'Content-Disposition: attachment; filename=' . $filename );
header( 'Content-Type: text/xml; charset=' . get_option( 'blog_charset' ), true );
/* Print comments */
echo "<!-- This is a export of the wptuts log table -->\n";
echo "<!-- (Demonstration purposes only) -->\n";
echo "<!-- (Optional) Included import steps here... -->\n";
/* Print the logs */
}
</pre><div class="contentsignin">ログイン後にコピー</div></div>
<p>您会注意到,我们已将实际查询数组作为参数传递给 <code>wptuts_export_logs()</code> 函数。我们可以对此进行硬编码,但不这样做也是有道理的。虽然这里的目的只是导出表中的<em>所有内容</em>,但将查询作为参数传递允许我们稍后添加在特定时间范围内或针对特定用户导出日志的选项。</ p>
<p>创建 XML 文件时,我们需要确保标签之间打印的值不包含字符 <code>&</code>、<code><</code> 或 <code>></code>。为了确保这一点,对于 ID,我们使用 <code>absint</code> 清理数据,并使用 <code>sanitize_key</code> 清理对象类型和活动(因为我们希望这些仅包含小写字母数字、下划线和连字符)。</p>
<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbal:false;">/* Print logs to file */
echo '<logs>';
foreach ( $logs as $log ) { ?>
<item>
<log_id><?php echo absint($log->log_id); ?></log_id>
<activity_date><?php echo mysql2date( 'Y-m-d H:i:s', $log->activity_date, false ); ?></activity_date>
<user_id><?php echo absint($log->user_id); ?></user_id>
<object_id><?php echo absint($log->object_id); ?></object_id>
<object_type><?php echo sanitize_key($log->object_type); ?></object_type>
<activity><?php echo sanitize_key($log->activity); ?></activity>
</item>
<?php }
echo '</logs>';
</pre><div class="contentsignin">ログイン後にコピー</div></div>
<p>更一般地,您可以使用以下函数将要打印的值包装在 <code>CDATA</code> 标记内来清理它们:</p>
<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbal:false;">/**
* Wraps the passed string in a XML CDATA tag.
*
* @param string $string String to wrap in a XML CDATA tag.
* @return string
*/
function wptuts_wrap_cdata( $string ) {
if ( seems_utf8( $string ) == false )
$string = utf8_encode( $string );
return '<![CDATA[' . str_replace( ']]>', ']]]]><![CDATA[>', $string ) . ']]>';
}
</pre><div class="contentsignin">ログイン後にコピー</div></div>
<p>最后我们 <code>exit()</code> 以防止任何进一步的处理:</p>
<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbal:false;"> /* Finished - now exit */
exit();
</pre><div class="contentsignin">ログイン後にコピー</div></div>
</p>
<p>导航到我们的导出页面,单击“下载活动日志”应提示下载 XML 文件。</p>
<hr>
<h2>摘要</h2>
<p>在本教程中,我们研究了从自定义表中导出数据。不幸的是,当数据引用本机 WordPress 表时,这充其量是有问题的。上述方法仅适用于数据无法做到这一点的情况。使用的示例(我们的活动日志)显然不属于此类,只是为了与本系列的其余部分保持一致而使用。</p>
<p>当数据<em>确实</em>引用本机表时,显然有必要将其与本机表一起导入,并在此过程中跟踪导入期间发生的 ID 任何更改。目前,现有的导入和导出处理程序无法实现这一点,因此唯一可行的选择是创建自己的处理程序。在自定义数据仅引用单个帖子类型的简单情况下,可以设计导入和导出处理程序来处理该帖子类型以及自定义数据,并通知用户不要使用该帖子类型的本机导出器。
</p>
<p>在本系列的下一部分中,我们将为导出的 .xml 文件创建一个简单的导入处理程序。</p>
以上がデータ エクスポート: カスタマイズされたデータベース テーブルの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。