如果是isset,PHP会创建一个新对象还是使用现有对象?

时间:2011-09-30 21:40:42

标签: php object new-operator ternary-operator isset

我很多次发现这个多余:

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

任何人都可以建议更好的方式,类似于(不工作):

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

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

4 个答案:

答案 0 :(得分:4)

如果您使用的是> = PHP 5.3

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

否则也许这样更好? (还是有点难看)......

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

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

答案 1 :(得分:0)

你所描述的是懒惰的单身人士模式。这是只有一个类的实例,但是在你尝试使用它之前它不会被初始化。

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

答案 2 :(得分:0)

您可以执行以下操作:

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

但是,请注意,这与使用isset() 完全无效。虽然使用isset()将允许NULL以外的其他虚假值传递(例如FALSE),但使用a ? b : c将解析为c 所有虚假价值

答案 3 :(得分: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之后的部分将被完全忽略。