我之前从未在我的代码中使用过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元素是数字,我构造一个用于执行SQL的活动记录:
$ this-&gt; db-&gt; insert_batch('users_groups',$ datas);
显然是这样编写的,即使一个元素不是数字,动作也不会中止,而且我仍然使用无效值执行insert_batch,这是我想要避免的。这样做的确切方法是什么,因此我可以获得异常,并同时中止操作。 感谢
Leron
答案 0 :(得分:2)
这是因为is_numeric
Docs不会抛出异常但会返回一个值。它永远不会失败/抛出异常。
你需要这样做(只是一个例子,我不建议它,因为它是多余的):
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;
}
答案 1 :(得分: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');
}
}
答案 2 :(得分:1)
如果您想验证,则不需要在此使用Exception
for ($i = 0; $i < $count; ++$i)
{
if((int) $groupNumbers[$i] <= 0) {
process_exception_to_json($groupNumbers[$i]);
break; //optinal
}
}
答案 3 :(得分: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。