使用密钥路径将序列化的多维数组值写入文件

时间:2014-08-26 14:39:26

标签: php arrays serialization iterator

我的问题是如何成功抓取此序列化数据的所有级别,并将每个叶级写入文件中的单独字符串,其中每行包含数组"键路径"和价值。 基本上,我需要包含在i18n函数中的每个值用于翻译目的。

我在mySQL数据库中有一些序列化数据,这里有一个有问题的值的样本:

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

预期的结果是将每个叶子值写入一个PHP文件,并使用它的关键hierearchy,这样我就可以将它重新转换为数组:

$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 [&#39; fields&#39;] [0] [&#39; text&#39;] = __(&#34;我的字符串&#34;,&#34; tjxgallery&#34;);

所以,它错过了['choices'][0]部分。

任何帮助表示赞赏

感谢您的时间

2 个答案:

答案 0 :(得分:1)

我在代码中的所有位置添加了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";

    }
}

答案 1 :(得分:0)

接受的回复让我大部分时间都可以,但我仍然需要检查一个键是否为数字,因为它必须是[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;
}

因此反向添加密钥。