【问题标题】:SImplexml slow or is it WordPress update_meta?SIMplexml 慢还是 WordPress update_meta?
【发布时间】:2017-07-15 22:10:02
【问题描述】:

我有一个使用 simplexml_load_string 解析 658kB XML 文件的脚本。该文件是一个包含 118 个不同属性的属性(房地产)提要,总计 21000 行。该脚本使用大量以下调用从节点中提取数据:

(string)$properties->address->county

我还在脚本中使用高级自定义字段来更新 WordPress 中的元数据自定义字段,更多调用:

update_field( 'field_59606d60525d3', (string)$properties->floorplans, $post_id );

在 Vagrant VVV 盒子上,脚本需要超过 5 分钟才能运行,之后会超时。它设法将 118 个属性中的 46 个加载到自定义帖子类型中我不知道是瓶颈。是吗:

  • simplexml 解析文件?
  • 在 ACF 中使用 update_field?

Webgrind (xdebug) 似乎指向很多 update_meta 调用,但我不太确定在 cachegrind 文件中查找和理解什么。

我想我要问的是有没有比 PHP 原生 simpleXML 更快的替代方案,以及如何解释 XDEBUG/webgrind 输出

此脚本最终将在商品主机上运行(无 VPS/专用)

技能水平:程序性(函数,而非类)

xdebug 输出:

Call Stack
#   Time    Memory  Function    Location
1   0.2021  361704  {main}( )   .../test.php:0
2   0.6501  5888288 get_xml( )  .../test.php:163
3   544.3322    115472480   update_field( string(19), array(457), long )    .../test.php:115
4   544.3325    115472480   acf_update_value( array(457), long, array(24) ) .../api-template.php:1018
5   544.3325    115472536   apply_filters( string(30), array(457), long, array(24) )    .../api-value.php:350
6   544.3325    115472936   WP_Hook->apply_filters( array(457), array(3) )  .../plugin.php:203
7   544.3326    115473688   acf_field_repeater->update_value( array(457), long, array(24) ) .../class-wp-hook.php:298
8   556.4756    117433368   acf_field_repeater->update_row( array(2), long, array(24), long )   .../repeater.php:900
9   556.4756    117434744   acf_update_value( string(42), long, array(20) ) .../repeater.php:804
10  556.5003    117437600   acf_update_metadata( long, string(15), string(19), true )   .../api-value.php:368
11  556.5004    117438016   update_metadata( string(4), long, string(15), string(19), ??? ) .../api-value.php:101
12  556.5005    117438136   get_metadata( string(4), long, string(15), ??? )    .../meta.php:193
13  556.5005    117438512   update_meta_cache( string(4), array(1) )    .../meta.php:497
14  556.5124    118050992   intval ( string(3) )    .../meta.php:830

更新 #1 01/08/2017

我正处于一个阶段,我认为file_get_contents 可能是问题所在,因为提要中的每个属性都关联了大约 10 到 15 个图像 URL。 118 个属性 = 仅需要 1800 个图像 URL 调用。我尝试了 cUrl,然后偶然发现了curl_multi

我现在有了下面的工作代码,它将 curl_multi 在图像 URL 数组上,将它们作为附件添加到 WP 中,并将它们附加到特定的 post_id,同时更新 ACF 库字段。但是,我仍然不知道这实际上是否更快?如果curl_multi 实际上是在异步执行操作或者我的代码是否正确,我该如何计算这样的时间或解决问题?

require_once( '/srv/www/broadbean/wp-blog-header.php' );
require_once( '/srv/www/broadbean/wp-admin/includes/media.php' );
require_once( '/srv/www/broadbean/wp-admin/includes/file.php' );
require_once( '/srv/www/broadbean/wp-admin/includes/image.php' );

// https://stackoverflow.com/questions/15436388/download-multiple-images-from-remote-server-with-php-a-lot-of-images
// http://php.net/manual/en/function.curl-multi-init.php

$post_id = '2773';
$image_urls = array( 'http://target.domain.net/photos/1334268.jpg', 'http://target.domain.net/photos/1278564.jpg', 'http://target.domain.net/photos/1278565.jpg' );
$chs = array();
$upload_dir = wp_upload_dir();
$tc = count($image_urls);
$cmh = curl_multi_init();

for ($t = 0; $t < $tc; $t++)
{
    $chs[$t] = curl_init();
    curl_setopt($chs[$t], CURLOPT_URL, $image_urls[$t]);
    //curl_setopt($chs[$t], CURLOPT_FILE, $fp);
    curl_setopt($chs[$t], CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($chs[$t], CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($chs[$t], CURLOPT_TIMEOUT, 120);
    curl_setopt($chs[$t], CURLOPT_USERAGENT, 'Mozilla/5.0');
    curl_multi_add_handle($cmh, $chs[$t]);
}

$running = null;

do {
    curl_multi_exec($cmh, $running);
} while ($running);


for ($t = 0; $t < $tc; $t++)
{
    $filename = basename( $image_urls[$t] );
    $image_file = $upload_dir['path'] . '/' . $filename;
    $fp = fopen($image_file, 'w+');

    fwrite($fp, curl_multi_getcontent( $chs[$t] ) );
    fclose($fp);

    $wp_filetype = wp_check_filetype($image_file, null );

    $attachment = array(
        'post_mime_type' => $wp_filetype['type'],
        'post_title' => sanitize_file_name( $filename),
        'post_content' => '',
        'post_status' => 'inherit'
    );


    $attach_id = wp_insert_attachment( $attachment, $image_file, $post_id );
    $attach_data = wp_generate_attachment_metadata( $attach_id, $image_file );
    $update_attach_metadata = wp_update_attachment_metadata( $attach_id, $attach_data );

    $add_gallery_images[] = $attach_id;

    curl_multi_remove_handle($cmh, $chs[$t]);
    curl_close($chs[$t]);

}
var_dump($add_gallery_images);
update_field( 'field_5973027c18fdc', $add_gallery_images , $post_id );

curl_multi_close($cmh);

【问题讨论】:

    标签: php wordpress xdebug advanced-custom-fields curl-multi


    【解决方案1】:

    不是对您的问题的具体答案,但由于您使用的是 Wordpress,您是否尝试过使用 WP All Import?它对 ACF 也有很好的实现(我认为在这种情况下你需要专业版)

    【讨论】:

    • 我没有,但这是一个很好的观点。我有一位同事使用它将 MS Access 导出导入 ACF,效果很好(大约 4000 条记录)。 WP All Import 和“手工”操作有什么不同?也许我需要发布一个代码 sn-p?
    • 主要的好处是 WP All Import 插件非常适合执行此类操作。如果您真的想在不使用现有插件/库的情况下执行此操作,那么您应该知道 Wordpress 的所有注意事项(在本例中为高级自定义字段),这可能会导致编写自定义 mysql 查询。
    猜你喜欢
    • 1970-01-01
    • 2010-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-21
    • 2015-04-07
    • 1970-01-01
    • 2013-06-26
    相关资源
    最近更新 更多