PHP создает новый объект или использует существующий, если isset? - PullRequest
4 голосов
/ 01 октября 2011

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

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

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

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

РЕДАКТИРОВАТЬ : я не могу изменить Zone и findOneByCode, поскольку они являются автоматически генерируемыми классами и функционируют в Doctrine ORM.

Ответы [ 4 ]

4 голосов
/ 01 октября 2011

Если вы используете> = PHP 5.3

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

в противном случае может быть, это лучше?(все еще немного некрасиво) ...

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

В случае ошибки $repo->findOneByCode() возвращает ложное значение ...

0 голосов
/ 01 октября 2011

Эти два метода также сделают свою работу:

$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 будет содержать результат логической операции (истина или ложь).Но когда мы пишем:

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

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

0 голосов
/ 01 октября 2011

Вы можете сделать следующее:

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

Обратите внимание, однако, что это не работает точно , как при использовании isset(). Хотя использование isset() позволит проходить другим значениям, отличным от NULL (например, FALSE), использование a ? b : c приведет к c для всех значений Falsey .

0 голосов
/ 01 октября 2011

То, что вы описываете, - это ленивый шаблон синглтона.Это когда есть только один экземпляр класса, но он не инициализируется, пока вы не попытаетесь его использовать.

Пример: http://blog.millermedeiros.com/2010/02/php-5-3-lazy-singleton-class/

...