优化PHP代码实现多维数组数据存入数据库
修复多维数组插入数据库的两个问题
当前代码在将两个多维数组插入WordPress数据库时存在两个问题:
$_POST['menu_meal_name']中的值无法保存到数据库$menu_categorie仅最后一个分类的值被存储,其余条目被忽略
问题根源分析
- 数组结构解析错误:从给出的数组结构可见,
menu_meal_name下的name、price、description都是嵌套数组(比如name[0]才是具体餐品名称),原代码直接赋值$meal_name = $meal['name'],实际得到的是数组而非字符串,导致数据库无法正确存储。 - 循环逻辑错误:原代码中
foreach ($meals as $meal)的循环逻辑错误,$meals本身就是menu_meal_name[$key]对应的单条餐品组数据,不需要再循环;正确逻辑应该是遍历餐品的索引,将同索引的name、price、description对应起来。
优化后的代码
$menu_categorie = isset($_POST['menu_categorie']) ? map_deep($_POST['menu_categorie'], 'sanitize_text_field') : array(); $menu_meal_name = isset($_POST['menu_meal_name']) ? map_deep($_POST['menu_meal_name'], 'sanitize_text_field') : array(); global $wpdb; $table_name = $wpdb->prefix . "restaurant"; // 确保遍历到所有分类和餐品组,避免索引越界 $max_index = max(count($menu_categorie), count($menu_meal_name)); if ($max_index > 0) { for ($i = 0; $i < $max_index; $i++) { // 获取当前分类名称 $categorie_name = ''; if (isset($menu_categorie[$i]['name'])) { $categorie_name = $menu_categorie[$i]['name']; } // 跳过空分类(可根据业务需求调整) if (empty($categorie_name)) { continue; } // 获取当前分类对应的餐品数据组 $meal_group = isset($menu_meal_name[$i]) ? $menu_meal_name[$i] : array(); $meal_names = isset($meal_group['name']) ? $meal_group['name'] : array(); $meal_prices = isset($meal_group['price']) ? $meal_group['price'] : array(); $meal_descriptions = isset($meal_group['description']) ? $meal_group['description'] : array(); // 遍历当前分类下的所有餐品 $meal_count = max(count($meal_names), count($meal_prices), count($meal_descriptions)); for ($j = 0; $j < $meal_count; $j++) { $meal_name = isset($meal_names[$j]) ? $meal_names[$j] : ''; $price = 0; if (isset($meal_prices[$j])) { // 格式化价格,替换逗号为点并转为浮点数 $price = floatval(str_replace(',', '.', $meal_prices[$j])); } $description = isset($meal_descriptions[$j]) ? $meal_descriptions[$j] : ''; // 仅当餐品名称有效时执行操作(可根据业务需求调整判断条件) if (!empty($meal_name)) { $current_time = current_time('mysql'); $data_to_insert = array( 'post_id' => absint($post_id), 'post_title' => sanitize_text_field(get_the_title($post_id)), 'categorie' => sanitize_text_field($categorie_name), 'meal_name' => sanitize_text_field($meal_name), 'price' => $price, 'pp' => 0, 'description' => sanitize_text_field($description), ); // 检查是否已存在该分类下的同名餐品 $existing = $wpdb->get_row( $wpdb->prepare( "SELECT id FROM {$table_name} WHERE post_id = %d AND meal_name = %s AND categorie = %s", absint($post_id), sanitize_text_field($meal_name), sanitize_text_field($categorie_name) ) ); if ($existing) { // 更新现有记录 $data_to_insert['aangepast_op'] = $current_time; $wpdb->update( $table_name, $data_to_insert, array('id' => $existing->id) ); } else { // 插入新记录 $data_to_insert['aangemaakt_op'] = $current_time; $wpdb->insert($table_name, $data_to_insert); } } } } }
关键修改说明
- 修正数组解析逻辑:通过索引
$j对应name、price、description数组中的元素,确保取到的是字符串而非嵌套数组。 - 调整循环结构:使用
for循环替代嵌套foreach,确保每个分类都能被遍历到,解决仅最后一个分类被存储的问题。 - 增强数据安全性:对
post_title、categorie等字段添加额外的sanitize_text_field处理,避免恶意数据注入。 - 优化存在性检查:查询现有记录时加入
categorie条件,避免不同分类下同名餐品被错误覆盖。
内容的提问来源于stack exchange,提问作者kiarashi
相关产品推荐
相关产品推荐

