Eksport data: jadual pangkalan data tersuai

WBOY
Lepaskan: 2023-09-02 18:02:01
asal
801 orang telah melayarinya
<p><img src="https://img.php.cn/upload/article/000/887/227/169364887365792.jpg" alt="Eksport data: jadual pangkalan data tersuai"></p> <p>Seperti yang dinyatakan dalam artikel pertama siri ini, salah satu masalah utama dengan jadual pangkalan data tersuai ialah ia tidak dikendalikan oleh pengendali import dan eksport sedia ada. Artikel ini bertujuan untuk menangani masalah ini, tetapi perlu diingatkan bahawa pada masa ini tiada penyelesaian yang memuaskan sepenuhnya. </p> <p>Mari kita pertimbangkan dua senario: </p> <ol> <li>Jadual tersuai merujuk kepada jadual WordPress asli</li> <li>Meja tersuai adalah bebas sepenuhnya daripada jadual asli</li> </ol> <p> "Senario kes terburuk" ialah senario pertama. Ambil jadual tersuai yang menyimpan log aktiviti pengguna sebagai contoh. Ia merujuk ID pengguna, ID objek dan jenis objek - yang kesemuanya merujuk data yang disimpan dalam jadual WordPress asli. Sekarang bayangkan seseorang ingin mengimport semua data dari laman web WordPress mereka ke laman web kedua. Sebagai contoh, sangat mungkin apabila mengimport siaran, WordPress perlu memberikannya ID baharu kerana siaran dengan ID tersebut mungkin sudah wujud di tapak kedua. </p> <p>Dalam kes ini, adalah perlu untuk menjejaki perubahan tersebut dan mengemas kini ID yang dirujuk dalam jadual. Ini sendiri tidak begitu sukar. <em>Malangnya</em>, pemalam Pengimport WordPress untuk mengendalikan pengimportan data dari tapak WordPress lain tidak mempunyai cangkuk yang diperlukan untuk mencapai ini. Seperti yang dicadangkan dalam ulasan ini, penyelesaian yang berpotensi adalah untuk menyimpan data dalam metadata juga. Malangnya, ini mengakibatkan data pendua dan melanggar normalisasi pangkalan data—secara amnya bukan idea yang baik. Akhirnya, ia hanya benar-benar boleh dilaksanakan dalam beberapa kes penggunaan. </p> <p>Kes kedua mengelakkan kerumitan ini tetapi masih memerlukan pengendali import dan eksport tersuai. Kami akan menunjukkan keadaan ini dalam dua artikel seterusnya. Walau bagaimanapun, untuk selaras dengan seluruh siri ini, kami akan kekal dengan jadual log aktiviti, walaupun ia adalah contoh kes (1). </p> <hr> <h2>Tentukan format</h2> <p>Mula-mula kita perlu memutuskan format fail yang dieksport. Format terbaik bergantung pada sifat (atau "struktur") data dan cara ia akan digunakan. Pada pendapat saya, XML secara amnya lebih baik kerana ia boleh mengendalikan perhubungan satu-ke-banyak. Walau bagaimanapun, kadangkala jika data dalam bentuk jadual, CSV mungkin lebih baik, terutamanya kerana kemudahan penyepaduan dengan aplikasi hamparan. Dalam contoh ini kita akan menggunakan XML. </p> <hr> <h2>Kenaikan harga</h2> <p>Langkah seterusnya ialah membuat halaman pentadbir untuk membolehkan pengguna mengeksport data daripada jadual log. Kami akan membuat kelas yang akan menambah halaman di bawah item menu Alat. Halaman hanya mengandungi butang yang menggesa pengguna memuat turun fail eksport. Kelas juga akan menambah pengendali untuk mendengar penyerahan borang dan mencetuskan muat turun fail. </p> <p>Mula-mula mari kita lihat struktur kelas dan kemudian isikan butiran kaedahnya. </p> <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbal:false;">class WPTuts_Log_Export_Admin_Page{ /** * The page hook suffix */ static $hook_suffix=''; static function load(){ add_action('admin_menu', array(__CLASS__,'add_submenu')); add_action('admin_init', array(__CLASS__,'maybe_download')); } static function add_submenu(){} static function maybe_download(){} static function display(){} } WPTuts_Log_Export_Admin_Page::load(); </pre><div class="contentsignin">Salin selepas log masuk</div></div> <p><code>WPTuts_Log_Export_Admin_Page::load()</code> Mulakan kelas dan cangkuk panggil balik kepada operasi yang sesuai: <code>WPTuts_Log_Export_Admin_Page::load()</code> 初始化类并将回调挂钩到适当的操作:</p> <ul> <li> <code>add_submenu</code> – 负责在“工具”菜单下添加页面的方法。</li> <li> <code>maybe_download</code> – 此方法将监听检查是否已提交下载请求。这还将检查权限和随机数。 </li> </ul> <p>需要在发送任何标头之前尽早调用导出侦听器,因为我们将自己设置这些标头。我们可以将其挂接到 <code>init</code> 上,但由于我们只允许在管理中下载导出文件,因此 <code>admin_init</code> 在这里更合适。</p> <p>向菜单添加页面非常简单。要在“工具”下添加页面,我们只需调用 <code>add_management_page()</code>。</p> <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbal:false;">static function add_submenu(){ self::$hook_suffix = add_management_page( __('Export Logs','wptuts-log'), __('Export Logs','wptuts-log'), 'manage_options', 'wptuts-export', array(__CLASS__,'display') ); } </pre><div class="contentsignin">Salin selepas log masuk</div></div> <p>这里的 <code>$hook_suffix</code> 是用于各种屏幕特定钩子的后缀,这里讨论。我们在这里不使用它 - 但如果您使用它,最好将其值存储在变量中,而不是对其进行硬编码。</p> <p>在上面我们将方法 <code>display()</code> 设置为我们页面的回调,接下来我们定义它:</p> <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbal:false;">static function display(){ echo '&lt;div class=&quot;wrap&quot;&gt;'; screen_icon(); echo '&lt;h2&gt;' . __( 'Export Activity Logs', 'wptuts-log' ) . '&lt;/h2&gt;'; ?&gt; &lt;form id=&quot;wptuts-export-log-form&quot; method=&quot;post&quot; action=&quot;&quot;&gt; &lt;p&gt; &lt;label&gt;&lt;?php _e( 'Click to export the activity logs','wptuts-log' ); ?&gt;&lt;/label&gt; &lt;input type=&quot;hidden&quot; name=&quot;action&quot; value=&quot;export-logs&quot; /&gt; &lt;/p&gt; &lt;?php wp_nonce_field('wptuts-export-logs','_wplnonce') ;?&gt; &lt;?php submit_button( __('Download Activity Logs','wptuts-log'), 'button' ); ?&gt; &lt;/form&gt; &lt;?php } </pre><div class="contentsignin">Salin selepas log masuk</div></div> <p>最后,我们希望监听上述表单何时提交并触发导出文件下载。</p> <div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbal:false;">static function maybe_download(){ /* Listen for form submission */ if( empty($_POST['action']) || 'export-logs' !== $_POST['action'] ) return; /* Check permissions and nonces */ if( !current_user_can('manage_options') ) wp_die(''); check_admin_referer( 'wptuts-export-logs','_wplnonce'); /* Trigger download */ wptuts_export_logs(); } </pre><div class="contentsignin">Salin selepas log masuk</div></div> <p>剩下的就是创建函数 <code>wptuts_export_logs()</code> 来创建并返回我们的 .xml 文件。</p> <hr> <h2>创建导出文件</h2> <p>我们希望函数做的第一件事是检索日志。如果有的话,我们需要设置适当的标头并以 XML 格式打印它们。由于我们希望用户下载 XML 文件,因此我们将 Content-Type 设置为 <code>text/xml</code>,将 Content-Description 设置为 <code>File Transfer</code>。我们还将为下载文件生成合适的名称。最后,我们将添加一些注释 - 这些完全是可选的,但有助于指导用户如何处理下载的文件。</p> <p>由于在本系列的前一部分中,我们为表创建了 API,因此我们的导出处理程序不需要直接接触数据库 - 也不需要清理 <code>$args</code> 数组,因为这是由 <code> 处理的wptuts_get_logs()</code> <ul> </p> <code>add_submenu</code> – Kaedah bertanggungjawab untuk menambah halaman di bawah menu "Alat". 🎜 🎜 <code>mungkin_muat turun</code> – Kaedah ini akan mendengar untuk menyemak sama ada permintaan muat turun telah diserahkan. Ini juga akan menyemak kebenaran dan nonces. 🎜 </ul> 🎜Pendengar eksport perlu dipanggil awal sebelum sebarang pengepala dihantar, kerana kami akan menetapkan sendiri pengepala ini. Kami boleh menyambungkannya ke <code>init</code>, tetapi memandangkan kami hanya membenarkan fail eksport dimuat turun dalam pentadbir, <code>admin_init</code> adalah lebih sesuai di sini. 🎜 🎜Menambah halaman pada menu anda adalah mudah. Untuk menambah halaman di bawah Alat, kami hanya memanggil <code>add_management_page()</code>. 🎜 <div class="code" style="position:relative; padding:0px; margin:0px;"><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 &quot;&lt;!-- This is a export of the wptuts log table --&gt;\n&quot;; echo &quot;&lt;!-- (Demonstration purposes only) --&gt;\n&quot;; echo &quot;&lt;!-- (Optional) Included import steps here... --&gt;\n&quot;; /* Print the logs */ } </pre><div class="contentsignin">Salin selepas log masuk</div></div><div class="contentsignin">Salin selepas log masuk</div></div> 🎜 <code>$hook_suffix</code> di sini ialah akhiran yang digunakan untuk pelbagai cangkuk khusus skrin, dibincangkan di sini. Kami tidak menggunakannya di sini - tetapi jika anda melakukannya, adalah lebih baik untuk menyimpan nilainya dalam pembolehubah daripada mengekodkannya secara keras. 🎜 🎜 Di atas kami menetapkan kaedah <code>display()</code> sebagai panggilan balik halaman kami, seterusnya kami mentakrifkannya: 🎜 <div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbal:false;">/* Print logs to file */ echo '&lt;logs&gt;'; foreach ( $logs as $log ) { ?&gt; &lt;item&gt; &lt;log_id&gt;&lt;?php echo absint($log-&gt;log_id); ?&gt;&lt;/log_id&gt; &lt;activity_date&gt;&lt;?php echo mysql2date( 'Y-m-d H:i:s', $log-&gt;activity_date, false ); ?&gt;&lt;/activity_date&gt; &lt;user_id&gt;&lt;?php echo absint($log-&gt;user_id); ?&gt;&lt;/user_id&gt; &lt;object_id&gt;&lt;?php echo absint($log-&gt;object_id); ?&gt;&lt;/object_id&gt; &lt;object_type&gt;&lt;?php echo sanitize_key($log-&gt;object_type); ?&gt;&lt;/object_type&gt; &lt;activity&gt;&lt;?php echo sanitize_key($log-&gt;activity); ?&gt;&lt;/activity&gt; &lt;/item&gt; &lt;?php } echo '&lt;/logs&gt;'; </pre><div class="contentsignin">Salin selepas log masuk</div></div><div class="contentsignin">Salin selepas log masuk</div></div> 🎜Akhir sekali, kami ingin memantau apabila borang di atas diserahkan dan mencetuskan muat turun fail eksport. 🎜 <div class="code" style="position:relative; padding:0px; margin:0px;"><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 '&lt;![CDATA[' . str_replace( ']]&gt;', ']]]]&gt;&lt;![CDATA[&gt;', $string ) . ']]&gt;'; } </pre><div class="contentsignin">Salin selepas log masuk</div></div><div class="contentsignin">Salin selepas log masuk</div></div> 🎜Semua yang tinggal ialah mencipta fungsi <code>wptuts_export_logs()</code> untuk mencipta dan mengembalikan fail .xml kami. 🎜 🎜 🎜Buat fail eksport🎜 🎜Perkara pertama yang kami mahu fungsi lakukan ialah mendapatkan semula log. Jika ada, kami perlu menetapkan pengepala yang sesuai dan mencetaknya dalam format XML. Memandangkan kami mahu pengguna memuat turun fail XML, kami menetapkan Content-Type kepada <code>text/xml</code> dan Content-Description kepada <code>File Transfer</code>. Kami juga akan menjana nama yang sesuai untuk fail yang dimuat turun. Akhir sekali, kami akan menambah beberapa ulasan - ini adalah pilihan sepenuhnya, tetapi membantu dalam membimbing pengguna tentang perkara yang perlu dilakukan dengan fail yang dimuat turun. 🎜 🎜Memandangkan kami mencipta API untuk jadual di bahagian sebelumnya dalam siri ini, pengendali eksport kami tidak perlu menyentuh pangkalan data secara langsung - ia juga tidak perlu membersihkan tatasusunan <code>$args</code>, kerana ini dilakukan oleh <code > Processed wptuts_get_logs()</code>. 🎜 <div class="code" style="position:relative; padding:0px; margin:0px;"><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 &quot;&lt;!-- This is a export of the wptuts log table --&gt;\n&quot;; echo &quot;&lt;!-- (Demonstration purposes only) --&gt;\n&quot;; echo &quot;&lt;!-- (Optional) Included import steps here... --&gt;\n&quot;; /* Print the logs */ } </pre><div class="contentsignin">Salin selepas log masuk</div></div><div class="contentsignin">Salin selepas log masuk</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;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbal:false;">/* Print logs to file */ echo '&lt;logs&gt;'; foreach ( $logs as $log ) { ?&gt; &lt;item&gt; &lt;log_id&gt;&lt;?php echo absint($log-&gt;log_id); ?&gt;&lt;/log_id&gt; &lt;activity_date&gt;&lt;?php echo mysql2date( 'Y-m-d H:i:s', $log-&gt;activity_date, false ); ?&gt;&lt;/activity_date&gt; &lt;user_id&gt;&lt;?php echo absint($log-&gt;user_id); ?&gt;&lt;/user_id&gt; &lt;object_id&gt;&lt;?php echo absint($log-&gt;object_id); ?&gt;&lt;/object_id&gt; &lt;object_type&gt;&lt;?php echo sanitize_key($log-&gt;object_type); ?&gt;&lt;/object_type&gt; &lt;activity&gt;&lt;?php echo sanitize_key($log-&gt;activity); ?&gt;&lt;/activity&gt; &lt;/item&gt; &lt;?php } echo '&lt;/logs&gt;'; </pre><div class="contentsignin">Salin selepas log masuk</div></div><div class="contentsignin">Salin selepas log masuk</div></div> <p>更一般地,您可以使用以下函数将要打印的值包装在 <code>CDATA</code> 标记内来清理它们:</p> <div class="code" style="position:relative; padding:0px; margin:0px;"><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 '&lt;![CDATA[' . str_replace( ']]&gt;', ']]]]&gt;&lt;![CDATA[&gt;', $string ) . ']]&gt;'; } </pre><div class="contentsignin">Salin selepas log masuk</div></div><div class="contentsignin">Salin selepas log masuk</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">Salin selepas log masuk</div></div> <p>导航到我们的导出页面,单击“下载活动日志”应提示下载 XML 文件。</p> <hr> <h2>摘要</h2> <p>在本教程中,我们研究了从自定义表中导出数据。不幸的是,当数据引用本机 WordPress 表时,这充其量是有问题的。上述方法仅适用于数据无法做到这一点的情况。使用的示例(我们的活动日志)显然不属于此类,只是为了与本系列的其余部分保持一致而使用。</p> <p>当数据<em>确实</em>引用本机表时,显然有必要将其与本机表一起导入,并在此过程中跟踪导入期间发生的 ID 任何更改。目前,现有的导入和导出处理程序无法实现这一点,因此唯一可行的选择是创建自己的处理程序。在自定义数据仅引用单个帖子类型的简单情况下,可以设计导入和导出处理程序来处理该帖子类型以及自定义数据,并通知用户不要使用该帖子类型的本机导出器。 </p> <p>在本系列的下一部分中,我们将为导出的 .xml 文件创建一个简单的导入处理程序。</p>

Atas ialah kandungan terperinci Eksport data: jadual pangkalan data tersuai. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan