2012-04-04 78 views
1

我之前从未在我的代码中使用Try-catch,但现在我需要这样做,看起来我并不完全理解它的工作方式。我有一个字符串数据,我开始使用爆炸:在PHP中使用Try-catch结构

$groupNumbers = array(); 
$str = $dataGroups['groups']; 
$groupNumbers = explode(",", $str); 
$count = count($groupNumbers); 

然后我想检查是否每一个元素是数字,如果是我着手进行数据库查询,否则我要中止行动蚂蚁回报一些错误。

下面是我在做什么:

for ($i = 0; $i < $count; ++$i) 
    { 
     try 
     { 
      is_numeric($groupNumbers[$i]); 

     } 
     catch (Exception $ex) 
     { 
      process_exception_to_json($ex); 
     } 
    } 

如果evrery元素是数字我construc的活动记录做SQL:

$这个 - > DB-> insert_batch(” users_groups',$ datas);

很明显就是这样写的,即使一个元素不是数字,该操作也不会中止,而且insert_batch仍然执行时带有无效的值,这是我想要避免的。做这件事的确切方法是什么,所以我可以得到一个异常,并同时中止行动。 感谢

Leron

+2

把尝试捕获外for循环。理想情况下,你不想依赖try-catch来进行验证。 – Sachin 2012-04-04 08:38:02

回答

2

这是因为is_numericDocs不会抛出异常,但返回一个值。它永远不会失败/抛出异常。

你需要做的是这样(只是一个例子,因为它是多余的,我不认为它):

try 
{ 
    if (!is_numeric($groupNumbers[$i])) { 
     throw new RuntimeException('Not numeric.'); 
    } 

} 
catch (Exception $ex) 
{ 
    process_exception_to_json($ex); 
} 

而是创建自己的组号类型:

try 
{ 
    $groupNumbers = GroupNumbers::createFromString($dataGroups['groups']); 
} 
catch (Exception $ex) 
{ 
    process_exception_to_json($ex); 
} 

使用以下类型:

class GroupNumbers extends ArrayObject 
{ 
    public function construct(Array $numbers) { 
     foreach ($numbers as $number) 
     { 
      if (!is_numeric($number)) 
      { 
       throw new InvalidArgumentException(sprintf('Not numeric "%s".', $number)); 
      } 
     } 
     parent::__construct($numbers); 
    } 
    public static function createFromString($string) { 
     return new self(explode(",", $string)); 
    } 
} 

字符串处理现在被封装,没有更多的外部循环和GroupNumbers只会在字符串中存在实际数字的情况下进行实例化。

如果您不擅长上课,您可以享受类似的好处以及程序风格。它可能更容易理解(但几乎相同的):

try 
{ 
    $groupNumbers = GroupNumbers_createFromString($dataGroups['groups']); 
} 
catch (Exception $ex) 
{ 
    process_exception_to_json($ex); 
} 

function GroupNumbers_createFromString($string) 
{ 
    $numbers = explode(",", $string); 
    foreach ($numbers as $number) 
    { 
     if (!is_numeric($number)) 
     { 
      throw new InvalidArgumentException(sprintf('Not numeric "%s".', $number)); 
     } 
    } 
    return $numbers; 
} 
+0

LOL稍微超过亩级,但稍后会查看您的代码。非常感谢! – Leron 2012-04-04 08:56:03

+0

而不是类,您可以创建一个返回数值数组的函数,例如,类似于静态函数内联构造函数。编辑答案。 – hakre 2012-04-04 08:57:44

1

is_numeric不会抛出任何异常,所以你的例子并不做任何事情,这会工作寿:

for ($i = 0; $i < $count; ++$i) 
{ 
    try 
    { 
     if (is_numeric($groupNumbers[$i]) !== true) 
     { 
      throw new Exception($groupNumbers[$i] . ' is not numeric'); 
     } 
    } 

    catch (Exception $ex) 
    { 
     process_exception_to_json($ex); 
    } 
} 

下面将完成(几乎)同样的事情:

for ($i = 0; $i < $count; ++$i) 
{ 
    if (is_numeric($groupNumbers[$i]) !== true) 
    { 
     process_exception_to_json($groupNumbers[$i] . ' is not numeric'); 
    } 
} 
1

如果你想验证,你不需要使用Exception这里

for ($i = 0; $i < $count; ++$i) 
{ 
    if((int) $groupNumbers[$i] <= 0) { 
     process_exception_to_json($groupNumbers[$i]); 
     break; //optinal 
    } 
} 
0

您需要做一些事实上在try块内引发异常。 is_numeric()将仅返回false,因此不起作用。这将:

try { 
    if (!is_numeric($groupNumbers[$i]) { 
     throw new exception('Uh-oh!'); 
    } 
} catch (Exception $ex) { 
    process_exception_to_json($ex); 
} 

这可能是最好这样做:

function checkNumbers($groupNumbers) { 
    for ($i = 0; $i < count($groupNumbers); ++$i) { 
     if (!is_numeric($groupNumbers[$i]) { 
      throw new Exception('"'.$groupNumbers[$i]." is non-numeric!"); 
     } 
    } 
} 

try { 
    checkNumbers($numbers); 
    // Won't get this far if it throws an exception 
    $this->db->insert_batch('users_groups', $numbers); 
} catch (Exception $ex) { 
    process_exception_to_json($ex); 
} 

例外情况可以嵌套很深的代码和主要好处内是错误消息是特有的,泡了而不必担心很多真实或错误的值。您可能会从checkNumbers()中调用几十个链接函数,无论出现什么错误,它都会在catch块中弹出,并准备将其发送给JSON。