【发布时间】: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