Есть у меня две переменные:
$a_error = array();
$a_neerror = array();
И есть у меня сложная логика, например есть некие “события”, у неких “событий” есть некий “тип” и мне надо учитывать сколько типов этих событий было успешно или нет. Страшной силы код:
if ( $status == 'ok' ) {
if ( !isset($a_neerror[$event->type]) ) {
$a_neerror[$event->type] = 0;
}
$a_neerror[$event->type]++;
}
И потом его ещё продублировать для ошибочного варианта. Сильно печалит меня дублирование кода и тут на помощь приходит “variable variable” (с таким названием и на помощь, ага), ну смысл в том что можно делать так:
$postfix = $status == 'ok' ? 'neerror' : 'error';
$var = "a_{$status}";
var_dump($$var);
И всё прекрасно работает, но стоит переписать предыдущий пример как:
$postfix = $status == 'ok' ? 'neerror' : 'error';
$var = "a_{$status}";
if ( !isset($$var[$event->type]) ) {
$$var[$event->type] = 0;
}
$$var[$event->type]++;
Как всё перестаёт работать потому что пхп считает что это я пытаюсь забрать символа под номером “$event->type” из строки $var и потом уже этот символ подставить как имя переменной. Но есть решение, Даже два:
$postfix = $status == 'ok' ? 'neerror' : 'error';
$var_temp = "a_{$postfix}";
$var = &$var_temp;
if ( !isset($var[$event->type]) ) {
$var[$event->type] = 0;
}
$var[$event->type]++;
Но ведь это некрасиво, лишняя переменная всё такое. Есть красивое решение:
$postfix = $status == 'ok' ? 'neerror' : 'error';
$var = "a_{$postfix}";
if ( !isset(${$var}[$event->type]) ) {
${$var}[$event->type] = 0;
}
${$var}[$event->type]++;
Или совсем красивое решение без введения лишних переменных:
$postfix = $status == 'ok' ? 'neerror' : 'error';
if ( !isset(${"a_{$postfix}"}[$event->type]) ) {
${"a_{$postfix}"}[$event->type] = 0;
}
${"a_{$postfix}"}[$event->type]++;
А вот сказать почему надо делать такую красоту? Потому что или так, ну чтобы красиво, или многострочный switch()/if() для выбора переменной, а вот так написать нельзя:
$postfix = $status == 'ok' ? &$a_neerror : &$a_error;
$postfix =& $status == 'ok' ? $a_neerror : $a_error;
Как после такого можно не любить пхп? А вот его надо любить потому что решение есть! Красиво и элегантное!!!
$postfix = $status == 'ok' ? 'neerror' : 'error';
$var = "a_{$postfix}";
$var = &$$var; // ЭТО ОНО!!!!
if ( !isset($var[$event->type]) ) {
$var[$event->type] = 0;
}
$var[$event->type]++;
И, внимание, я считаю это победа, но один благодарный читатель мне посоветовал не страдать хернёй и воспользоваться проверенным решением:
$stats = array('neerror'=>array(), 'error'=>array());
$var = &$stats[$status == 'ok' ? 'neerror' : 'error'];
if ( !isset($var[$event->type]) ) {
$var[$event->type] = 0;
}
$var[$event->type]++;
Тот же благодарный читатель сказал мне что я плохой неопытный недопрограммист и мой элегантный пример можно переписать короче:
$postfix = $status == 'ok' ? 'neerror' : 'error';
$var = &${"a_{$postfix}"}; // Вот так
if ( !isset($var[$event->type]) ) {
$var[$event->type] = 0;
}
$var[$event->type]++;
Но я не знаю, мне так не хочется терять красивую конструкцию “$var = &$$var;”… Как же быть?
2013.02.13 20:25