PHP array_filter使用问题:无法提取Namecheap数据中的注册价格
问题:提取Namecheap沙箱指定TLD的1年注册价格时出现未定义数组键警告
问题背景
我是PHP新手,需要从Namecheap沙箱返回的大型数组中,提取指定域名后缀(TLD)对应「register」产品分类下的1年注册价格。我写了对应的代码,但运行时持续报错,不过通过硬编码数组路径可以成功获取目标价格。
我的代码
class registerPrice { function getRegisterPrice($domainTLD, $newArr) { // Extract the "Register" product category for the target TLD $registerCategory = array_filter($newArr['CommandResponse']['UserGetPricingResult']['ProductType'], function ($category) use ($domainTLD) { return $category['@attributes']['Name'] === 'register' && $category['Product']['@attributes']['Name'] === $domainTLD; }); // Extract the prices for the 1-year duration from the "register" category for the target TLD $registerPrices = array_column($registerCategory, 'Product'); $registerPriceForOneYear = null; foreach ($registerPrices as $product) { foreach ($product as $price) { if ($price['@attributes']['Duration'] == 1 && $price['@attributes']['DurationType'] == 'YEAR') { $registerPriceForOneYear = $price['Price']['@attributes']['Price']; break 2; // Exit both loops once the price for 1 year is found } } } return $registerPriceForOneYear; } }
数组结构片段
Array ( [@attributes] => Array ( [Status] => OK ) [Errors] => Array ( ) [Warnings] => Array ( ) [RequestedCommand] => namecheap.users.getpricing [CommandResponse] => Array ( [@attributes] => Array ( [Type] => namecheap.users.getPricing ) [UserGetPricingResult] => Array ( [ProductType] => Array ( [@attributes] => Array ( [Name] => domains ) [ProductCategory] => Array ( [0] => Array ( [@attributes] => Array ( [Name] => reactivate ) [Product] => Array ( [@attributes] => Array ( [Name] => com ) [Price] => Array ( [@attributes] => Array ( [Duration] => 1 [DurationType] => YEAR [Price] => 13.48 [Currency] => USD ) ) ) ) [1] => Array ( [@attributes] => Array ( [Name] => register ) [Product] => Array ( [@attributes] => Array ( [Name] => com ) [Price] => Array ( [0] => Array ( [@attributes] => Array ( [Duration] => 1 [DurationType] => YEAR [Price] => 10.28 [Currency] => USD ) ) ) ) ) ) ) ) ) )
错误信息
PHP Warning: Undefined array key "@attributes" in D:\xampp\htdocs\sm\registrationPrice.php on line 6 Warning: Undefined array key "@attributes" in D:\xampp\htdocs\sm\registrationPrice.php on line 6 Warning: Trying to access array offset on value of type null in D:\xampp\htdocs\sm\registrationPrice.php on line 6 Warning: Undefined array key "@attributes" in D:\xampp\htdocs\sm\registrationPrice.php on line 6 Warning: Trying to access array offset on value of type null in D:\xampp\htdocs\sm\registrationPrice.php on line 6
第6行代码:return $category['@attributes']['Name'] === 'register' && $category['Product']['@attributes']['Name'] === $domainTLD;
原因分析
- 遍历层级错误:当前用
array_filter遍历的是ProductType数组,而该数组包含两个元素:@attributes(产品类型标识,值为domains)和ProductCategory(所有产品分类的数组)。当遍历到@attributes元素时,它本身没有@attributes子键,也没有Product键,直接访问就会触发未定义键警告。 - 缺少存在性检查:即使遍历正确的数组,也可能存在部分分类结构不完整的情况,直接访问深层数组键会导致警告。
解决方法
- 修正遍历目标:将
array_filter的目标改为ProductType下的ProductCategory数组,这才是包含各个分类(如register、reactivate)的数组。 - 添加数组键存在性检查:在访问数组键之前,用
isset()确认键存在,避免警告。
修正后的代码
class registerPrice { function getRegisterPrice($domainTLD, $newArr) { // 确认基础数组路径存在,避免后续报错 if (!isset($newArr['CommandResponse']['UserGetPricingResult']['ProductType']['ProductCategory'])) { return null; } // 遍历正确的ProductCategory数组,筛选register分类和指定TLD $registerCategory = array_filter($newArr['CommandResponse']['UserGetPricingResult']['ProductType']['ProductCategory'], function ($category) use ($domainTLD) { // 先检查必要键是否存在 if (!isset($category['@attributes']['Name'], $category['Product']['@attributes']['Name'])) { return false; } return $category['@attributes']['Name'] === 'register' && $category['Product']['@attributes']['Name'] === $domainTLD; }); $registerPriceForOneYear = null; foreach ($registerCategory as $category) { // 处理Price数组的两种情况:单个价格或多个价格数组 $prices = is_array($category['Product']['Price']) ? $category['Product']['Price'] : [$category['Product']['Price']]; foreach ($prices as $price) { if (isset($price['@attributes']['Duration'], $price['@attributes']['DurationType']) && $price['@attributes']['Duration'] == 1 && $price['@attributes']['DurationType'] == 'YEAR' && isset($price['@attributes']['Price'])) { $registerPriceForOneYear = $price['@attributes']['Price']; break 2; } } } return $registerPriceForOneYear; } }
内容的提问来源于stack exchange,提问作者Bryan Corringham
相关产品推荐
相关产品推荐

