У меня есть оператор if с несколькими условиями, которые я просто не могу понять
if(((ISSET($_SESSION['status'])) && ($_SESSION['username']=="qqqqq")) || ((ISSET($_SESSION['status'])) && ($_SESSION['company']=="wwwwww")) || ((ISSET($_SESSION['status'])) && ($_SESSION['company']=="ffffffff")) || ((ISSET($_SESSION['status'])) && ($_SESSION['company']=="ggggggg")) || ((ISSET($_SESSION['status'])) && ($_SESSION['company']=="hhhhhhh")) || ($_SESSION['LOGINTYPE']=="ADMIN")) {
Предполагается, что он вернется, если статус установлен так же, как и одно из имен компаний OTHERWISE, если logintype является администратором, он также должен возвращать true независимо от компании или статуса
Как насчет этого :
if ( (isset($_SESSION['status']) && $_SESSION['username']=="qqqqq") || (isset($_SESSION['status']) && in_array($_SESSION['company'], array('wwwwww', 'ffffffff', 'ggggggg', 'hhhhhhh'))) || $_SESSION['LOGINTYPE']=="ADMIN" )
Перезаписать условие, чтобы попытаться сделать его более легким для чтения, может помочь:
По крайней мере, переделайте его так, чтобы он читал, что вы сказали, что он должен делать:
Предполагается, что он вернется, если статус установлен так же, как и одно из имен компаний OTHERWISE, если logintype является администратором, он также должен возвращать true независимо от компании или статуса
function mayAccessResource(array $sessionState) { return (hasStatus($sessionState) && isAllowedUserOrCompany($sessionState)) || isAdmin($sessionState); }
Затем добавьте методы для инкапсулирования одиночных тестов:
function hasStatus($sessionState) { return isset($sessionState['status']); } function isAllowedUserOrCompany($sessionState) { return isAllowedUser($sessionState) || isAllowedCompany($sessionState); } function isAllowedUser($sessionState) { return isset($sessionState['user']) && $sessionState['user'] === 'blah'; } function isAllowedCompany($sessionState) { $allowedCompanies = array('foo', 'baz', 'baz'); return isset($sessionState['company']) && in_array($sessionState['company'], $allowedCompanies); } function isAdmin($sessionState) { return isset($sessionState['LOGINTYPE']) && $sessionState['LOGINTYPE'] === 'admin'; }
Это все еще далека от совершенства, потому что он жестко кодирует слишком много информации, но, по крайней мере, теперь он гораздо читабельнее. Поскольку все они работают в состоянии сеанса, было бы намного красивее существовать объект SessionState. Еще лучше было бы дразнить различные возможные состояния сеанса дальше друг от друга и иметь класс Company, User и AccessControl.
Также обратите внимание на комментарии ниже вашего вопроса.
Некоторое форматирование сделало бы намного легче разобрать мысленно =) Кроме того, вы, вероятно, могли бы упростить аспект компании, создав множество разрешенных компаний. Тестирование по одному делает это, если () трудно поддерживать и читать – каждый раз, когда вы добавляете компанию, вы рискуете нарушить логику.
Кроме того, похоже, что если $_SESSION['LOGINTYPE'] == 'ADMIN'
, это переопределение, которое всегда должно быть истинным, в противном случае вам всегда нужно установить $ _SESSION ['status'].
$companies = array( 'wwww'=>true, 'ffff'=>true, 'gggg'=>true, 'hhhh'=>true ); if ( $_SESSION['LOGINTYPE'] == 'ADMIN' || isset($_SESSION['status']) && ( $_SESSION['username'] == 'qqqqq' || isset($companies[$_SESSION['company']]) ) ) { ... }
Или, может быть, более четко:
$pass = false; if ($_SESSION['LOGINTYPE'] == 'ADMIN') { $pass = true; } else if (isset($_SESSION['status'])) { if ($_SESSION['username'] == 'qqqq') $pass = true; if (isset($companies, $_SESSION['company']) $pass = true; } if ($pass) { ... }
Другой вариант:
if (!$_SESSION['LOGINTYPE']=="ADMIN") { return false; } if (!ISSET($_SESSION['status']) { return false } if ($_SESSION['username']=="qqqqq") { return true; } // etc
Или используйте переключатель, начинающийся с третьего условного.
Еще лучше было бы сделать этот объект ориентированным:
if ($this->user->isAdmin()) || $this->user->belongsToCompany($this->allowedCompanies)
Это читается еще лучше благодаря созданию «языка более высокого уровня».
Примечание: речь идет не о том, чтобы наименьший символ был как можно меньше строк.
Почему бы вам не использовать блоки try-catch и установить переменную в true, если случай становится истинным?
Гораздо понятнее читать и поддерживать.
try($foo) { catch x: $bar = true; default: $bar = false; }