如何停止PHP notice: Undefined index | array_map | return

How to stop PHP notice: Undefined index | array_map | return

我总是在错误日志中收到 PHP 通知,因为我使用了一些语言功能。不知何故我无法正确...

我的语言数组如下所示(已编辑):

    $dict = [
        'title' => [
            'en' => 'Welcome',
            'de' => 'Willkommen'
        ],
        'description' => [
            'en' => 'Hello',
            'de' => 'Hallo'
        ],
    ];

这是我的语言功能(已编辑):

function lang($phrase){
    global $l, $dict;

    return $dict[$phrase][$l];
}

$l 在 $dict 数组之前定义(如“de”或“en”)。

在我的文档中我正在做:

<?php echo lang('title');?>

并且 PHP 通知引用了“return $dict[$phrase][$l];”部分。 我真的不明白为什么。我尝试了不同的方法,但没有任何效果。

编辑:

哦,该死。在 posting 之后,我终于意识到我在哪里使用了一个不再在我的语言数组中的短语。不知何故我是瞎子。不过 post 可以很好地清理我的函数。谢谢!

该通知意味着您正在尝试访问不存在的数组索引。在您的情况下,您似乎混淆了语言和短语的顺序:您尝试访问 $dict[en][title] 而不是 $dict[title][en].

更一般地说,总是在 return 它之前检查索引是否存在:

if (isset($dict[$l])) {
    return ...
} else {
    throw new Exception... // or whatever
}

随着 PHP 的进一步发展,您会发现使用全局变量带来的危害大于其价值。

如我对原始 post 的评论所述,在修复数组声明中缺少的括号(假设拼写错误)后,函数 works correctly,如果被正确调用为 echo lang('title')。如果您在 Undefined index 上收到通知,则表示您要查找的 $phrase 不存在于 $dict 数组中。 (如果您只在错误日志中收到通知,您可能需要在开发时打开 on-screen 错误报告以实时捕获这些错误!)

撇开基本的调试不谈,让我帮你稍微整理一下这段代码。首先,$l 或语言可以作为函数参数传入。其次,$dict 不需要是一个变量,假设您没有即时修改它。您可以将其声明为常量并避免使用全局变量。第三,你的数组映射是不必要的开销,这时你可以简单地调用数组中的相关索引。最小的 clean-up 看起来像这样:

const DICT = [
    'title' => [
        'en' => 'Welcome',
        'de' => 'Willkommen'
    ],
    'description' => [
        'en' => 'Hello',
        'de' => 'Hallo'
    ]
];

function lang($phrase, $lang) {
    // If you're using PHP 7, the null-coalescing operator is handy here:
    return DICT[$phrase][$lang] ?? "Phrase {$phrase} Unknown!";
}

你会像这样使用它:

// Sample usage: Output title in English and description in German:

echo lang('title', 'en') . ' ' . lang('description', 'de');

// Or, if the language variable is pre-defined, then e.g.:

$l = 'en';
echo lang('title', $l) . ' ' . lang('description', $l);

在这里,为您的字典使用常量是一种基本但非常有效的方式来处理全球对 pre-defined 数据的需求。常量在 compile-time 时解析,而变量声明在运行时解析。它们在所有情况下都可用。而且您绝对不想为了避免全局声明而将整个 $dict 放在函数中!

一种更优雅的处理方法是创建一个 class,这样您就可以避免使用语言函数参数。 (Class 常量和属性就像“本地全局变量”,可用于 class 中的所有方法。)这是您案例的示例应用程序 class,其中字典是 class常量,语言是class属性:

class Dict {

    const DICT = [
        'title' => [
            'en' => 'Welcome',
            'de' => 'Willkommen'
        ],
        'description' => [
            'en' => 'Hello',
            'de' => 'Hallo'
        ]
    ];
    
    public static $lang = 'en'; // for a default language
    
    public static function phrase($phrase)
    {
        return self::DICT[$phrase][self::$lang] ?? "Phrase {$phrase} Unknown!";
    }

}   

Dict::$lang = 'de'; // Define language

echo Dict::phrase('title') . ' ' . Dict::phrase('description');
// : Willkommen Hallo

如果您希望有一个需要在其他上下文中访问的大型词典,或者只是希望集中您的语言参考,那么您可能希望将其定义为 class 之外的常规常量,和第一个例子一样。我在这里使用 class 常量主要是出于教育目的。希望这能帮助您朝着更简洁的代码前进。