Записать сериализованные значения многомерного массива в файл с путем ключа
Мой вопрос заключается в том, как я могу успешно сканировать все уровни этих сериализованных данных и записывать каждый конечный уровень в отдельные строки в файле, где каждая строка содержит массив "путь ключа" и значение. По сути, мне нужно, чтобы каждое значение было заключено в функцию 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;
}
Так что добавляем ключи в обратном порядке.