2011-09-30 81 views
4

很多时候,我觉得这是多余的:如果isset创建一个新对象或使用现有的对象?

$found = $repo->findOneByCode($code); 
$zone = isset($found) ? $found : new Zone(); 

任何人都可以提出一个更好的办法,类似于(不工作):

$zone = $repo->findOneByCode($code) || new Zone(); 

编辑:我不能修改ZonefindOneByCode为它们是由Doctrine ORM自动生成的类和函数。

+2

http://en.wikipedia.org/wiki/Singleton_pattern –

+0

将'findOneByCode()'方法扩展为返回所需空对象而不是'null'的方法。 – mario

回答

4

如果您使用> = PHP 5.3

$zone = $repo->findOneByCode($code) ?: new Zone(); 

否则也许这是更好? (还是有点丑)...

if (! ($zone = $repo->findOneByCode($code))) { 
    $zone = new Zone(); 
} 

假设失败,$repo->findOneByCode()返回falsy值...

+0

不,'$ repo-> findOneByCode()'在失败时返回'null' ... – gremo

+1

'jondavidjohn'这两种方法都可以在'null'下正常工作 –

+0

@jondavidjohn'findOneByCode()'是Doctrine ORM api的一部分,我无法控制它。 – gremo

0

什么你所描述的是一个懒惰的单例模式。这是当只有一个类的实例,但它不会被初始化,直到你尝试使用它。

例子:http://blog.millermedeiros.com/2010/02/php-5-3-lazy-singleton-class/

+0

我无法修改“区域”类,因为它是自动生成的。并包装它似乎有点矫枉过正... – gremo

+0

小心单身。他们通常因为引入紧耦合和难以测试代码而不悦。 – NikiC

0

你可以做到以下几点:

$zone = ($z = $repo->findOneByCode($code)) ? $z : new Zone(); 

但是请注意,这不工作完全相同喜欢使用isset()。虽然使用isset()将允许除NULL之外的其他错误值通过(例如FALSE),使用a ? b : c将解析为c关于所有错误值

+1

需要注意的是'$ z' **和**'$ zone'在此之后定义... – jondavidjohn

0

这两种方法也将做的工作:

$zone = $repo->findOneByCode($code) or $zone = new Zone(); 

($zone = $repo->findOneByCode($code)) || ($zone = new Zone()); 

注意or&&有不同的优先级,这就是为什么我们的()在第二个例子中所需要的。见http://www.php.net/manual/en/language.operators.logical.php。这个例子有:

// The result of the expression (false || true) is assigned to $e 
// Acts like: ($e = (false || true)) 
$e = false || true; 

// The constant false is assigned to $f and then true is ignored 
// Acts like: (($f = false) or true) 
$f = false or true; 

var_dump($e, $f); 

而结果:

bool(true) 
bool(false) 

这是因为andor具有优先级低于=意味着分配将被首先完成。另一方面,&&||具有比=更高的优先级,这意味着逻辑操作将首先完成,并将其结果分配给变量。这就是为什么我们不能写:

$result = mysql_query(...) || die(...); 

$result将持有的逻辑运算(true或false)的结果。但是当我们写:

$result = mysql_query(...) or die(...); 

该分配是在逻辑操作之前完成的。如果它不是虚假价值,or之后的部分完全被忽略。

相关问题