php 导入csv ucs 2,php-从csv文件将大量自定义帖子导入到wordpress中

我的脚本出现问题,该脚本从csv文件导入条目并将其作为wordpress自定义帖子插入(每行都是一个帖子)…

最初,我在自己的类中设置了导入功能,这几乎没有用…从我收集的内容来看,问题是全局变量未缓存,并且每次我调用实例时,都会消耗更多内存,直到该过程为止内存不足并崩溃了…所以我删除了该类并按照下面的代码所述设置了导入功能.

有了这个设置,我到了可以处理多达17k个帖子的地步,但是,如果我尝试导入的帖子超过该数量,它就会退出而不会出现任何错误(我的php错误日志或wordpress debug.log文件)

该脚本成功插入了17k个帖子,打印出回声信息,直到回声信息在“剩余XXX个项目”处过早停止为止,并完成了该页面的加载,此时不再输出任何内容……它永远不会返回到最终回声“完成” !“;声明…

在localhost开发环境和托管开发服务器上都会发生这种情况.

我一直关注着内存使用情况,在我的本地主机上它从未超过60%(开始时为〜50%),而且我看不到逐步出现的内存上升指示内存泄漏的情况…

我也曾尝试使用ini_set(‘memory_limit’,’64M’);和set_time_limit(0);

从我阅读过的与此类似的其他一些问题来看,

>对于SQL 20k条目应该没什么大不了的

>如果服务器是服务器,wordpress也应该能够处理此问题

足够强大

我可以对下面的代码进行什么样的优化/改进,以使此脚本在这种规模下工作?

或跳过fancypants here提到的内置功能的wordpress并使用LOAD DATA INFILE处理所有内容

我希望通过提供的wordpress功能处理数据.

csv文件约为1mb …

编码:

这些函数驻留在自己的文件中-import.php

function fileupload_process() {

ini_set('memory_limit', '64M');

set_time_limit(0);

$uploadfiles = $_FILES['uploadfiles'];

if (is_array($uploadfiles)) {

foreach ($uploadfiles['name'] as $key => $value) {

// look only for uploaded files

if ($uploadfiles['error'][$key] == 0) {

$filetmp = $uploadfiles['tmp_name'][$key];

if (($handle = fopen($filetmp, "r")) !== FALSE) {

$flag = true;

$songs = explode("\n",file_get_contents($filetmp));

$count = count( $songs );

unset($songs);

echo "Total item count: " . $count . "
";

// typical entry: If You Have To Ask,Red Hot Chili Peppers,0:03:37, Rock & Alternative,1991,on

// using a generous 1000 length - will lowering this actually impact performance in terms of memory allocation?

while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {

// Skip the first entry in the csv containing colmn info

if($flag) {

$flag = false;

echo "
";

$count--;

continue;

}

// insert the current post and relevant info into the database

$currently_processed = process_custom_post($data, $count);

$count--;

}

echo "Done!";

fclose($handle);

}

unlink($filetmp); // delete the temp csv file

}

}

}

} // END: file_upload_process()

function process_custom_post($song, $count) {

$track = (array_key_exists(0, $song) && $song[0] != "" ? $song[0] : 'N/A');

$artist = (array_key_exists(1, $song) && $song[1] != "" ? $song[1] : 'N/A');

$length = (array_key_exists(2, $song) && $song[2] != "" ? $song[2] : 'N/A');

$genre = (array_key_exists(3, $song) && $song[3] != "" ? $song[3] : 'N/A');

$year = (array_key_exists(4, $song) && $song[4] != "" ? $song[4] : 'N/A');

$month = (array_key_exists(5, $song) && $song[5] != "" ? $song[5] : 'N/A');

$playlist = (array_key_exists(6, $song) && $song[6] != "" ? $song[6] : '');

$custom_post = array();

$custom_post['post_type'] = 'songs';

$custom_post['post_status'] = 'publish';

$custom_post['post_title'] = $track;

echo "Importing " . $artist . " - " . $track . " (" . $count ." items remaining)...
";

$post_id = wp_insert_post( $custom_post );

$updated = update_post_meta($post_id, 'artist_name', $artist);

$updated = update_post_meta($post_id, 'song_length', $length);

$updated = update_post_meta($post_id, 'song_genre', $genre);

$updated = update_post_meta($post_id, 'song_year', $year);

$updated = update_post_meta($post_id, 'song_month', $month);

$updated = update_post_meta($post_id, 'sample_playlist', $playlist);

return true;

} // END: process_custom_post()

function import_page () {

//HTML for the import page + the file upload form

if (isset($_POST['uploadfile'])) {

fileupload_process();

}

}

import.php包含在插件类之外的wordpress插件中

即以下是有关如何在导入页面上获取脚本的相关信息:

define( 'MY_PLUGIN_ROOT' , dirname(__FILE__) );

include_once( MY_PLUGIN_ROOT . 'import.php');

class my_plugin () {

function __construct() {

add_action( 'init', array( &$this, 'admin_menu_init' ) );

}

function admin_menu_init() {

if(is_admin()) {

//Add the necessary pages for the plugin

add_action('admin_menu', array(&$this, 'add_menu_items'));

}

}

function add_menu_items() {

add_submenu_page( 'edit.php?post_type=songs', 'Import Songs', 'Import Songs', 'manage_options', 'import-songs', 'import_page' );

}

}

任何想法,评论或建议将不胜感激.

解决方法:

因此,在经过长时间的分析会议之后,与XDEBUG,phpmyadmin和朋友一起,我终于缩小了瓶颈所在:mysql查询

我启用了

define(‘SAVEQUERIES’,true);

来更详细地检查查询,然后将查询数组输出到我的debug.log文件

global $wpdb;

error_log( print_r( $wpdb->queries, true ) );

在检查对数据库的每个INSERT调用时

> wp_insert_post()

[0] =>插入wp_posts(post_author,post_date,post_date_gmt,post_content,post_content_filtered,post_title,post_excerpt,post_status,post_type,comment_status,ping_status,post_password,post_name,to_ping,pinged,post_modified,post_modified_gmt,order_parent,post_parent,post_parent,post_parent

[1] => 0.10682702064514

> update_post_meta()

[0] =>插入到wp_postmeta(post_id,meta_key,meta_value)值(…)

[1] => 0.10227680206299

我发现在我的本地主机服务器上,对数据库的每次调用平均花费约0.1 s

但是,由于我要更新每个条目6个自定义字段,因此可以解决

6 cf插入呼叫/条目*〜0.1s / cf插入呼叫* 20000总条目* 1分钟/ 60s = 200分钟

大约2.5个小时的时间处理2万个帖子的自定义字段

现在,由于所有自定义字段都插入到同一表wp_post_meta中,因此我希望将所有update_post_meta调用合并为一个调用,因此,就此导入脚本的执行时间而言,可以大大提高性能.

我查看了wp核心中的update_post_meta函数,发现没有传递数组而不是单个cf键和值的本机选项,因此我仔细阅读了相关代码以查明SQL INSERT行,并了解如何进行操作的行:

`INSERT INTO `wp_postmeta` (`post_id`,`meta_key`,`meta_value`)

VALUES ( $post_id, 'artist_name' , $artist)

( $post_id, 'song_length' , $length )

( $post_id, 'song_genre' , $genre ) ...`

对于本例中的所有6个自定义字段,依此类推,所有这些都放在一个$wpdb-> query();中; .

调整我的process_custom_post()函数以反映这一点,我最终得到了:

function process_custom_post($song) {

global $wpdb;

// Prepare and insert the custom post

$track = (array_key_exists(0, $song) && $song[0] != "" ? $song[0] : 'N/A');

$custom_post = array();

$custom_post['post_type'] = 'songs';

$custom_post['post_status'] = 'publish';

$custom_post['post_title'] = $track;

$post_id = wp_insert_post( $custom_post );

// Prepare and insert the custom post meta

$meta_keys = array();

$meta_keys['artist_name'] = (array_key_exists(1, $song) && $song[1] != "" ? $song[1] : 'N/A');

$meta_keys['song_length'] = (array_key_exists(2, $song) && $song[2] != "" ? $song[2] : 'N/A');

$meta_keys['song_genre'] = (array_key_exists(3, $song) && $song[3] != "" ? $song[3] : 'N/A');

$meta_keys['song_year'] = (array_key_exists(4, $song) && $song[4] != "" ? $song[4] : 'N/A');

$meta_keys['song_month'] = (array_key_exists(5, $song) && $song[5] != "" ? $song[5] : 'N/A');

$meta_keys['sample_playlist'] = (array_key_exists(6, $song) && $song[6] != "" ? $song[6] : '');

$custom_fields = array();

$place_holders = array();

$query_string = "INSERT INTO $wpdb->postmeta ( post_id, meta_key, meta_value) VALUES ";

foreach($meta_keys as $key => $value) {

array_push($custom_fields, $post_id, $key, $value);

$place_holders[] = "('%d', '%s', '%s')";

}

$query_string .= implode(', ', $place_holders);

$wpdb->query( $wpdb->prepare("$query_string ", $custom_fields));

return true;

}

和中提琴!而不是每个自定义帖子对数据库进行7次INSERT调用,我最终在尝试遍历大量帖子时处理多个自定义字段时产生2个巨大差异-在我的情况下,现在20k个条目在15个内完成处理-20min(相对于〜17k帖子和几个小时的处理时间后我会退出的情况)…

所以我从整个经验中学到的关键是

介意您的数据库调用-他们可以快速添加!

标签:performance,csv,wordpress,mysql,php

来源: https://codeday.me/bug/20191122/2061814.html

你可能感兴趣的:(php,导入csv,ucs,2)