PHP - возвращает несколько состояний, а не только true / false - PullRequest
1 голос
/ 26 августа 2010

У меня есть концептуальная проблема, связанная с классами PHP и обработкой ошибок. Ниже приведен базовый класс, демонстрирующий мою проблему.

Существует функция для создания записи базы данных с именем "domain_create".Эта функция вызывает вторичную функцию, чтобы убедиться, что создаваемый домен еще не существует в таблице базы данных.

В прошлом я всегда использовал true или false, чтобы отразить, если функция нашла запись, но это создает недостаток в моей логике. Записи вставляются, когда функция domain_lu возвращает false, однако это следует делатьесли обнаружена ошибка, например, ошибка выбора?Возврат false приведет к тому, что функция create поверит, что ничего не найдено, и продолжит процесс создания ..

Мой вопрос: как должно отражаться несколько состояний в этом сценарии?Есть ли «лучшая практика» для этого сценария?

<?php

require_once('auth.base.class.php');
require_once('mysql.class.php');

class auth extends base
{
   public function __construct()
   {
      parent::__construct();
   }

   /*
    * User
    */

   public function domain_create($args='')
   {
      if ( domain_lu($args['dname']) === FALSE )  
      {
         return $error['Domain already in use'];
      }
   }

   /* 
    * Domain
    */

   private function domain_lu($dname)
   {
      $sql = "SELECT name FROM domain WHERE name = '$dname'";
      $this->_mysql->SQLQuery($sql); 

      if ($this->_mysql->numRow() > 0) return true; 
      else return false;
   }
}

?>

Ответы [ 3 ]

8 голосов
/ 26 августа 2010

Вы должны использовать Исключения . Если есть ошибка запроса, выведите исключение с указанием причины сбоя. Если домен уже существует, выведите исключение, сообщающее, что домен уже существует. Вот очень простой пример:

   public function domain_create($args='')
   {
      if (!$this->domain_lu($args['dname']))  
          throw new Exception('domain already in use');
   }

   private function domain_lu($dname)
   {
      $sql = "SELECT name FROM domain WHERE name = '$dname'";
      $this->_mysql->SQLQuery($sql); // SQLQuery should throw an exception if it fails
      return ($this->_mysql->numRow() > 0);
   }

Вы должны действительно создать специализированные классы исключений, чтобы пользователь мог перехватить конкретное исключение, не полагаясь только на одно сообщение об исключении, в документации PHP есть больше информации об этом. Но, в основном, выполнение этих действий приведет к выходу из функции, как только будет сгенерировано исключение, и вернется назад, если есть код, который перехватывает исключение. Или, если он нигде не пойман, PHP прекратит работу скрипта.

4 голосов
/ 26 августа 2010

У вас есть два варианта: использовать исключения или определить константы ошибок, например

class auth extends base
{
   const E_OK = 0;
   const E_NOTFOUND = 1;
   const E_FAILURE = 2;
//[snip]

   private function domain_lu($dname)
   {
      $sql = "SELECT name FROM domain WHERE name = '$dname'";
      if(!$this->_mysql->SQLQuery($sql)) return self::E_FAILURE;
      if ($this->_mysql->numRow() > 0) return self::E_OK; 
      else return self::E_NOTFOUND;
   }
}
0 голосов
/ 26 августа 2010

ИМО, вы решаете это не в том месте. Если вам нужно убедиться, что столбец базы данных не может содержать повторяющиеся значения, вам следует создать этот столбец с ключом UNIQUE :

Индекс UNIQUE создает ограничение, так что все значения в индексе должны быть различны. При попытке добавить новую строку со значением ключа, совпадающим с существующей строкой, возникает ошибка. Для всех механизмов индекс UNIQUE допускает несколько значений NULL для столбцов, которые могут содержать NULL.

Обходы БД, как правило, являются узкими местами в приложениях, поэтому преимущество заключается в том, что вам не нужно отправлять два запроса к вашей базе данных (один для проверки, один для вставки). Просто запустите ваш запрос и посмотрите, был ли он успешным, а если нет, получите и верните ошибку или сгенерируйте соответствующий Exceptions.

...