Записать сериализованные значения многомерного массива в файл с путем ключа

Мой вопрос заключается в том, как я могу успешно сканировать все уровни этих сериализованных данных и записывать каждый конечный уровень в отдельные строки в файле, где каждая строка содержит массив "путь ключа" и значение. По сути, мне нужно, чтобы каждое значение было заключено в функцию i18n для целей перевода.

У меня есть некоторые сериализованные данные в базе данных MySQL, вот пример проблемного значения:

stdClass Object
(
 {...}
 [fields] => Array
    (
        [0] => stdClass Object
            (
            {...}
            [choices] => Array
                    (
                        [0] => stdClass Object
                            (
                                [text] => My string
                                [value] => 7
                                [isSelected] => 
                                [price] => 
                            )
     ) {...}

Ожидаемый результат - каждое значение листа, записанное в файл PHP с его ключевой иерархией, такой как эта, поэтому я могу затем преобразовать его в массив:

$form['fields'][0]['choices'][0]['text'] = __( "My string", "tjxgallery" );

И вот мой код, который пытается сделать это

$iterator = new RecursiveIteratorIterator( new RecursiveArrayIterator( $form_fields ) );

$strings_to_translate = array(
    '<?php' . PHP_EOL
);

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

    // Fields to skip, as they don't contain any translatable strings
    $unwanted_fields = array(
        'inputName',
        'type',
        'size',
        'inputType',
        'descriptionPlacement',
        'postCustomFieldName',
        'allowedExtensions',
        'actionType',
        'operator',
        'logicType',
        'conditionalLogic',
    );

    // Only proceed if array item is a string and it's not empty and it's not a number and it's not in the ignored fields
    if ( ! in_array( $key, $unwanted_fields ) && ( is_string( $value ) && ( 0 < strlen( $value ) ) &&  ! is_numeric( $value ) ) ) {

        // Iterate through the sub arrays
        for ( $i = $iterator->getDepth() - 1; $i >= 0; $i -- ) {

            $path = '';

            // get the parent key of current item
            $subkey = $iterator->getSubIterator( $i )->key();

            // Build a string with the full key path - e.g. [0]['choices'][0]['text']
            if ( is_numeric( $subkey ) ) {

                if ( empty( $path ) ) {

                    $path = '[' . $subkey . '][\'' . $key;

                } else {

                    $path = '[' . $subkey . ']' . $key;

                }

            } else {

                if ( empty( $path ) ) {

                    $path = '[\'' . $subkey . '\'][\'' . $key;

                } else {

                    $path = '[\'' . $subkey . '\']' . $key;

                }

            }

        }

        // Build an array of translation ready strings e.g. $form['fields'][0]['text'] = __( "Give Up Clothes For Good – Cancer Research UK", "tjxgallery" );
        $strings_to_translate[] = '$form[\'fields\']' . $path . '\'] = __( "' . preg_replace( "/\n/", '', $value ) . '", "tjxgallery" );' . PHP_EOL;

    }

Теперь я получаю следующий результат: $form['fields'][0]['text'] = __( "My string", "tjxgallery");

Итак, он пропускает ['choices'][0] часть.

Любая помощь приветствуется

Спасибо за ваше время

2 ответа

Решение

Я добавил операторы echo повсюду в вашем коде, чтобы отследить, где возникла проблема. Я думаю, что было две проблемы: одна, $path находится во внутреннем цикле и продолжает сбрасываться, и два, $path меняли каждый раз, вместо того, чтобы к нему добавляли текст.

Вот что сработало для меня:

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

    // Fields to skip, as they don't contain any translatable strings
    $unwanted_fields = array(
        ...
    );
    // Only proceed if array item is a string and it's not empty
    // and it's not a number and it's not in the ignored fields
    if ( ! in_array( $key, $unwanted_fields ) && ( is_string( $value ) && ( 0 < strlen( $value ) ) &&  ! is_numeric( $value ) ) ) {

        // start a new path from $key here.
        $path = '';

        // Iterate through the sub arrays
        for ( $i = $iterator->getDepth() - 1; $i >= 0; $i -- ) {

            // get the parent key of current item
            $subkey = $iterator->getSubIterator( $i )->key();
            // Build a string with the full key path - e.g. [0]['choices'][0]['text']
            $path .= '[\'' . $subkey . '\']';
        }
        // OK, we've constructed the path. Add $key to the end.
        $path .= '[\'' . $key . '\']';

        // Build an array of translation ready strings e.g. $form['fields'][0]['text'] = __( "Give Up Clothes For Good – Cancer Research UK", "tjxgallery" );
        echo '$form[\'fields\']' . $path . ' = __( "' . preg_replace( "/\n/", '', $value ) . '", "tjxgallery" );' . "\n";

    }
}

Принятый ответ дает мне большую часть пути, но мне все еще нужно было проверить, является ли ключ числовым, потому что он должен быть [0] не ['0']

Также еще нужно выяснить, почему ключи не в правильном порядке:

$form['fields'][0]['choices'][0]['text'] = __( "String 1", "tjxgallery" );
$form['fields'][1]['choices'][0]['text'] = __( "String 2", "tjxgallery" );
$form['fields'][2]['choices'][0]['text'] = __( "String 3", "tjxgallery" );
$form['fields'][3]['choices'][0]['text'] = __( "String 4", "tjxgallery" );

должно быть (обратите внимание, что цифровые клавиши меняются местами:

$form['fields'][0]['choices'][0]['text'] = __( "String 1", "tjxgallery" );
$form['fields'][0]['choices'][1]['text'] = __( "String 2", "tjxgallery" );
$form['fields'][0]['choices'][2]['text'] = __( "String 3", "tjxgallery" );
$form['fields'][0]['choices'][3]['text'] = __( "String 4", "tjxgallery" );

Вот что нужно изменить:

if ( is_numeric( $subkey ) ) {
    $path = '[' . $subkey . ']' . $path;
} else {
    $path =  '[\'' . $subkey . '\']' . $path;
}

Так что добавляем ключи в обратном порядке.

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