PHP создает новый объект или использует существующий, если isset?


Много раз я нахожу это излишним:

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

Может ли кто-нибудь предложить лучший способ, подобный (не работает):

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

EDIT : я не могу модифицировать Zone и findOneByCode, поскольку они автоматически генерируются классами и функциями по Доктрине ORM.

4 4

4 ответа:

Если вы используете >= 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() позволит другим значениям falsey, отличным от 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)

Это потому, что and и or имеют более низкий приоритет, чем =, что означает, что задание будет выполнено первым. С другой стороны, && и || имеют более высокий приоритет. чем =, то есть логическая операция будет выполнена первой, а ее результат присвоен переменной. Вот почему мы не можем написать:

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

$result будет содержать результат логической операции (true или false). Но когда мы пишем:

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

Задание выполняется перед логической операцией. И если это не ложное значение, то часть после or полностью игнорируется.