0

我无法使用以下代码捕获异常。任何人都可以帮我解决这个问题吗?

try
{
    $xml_emp_name = $xpath->evaluate("//EMPLOYEES[ID='" . $emp_id . "']/EMP-NAME/text()")->item(0)->nodeValue;
}
catch(Exception $e)
{
    echo "Error: " . $e->getMessage();
}
4

3 回答 3

2

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

于 2013-06-20T09:12:57.457 回答
0

您的代码容易受到 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 提供了一些预定义的异常

我希望这个答案可以帮助您处理这个问题和即将到来的问题。

于 2013-06-20T12:55:25.723 回答
0

->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
}
于 2013-06-20T09:20:33.737 回答