Smplexml медленный или это WordPress update_meta?

У меня есть сценарий, который использует simplexml_load_string для анализа XML-файла 658 КБ. Файл представляет собой фид свойств (недвижимости) с 118 различными свойствами, общим объемом 21000 строк. Сценарий использует множество следующих вызовов для извлечения данных из узлов:

(string)$properties->address->county

Я также использую расширенные настраиваемые поля в скрипте для обновления настраиваемых полей метаданных в WordPress.

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

На Vagrant VVV box выполнение сценария занимает более 5 минут, а время ожидания истекает после этого. Ему удается загрузить в пользовательский тип сообщения около 46 из 118 свойств. Что я не знаю, так это узкое место. Это:

  • Simplexml разбор файла?
  • используя update_field в ACF?

Webgrind (xdebug), кажется, указывает на множество вызовов update_meta, но я не совсем уверен, что искать и понимать в файле cachegrind.

Я полагаю, что я спрашиваю, есть ли более быстрая альтернатива простому PHPML для PHP и как интерпретировать вывод 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 от 08.01.2017

Я на стадии с этим, где я решил, что file_get_contents может быть проблема, поскольку каждое свойство в фиде имеет около 10-15 URL-адресов изображений. 118 свойств = просто не хватает 1800 изображений. Я попробовал 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://stackru.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);

1 ответ

Не совсем конкретный ответ на вашу проблему, но, поскольку вы используете Wordpress, пробовали ли вы использовать WP All Import? Он также имеет хорошую реализацию для ACF (я думаю, вам нужна профессиональная версия в этом случае)

Другие вопросы по тегам