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 (я думаю, вам нужна профессиональная версия в этом случае)