【问题标题】:pass correct multidimensional array values to function (without duplicates)将正确的多维数组值传递给函数(不重复)
【发布时间】:2018-05-10 23:14:09
【问题描述】:

我试图通过在 oop 编程中正确利用循环和函数(方法)来摆脱手动和重复执行的操作;但是在将正确的值传递给负责数据库操作的必要抽象函数(方法)时,我遇到了一个主要的绊脚石。

非常欢迎任何帮助,这将使我能够摆脱这个我一直试图推开的绊脚石,但我没有取得任何进展,我是出于真正的挫折和痛苦在这里求救。

下面是为简单起见我尽可能缩短的代码(可以通过复制和粘贴在本地轻松测试):

// array with table properties and form values - start
$form_fields_arr = [
    'group' => [
        'anime' => [ // genre
            'table_prop' => [ // for update query - table properties
                'table_name'    => 'anime_tbl',
                'account_id'    => 2,
                'visible'       => 'yes'
            ],

            'form_data' => [ // for update query - form values
                '2'             => 'Attack on Titan',
                '4'             => 'RWBY',
                '6'             => 'Rurouni Kenshin',
                '8'             => 'A Silent Voice'
            ]
        ],

        'movie' => [ // genre
            'table_prop' => [ // for update query - table properties
                'table_name'    => 'movie_tbl',
                'account_id'    => 4,
                'visible'       => 'yes'
            ],

            'form_data' => [ // for update query - form values
                '1'             => 'Queen of Katwe',
                '3'             => 'Forest Gump',
                '5'             => 'War Horse',
                '7'             => 'The Fault in our Stars'
            ]
        ]
    ]
]; // ... end


// loop through multidimensional array and pass values to function - start
foreach ($form_fields_arr['group'] as $frm_key_1 => $frm_val_1) { // 2d array
    foreach ($frm_val_1 as $frm_key_2 => $frm_val_2) { // 1d array

        if (strcasecmp($frm_key_1, $frm_key_1) === 0) { // group by genre

            foreach ($frm_val_2 as $frm_key_3 => $frm_val_3) { // 1d array

                if (strcasecmp($frm_key_2, 'form_data') === 0) {
                    $title =  $form_fields_arr['group'][$frm_key_1]['form_data'][$frm_key_3]; // anime/movie title
                }

                if (isset($frm_val_2['table_name']) &&
                    isset($frm_val_2['account_id']) &&
                    isset($frm_val_2['visible']) &&
                    isset($title)
                ) {
                    dbUpdate(
                        $frm_val_2['table_name'],
                        $frm_val_2['account_id'],
                        $frm_val_2['visible'],
                        $title
                    );
                }

            } // 1d array

        } // if block

    } // 1d array
} // 2d array
// ... end


// function that receives passed values - start
function dbUpdate($table_name, $account_id, $title_col, $form_value) {
    $test_val_arr = [$table_name, $account_id, $title_col, $form_value];

    return print_r($test_val_arr);
} // ... end

以上代码输出:

// array values passed to and returned from function
Array (
    [0] = movie_tbl
    [1] = 4
    [2] = yes
    [3] = A Silent Voice
)

Array (
    [0] = movie_tbl
    [1] = 4
    [2] = yes
    [3] = A Silent Voice
)

Array (
    [0] = movie_tbl
    [1] = 4
    [2] = yes
    [3] = A Silent Voice
)

Array (
    [0] = movie_tbl
    [1] = 4
    [2] = yes
    [3] = A Silent Voice
)

但我想要达到的理想结果是:

// for anime genre - array values passed to and returned from function
Array (
    [0] = anime_tbl
    [1] = 2
    [2] = yes
    [3] = Attack on Titan
)

Array (
    [0] = anime_tbl
    [1] = 2
    [2] = yes
    [3] = RWBY
)

Array (
    [0] = anime_tbl
    [1] = 2
    [2] = yes
    [3] = Rurouni Kenshin
)

Array (
    [0] = anime_tbl
    [1] = 2
    [2] = yes
    [3] = A Silent Voice
)


// for movie genre - array values passed to and returned from function
Array (
    [0] = movies_tbl
    [1] = 4
    [2] = yes
    [3] = Queen of Katwe
)

Array (
    [0] = movies_tbl
    [1] = 4
    [2] = yes
    [3] = Forest Gump
)

Array (
    [0] = movies_tbl
    [1] = 4
    [2] = yes
    [3] = War Horse
)

Array (
    [0] = movies_tbl
    [1] = 4
    [2] = yes
    [3] = The Fault in our Stars
)

所以一切都失败了,我花了大约一周的时间试图解决这个问题,告诉自己这很简单,我真的不应该被困在这里,出于绝望,我决定回到我重复的方式和尝试了以下方法:

// new array without table properties - start
$new_array = [];
$new_array['group']['anime'] = $form_fields_arr['group']['anime']['form_data'];
$new_array['group']['movie'] = $form_fields_arr['group']['movie']['form_data']; // ... end

// loop through multidimensional array and pass values to function - start
foreach ($new_array['group'] as $key_1 => $val_1) { // 2d array
    foreach ($val_1 as $key_2 => $val_2) { // 1d array

        if (strcasecmp($key_1, $key_1) === 0) {
            dbUpdate('anime_tbl', 2, 'yes', $val_2);
            dbUpdate('movie_tbl', 4, 'yes', $val_2);
        } // if block

    } // 1d array
} // 2d array
// ... end

但结果仍然非常不理想。在我开始使用多维数组之前,一切都运行良好,仅仅是因为我意识到使用多维数组可以帮助我大大缩短其他领域的代码。但是我被困在这里,如果我不能让它工作,我将不得不返回更远的地方并撤消很多更改。我恳求任何好心人的帮助。请帮助我的人!任何人!


我在这里很乐观,并假设如果有任何机会我确实在解决上述问题方面得到了一些帮助,是否有人也可以教我如何循环遍历像下面这样的数组结构,同时又没有得到想要的结果重复(我确实尝试过但确实失败了):

// array with table properties and form values - start
$form_fields_arr = [
    'table_prop' => [ // table properties group
        'anime' => [ // for update query - table properties
            'table_name'    => 'anime_tbl',
            'account_id'    => 2,
            'visible'       => 'yes'
        ],

        'movie' => [ // for update query - table properties
            'table_name'    => 'movie_tbl',
            'account_id'    => 4,
            'visible'       => 'yes'
        ]
    ],

    'form_data' => [ // for update query - form values
        'anime' => [ // genre
            '2'             => 'Attack on Titan',
            '4'             => 'RWBY',
            '6'             => 'Rurouni Kenshin',
            '8'             => 'A Silent Voice'
        ],

        'movie' => [ // genre
            '1'             => 'Queen of Katwe',
            '3'             => 'Forest Gump',
            '5'             => 'War Horse',
            '7'             => 'The Fault in our Stars'
        ]
    ]
]; // ... end

【问题讨论】:

    标签: php arrays function multidimensional-array foreach


    【解决方案1】:

    您的 for 循环中有一个逻辑错误。首先,您的变量命名不是很直观。 $frm_key_1$frm_key_2等看起来很像,迫使读者时刻牢记数组结构以理解变量的含义。这导致了这样一个错误:if( strcasecmp($frm_key_1, $frm_key_1) === 0 )。这始终是true

    那么你有两个独占条件:

    if (strcasecmp($frm_key_2, 'form_data') === 0)
    

    还有:

    if (isset($frm_val_2['table_name']) && /* ... */) {
    

    如果$frm_key_2'form_data',则您在流派数组的第二个子元素中,但字段'table_name' 等仅在第一个子元素中定义(带有键'table_prop')。所以这两个条件永远不可能同时为真。

    您触发dbUpdate() 函数的条件是,'table_prop' 数组的所有字段都存在(您同时迭代),并且还设置了$title。这仅在您的第三次for-loop 第二次迭代后才成立。在该迭代期间,$title 变量不断被覆盖,但没有触发sbUpdate(),因为$frm_val_2 的值来自'form_data' 而不是'table_prop'。所以在第三个for 循环完成后,第二次$title'A Silent Voice',它只是第一个'form_data' 数组的最后一个孩子。然后你的第二个for 循环再次迭代了第二个'table_prop' 数组,这意味着现在'dbUpdate()' 条件为真,所以它使用$title = 'A Silent Voice' 将参数postet 4 次('table_prop' 数组中的子项数) .

    你试图让一切都尽可能通用,让一切变得复杂。在这里工作的最佳解决方案是尊重特定结构的解决方案。

    这行得通:

    <?php
    // array with table properties and form values - start
    $form_fields_arr = [
        'group' => [
            'anime' => [ // genre
                'table_prop' => [ // for update query - table properties
                    'table_name'    => 'anime_tbl',
                    'account_id'    => 2,
                    'visible'       => 'yes'
                ],
    
                'form_data' => [ // for update query - form values
                    '2'             => 'Attack on Titan',
                    '4'             => 'RWBY',
                    '6'             => 'Rurouni Kenshin',
                    '8'             => 'A Silent Voice'
                ]
            ],
            'movie' => [ // genre
                'table_prop' => [ // for update query - table properties
                    'table_name'    => 'movie_tbl',
                    'account_id'    => 4,
                    'visible'       => 'yes'
                ],
    
                'form_data' => [ // for update query - form values
                    '1'             => 'Queen of Katwe',
                    '3'             => 'Forest Gump',
                    '5'             => 'War Horse',
                    '7'             => 'The Fault in our Stars'
                ]
            ]
        ]
    ];
    
    
    // loop through multidimensional array and pass values to function - start
    foreach ($form_fields_arr['group'] as $genreData) {
    
        $tableProperties = $genreData['table_prop'];
    
        if (!isset($tableProperties['table_name'])
        || !isset($tableProperties['account_id'])
        || !isset($tableProperties['visible'])) {
            continue;
        }
    
        $data = $genreData['form_data'];
    
        foreach ($data as $title) {
            dbUpdate(
                $tableProperties['table_name'],
                $tableProperties['account_id'],
                $tableProperties['visible'],
                $title
            );
        }
    }
    // function that receives passed values - start
    function dbUpdate($table_name, $account_id, $title_col, $form_value) {
        $test_val_arr = [$table_name, $account_id, $title_col, $form_value];
    
        return print_r($test_val_arr);
    } // ... end
    

    【讨论】:

    • 非常感谢 Philipp Maurer。我非常感激并感谢您的帮助,这超出了您的想象。我花了很长时间试图让它工作,但就像你很快修复它一样。你的方法很优雅。再次感谢您。
    【解决方案2】:

    对于没有回答的问题的最后一部分,感谢Philipp Maurer's 的回答,在玩弄了代码之后,我让它工作了。我只是为可能有类似问题并希望更好地了解如何使用 foreach 循环从多维数组中分组和获取值而没有重复或不正确结果的任何人提供答案。见以下代码:

    // array with table properties and form values - start
    $form_fields_arr = [
        'table_prop' => [ // table properties group
            'anime' => [ // for update query - table properties
                'table_name'    => 'anime_tbl',
                'account_id'    => 2,
                'visible'       => 'yes'
            ],
    
            'movie' => [ // for update query - table properties
                'table_name'    => 'movie_tbl',
                'account_id'    => 4,
                'visible'       => 'yes'
            ]
        ],
    
        'form_data' => [ // for update query - form values
            'anime' => [ // genre
                '2'             => 'Attack on Titan',
                '4'             => 'RWBY',
                '6'             => 'Rurouni Kenshin',
                '8'             => 'A Silent Voice'
            ],
    
            'movie' => [ // genre
                '1'             => 'Queen of Katwe',
                '3'             => 'Forest Gump',
                '5'             => 'War Horse',
                '7'             => 'The Fault in our Stars'
            ]
        ]
    ]; // ... end
    
    // loop through multidimensional array and pass values to function - start
    foreach ($form_fields_arr as $index => $group_array) {
        foreach ($group_array as $genre_key => $genre_val) {
    
            if (!isset($group_array[$genre_key]['table_name']) ||
                !isset($group_array[$genre_key]['account_id']) ||
                !isset($group_array[$genre_key]['visible'])
            ) {
                continue;
            }
    
            foreach ($form_fields_arr['form_data'][$genre_key] as $data_key => $data_title) {
                dbUpdate(
                    $group_array[$genre_key]['table_name'],
                    $group_array[$genre_key]['account_id'],
                    $group_array[$genre_key]['visible'],
                    $data_title
                );
            }
    
        }
    }
    // ... end
    
    // function that receives passed values - start
    function dbUpdate($table_name, $account_id, $title_col, $form_value) {
        $test_val_arr = [$table_name, $account_id, $title_col, $form_value];
    
        return print_r($test_val_arr);
    } // ... end
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-15
    • 1970-01-01
    相关资源
    最近更新 更多