2011-09-30 90 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之後的部分完全被忽略。

相關問題