PHP创建一个新对象或使用已有的对象


PHP creating a new object or use existing one if isset?

很多时候我觉得这是多余的:

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

谁能建议一个更好的方法,类似于(不起作用):

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

EDIT:我不能修改ZonefindOneByCode,因为它们是Doctrine ORM自动生成的类和函数。

如果您使用PHP> = 5.3

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

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

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

假设失败,$repo->findOneByCode()返回一个假值…

你所描述的是一个懒惰的单例模式。这是指该类只有一个实例,但直到您尝试使用它时才初始化。

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

您可以这样做:

$zone = ($z = $repo->findOneByCode($code)) ? $z : new Zone();
但是,请注意,这并不像使用isset()那样完全工作。使用isset()将允许NULL以外的其他假值通过(例如FALSE),使用a ? b : c将对所有假值解析为c

这两个方法也可以完成这项工作:

$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后面的部分。