重构重复PHP属性至JS:寻求优化赋值代码的可行方案
高效重构PHP中重复的数组属性赋值代码
这种重复的数组属性赋值在旧PHP项目里真的是家常便饭!我看你已经尝试了简化寻址的方式,但还是需要逐个处理属性,这里分享几个更高效的重构方案,帮你彻底摆脱重复代码:
方案1:同层级属性批量循环赋值
如果要复制的属性都属于同一个父级节点,比如spotify["current"]或者spotify_metadata下的属性,你可以先定义要复制的属性名列表,再通过循环一次性完成赋值:
// 处理 spotify[current] 下的基础属性 $sourceCurrent = $track["spotify"]["current"]; $targetCurrent = &$new_artist["spotify"]["current"]; // 用引用减少重复数组寻址 $baseProps = [ "total_streams", "total_listeners", "source_of_stream", "access_type", "date" ]; foreach ($baseProps as $prop) { // 可选:增加存在性检查,避免源属性不存在时报错 if (isset($sourceCurrent[$prop])) { $targetCurrent[$prop] = $sourceCurrent[$prop]; } } // 处理嵌套的 metrics 子属性 $sourceMetrics = $sourceCurrent["metrics"]; $targetMetrics = &$targetCurrent["metrics"]; $metricProps = [ "new_collection_listeners", "spotify_playlist_placement" ]; foreach ($metricProps as $prop) { if (isset($sourceMetrics[$prop])) { $targetMetrics[$prop] = $sourceMetrics[$prop]; } } // 处理 spotify_metadata 下的属性 $sourceMeta = $track["spotify_metadata"]; $targetMeta = &$new_artist["spotify_metadata"]; $metaProps = [ "artist_followers", "artist_genres", "artist_popularity", "artist_images" ]; foreach ($metaProps as $prop) { if (isset($sourceMeta[$prop])) { $targetMeta[$prop] = $sourceMeta[$prop]; } }
后续要增减属性,只需要修改对应的属性列表数组即可,不用改动赋值逻辑,维护成本低很多。
方案2:递归复制整个层级(适合整节点迁移)
如果某个父级节点下的所有属性都需要复制,不用逐个挑选,那可以封装一个递归函数,直接复制整个路径下的内容:
/** * 递归将源数组指定路径的内容复制到目标数组对应路径 * @param array $target 目标数组(传引用) * @param array $source 源数组 * @param string $path 路径用点分隔,例如 "spotify.current" */ function copyArrayNode(&$target, $source, $path) { $pathSegments = explode('.', $path); $currentTarget = &$target; $currentSource = $source; // 遍历路径找到对应的层级节点 foreach ($pathSegments as $segment) { if (!isset($currentSource[$segment])) { return; // 源路径不存在,直接终止 } // 如果目标路径不存在,先初始化空数组 if (!isset($currentTarget[$segment])) { $currentTarget[$segment] = []; } $currentTarget = &$currentTarget[$segment]; $currentSource = $currentSource[$segment]; } // 复制当前节点下的所有属性 foreach ($currentSource as $key => $value) { $currentTarget[$key] = $value; } } // 使用示例:一键复制整层级 copyArrayNode($new_artist, $track, "spotify.current"); copyArrayNode($new_artist, $track, "spotify_metadata"); // 也可以单独复制嵌套子层级 copyArrayNode($new_artist, $track, "spotify.current.metrics");
这个函数非常灵活,不管嵌套多少层,只要传入路径就能完成整节点复制,完全省去逐个属性编写的麻烦。
方案3:跨层级零散属性批量复制
如果需要复制的属性分布在不同层级,没有统一的父节点,你可以封装一个函数,接收属性路径列表来批量复制:
/** * 批量复制数组中指定路径的零散属性 * @param array $target 目标数组(传引用) * @param array $source 源数组 * @param array $propertyPaths 属性路径列表,例如 ["spotify.current.total_streams"] */ function copySpecificProps(&$target, $source, $propertyPaths) { foreach ($propertyPaths as $path) { $pathSegments = explode('.', $path); $lastProp = array_pop($pathSegments); $currentTarget = &$target; $currentSource = $source; $validPath = true; // 遍历到属性的父层级 foreach ($pathSegments as $segment) { if (!isset($currentSource[$segment]) || !isset($currentTarget[$segment])) { $validPath = false; break; } $currentTarget = &$currentTarget[$segment]; $currentSource = $currentSource[$segment]; } // 路径有效则赋值 if ($validPath && isset($currentSource[$lastProp])) { $currentTarget[$lastProp] = $currentSource[$lastProp]; } } } // 使用示例:列出所有要复制的属性路径 $propsToCopy = [ "spotify.current.total_streams", "spotify.current.total_listeners", "spotify.current.source_of_stream", "spotify.current.access_type", "spotify.current.metrics.new_collection_listeners", "spotify.current.metrics.spotify_playlist_placement", "spotify.current.date", "spotify_metadata.artist_followers", "spotify_metadata.artist_genres", "spotify_metadata.artist_popularity", "spotify_metadata.artist_images" ]; copySpecificProps($new_artist, $track, $propsToCopy);
这个方案适合精准复制零散属性的场景,把所有需要复制的属性路径列出来,一次调用就能完成所有赋值。
方案选择建议
- 如果是整层级复制所有属性:优先用方案2,代码最简洁
- 如果是同层级下的部分属性复制:用方案1,逻辑清晰易维护
- 如果是跨层级的零散属性复制:用方案3,一次搞定所有需求
内容的提问来源于stack exchange,提问作者Tomas Eglinskas
相关产品推荐
相关产品推荐

