我无法使用以下代码捕获异常。任何人都可以帮我解决这个问题吗?
try
{
$xml_emp_name = $xpath->evaluate("//EMPLOYEES[ID='" . $emp_id . "']/EMP-NAME/text()")->item(0)->nodeValue;
}
catch(Exception $e)
{
echo "Error: " . $e->getMessage();
}
我无法使用以下代码捕获异常。任何人都可以帮我解决这个问题吗?
try
{
$xml_emp_name = $xpath->evaluate("//EMPLOYEES[ID='" . $emp_id . "']/EMP-NAME/text()")->item(0)->nodeValue;
}
catch(Exception $e)
{
echo "Error: " . $e->getMessage();
}
DOMXPath::evaulate 不会抛出异常。domxpath 评估
如果表达式格式错误或 contextnode 无效,则 DOMXPath::evaluate() 返回 FALSE。
尝试
$xml_emp_name = $xpath->evaluate("//EMPLOYEES[ID='" . $emp_id . "']/EMP-NAME/text()");
if(!$xml_emp_name){
echo 'Error';
}else{
$name = $xml_emp_name->item(0)->nodeValue;
}
如果 evaulate 失败并返回,您将尝试访问非对象上的属性false
。
您的代码容易受到 xpath 注入。先解决这个问题。然后错误会自动消失(因为 xpath 不会在语法上变得无效)。您还需要检查/验证返回值。
因此,您缺少输入验证和返回值验证的基本原则。您需要做的就是多加小心。
输入验证:
您直接将变量$emp_id
注入 xpath 字符串以进行替换:
"//EMPLOYEES[ID='" . $emp_id . "']/EMP-NAME/text()"
但是,在那个地方,您不能在该字符串中使用单引号。而是检查输入值(验证)或过滤/简化它(清理)。例如,验证它不包含单引号或清除数值。这里是第二个:
$expression = sprintf('//EMPLOYEES[ID="%d"]/EMP-NAME/text()', $emp_id);
$result = $xpath->evaluate($expression);
这个小调用sprintf()
注意只使用数字整数值。它们从不包含引号,因此表达式始终有效。没有数字的无效值将变为0
。由于从不分配 ID 是一般原则,因此0
这通常不会在设计良好的系统中引起任何问题。如果您想进行更精细的过滤,请参阅PHP 手册中的数据过滤。
返回值验证
在您的代码中,您只需通过很少的检查(实际上没有检查)来接管结果的返回值。那是错的。对于您使用的每个方法或函数,您需要在 PHP 手册中查找它并检查文档以获取所有可能的返回值。这里的方法是DOMXpath::evaluate()
,单击链接并找到返回值部分。您可以在 PHP 手册中为每个方法和函数找到它。
当您阅读文档时,还要弄清楚方法使用了哪种错误处理。它会抛出异常(如果是,是哪些?)还是它的返回值显示错误条件(就像你的情况一样)?需要此信息来决定是否像您一样执行 try/catch(这是错误的,因为它不会引发异常),或者您是否需要检查返回值:
$expression = sprintf('//EMPLOYEES[ID="%d"]/EMP-NAME/text()', $emp_id);
$result = $xpath->evaluate($expression);
if (!$result) {
throw new Exception(
sprintf('No such employee (id: %s)', var_export($emp_id, true))
);
}
此示例将虚假返回值转换为带有单独异常消息的异常。您可能还想考虑一个不同的异常,SPL 提供了一些预定义的异常。
我希望这个答案可以帮助您处理这个问题和即将到来的问题。
->evaluate
由于某种原因不会抛出任何异常,所以我建议检查结果是否为假,然后抛出异常:
if (($xml_emp_name = $xpath->evaluate("//EMPLOYEES[ID='" . $emp_id . "']/EMP-NAME/text()") ) !== false) {
$xml_emp_name = $xml_emp_name->item(0)->nodeValue;
}
else {
// Throw Exception
}