Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Общие вопросы > php+mysql проверка на нахождение в БД информации


Автор: Dmitry_177 12.1.2008, 03:11
как правильнее проверять былали найдена какая-то информация в БД? где-то я видел так:

Код

$select_q = mysql_query("select ...");
if($select_q)
  {
    .. что-то нашли
  }


а где-то видел так:

Код

$select_q = mysql_query("select ...");
if(mysql_num_rows($select_q) > 0)
  {
    .. что-то нашли
  }


а еще так:

Код

$select_q = mysql_query("select ...");
$select_arr = mysql_fetch_array($select_q);
if($select_arr)
  {
    .. что-то нашли
  }


как все же лучше и надежней будет?

Автор: Golda 12.1.2008, 08:43
Если query вернет хотя бы пустой, но валидный result set, разницы между этими вариантами нет  Но в случае, если MySQL вернет ошибку при выполнении запроса, результатом mysql_query() будет FALSE. И попытка использовать этот результат в mysql_num_rows() или mysql_fetch_array() - уже нештатная ситуация, которая выдаст warning. Поэтому первый вариант надежнее. Учтите, ошибка при выполнении запроса не так уж маловероятна в реальной ситуации. Запрос может быть сформирован динамически и сформирован неправильно. Да и просто с соединением может что-то случиться. В этих случаях результатом mysql_query() будет false. 

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

Код

while($select_q = mysql_query("select ...")) {
  $select_arr = mysql_fetch_array($select_q);
}


Для 0 и 1 записи эффект тот же, а если их больше - сразу все результаты получаем  

Автор: GeneralElectric 12.1.2008, 14:48
Golda, формулировка не очень корректная.
Если поставить себя на место среднего читателя, то он не будет разбираться с тем, что возвращает false. Он прочтет, что первый вариант надёжнее. В то время, как это вообще не вариант.
Думаю, более правильным будет сказать, что на вопрос однозначно отвечает только вариант 2, а надёжнее - сочетание первого со вторым.

И while в коде, по-моему, совсем не на месте. Если подразумевается только одна итерация, то в этом месте явно должен быть IF
К тому же, речь, вроде бы, идет, о переборе в цикле результатов одного запроса, а не о выполнении нескольких?

Автор: Golda 12.1.2008, 17:36
Да, GeneralElectric, согласна. Нужно было указать отдельно, что собственно проверки, найдена ли информация по данному запросу, в первом варианте нет. Спасибо за уточнение.

Замечание по поводу while я не поняла. Речь и шла о переборе результатов одного запроса.


Цитата(Golda @  12.1.2008,  08:43 Найти цитируемый пост)

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


Автор: SqueeZe 12.1.2008, 17:53
Golda, ваш цикл будет бесконечным, пока, как вы сами говорили не произойдет ошибка и mysql_query не вернет значение false
Перебор в цикле результатов одного запроса может выглядеть так:

Код

while (list($var1, $var2) = mysql_fetch_array($res)) {
   // что-либо делаем с результатом запроса, например пишем в массивы.
   vars1[] = $var1;
   vars2[] = $var2;
}

Автор: Golda 12.1.2008, 18:39
А - вижу описку. Этот код пишется настолько автоматически, что его детали уже проходят мимо внимания. Конечно, имелось в виду

Код

while($select_arr = mysql_fetch_array($select_q)) {
  ;
}


Полный вариант - 

Код

if ($select_q = mysql_query("select ...")) {
    while($select_arr = mysql_fetch_array($select_q)) {
      ;
    }
}


Спасибо, что заметили. А то еще кого-то запутала бы

Автор: GeneralElectric 12.1.2008, 18:45
Последний вариант, кстати, подводит нас к теме обработки ошибок. Теме интересной и малоизученной.

На практике результат mysql_query можно не проверять. А поставить собаку и mysql_error().
А проверять только конечный результат. Скажем, перед обработкой шаблона написать
if ($data_array===false) doErrorPage();
А про отсутствие данных писатв шаблоне, проверяя количество элементов в массиве.

Автор: Golda 12.1.2008, 20:26
Не хотела сейчас углубляться в эту тему, поскольку она выходит далеко за рамки поставленного вопроса.

Вы подняли на самом деле два вопроса. Если мы обсуждаем разницу между

Код

if (!($res = mysql_query($query)) {
  // какая-то обработка ошибок с доступом информации об ошибке по mysql_error()..
}


и

Код

$res = mysql_query($query);
if (!($row = @mysql_fetch_result()) {
  // какая-то обработка ошибок с доступом информации об ошибке по mysql_error()..
}


это во многом дело вкуса. Я предпочитаю работать без @ Как минимум, это более чистый вариант. А если еще учесть, что чаще всего стандартный обработчик ошибок будет переопределен собственным, использование @ требует особого внимания и учета еще и в обработчике ошибок.

Вторая часть вопроса - выбрасывать какую-то исключительную ситуацию или просто переход по условию сразу или можно подождать до конца обработки всех участвующих в расчете данных. Это во многом зависит от ситуации. Тем более столь конкретное решение, как переход на какую-то страницу для обработки ошибочной ситуации (это если я правильно интерпритировала  название функции doErrorPage()). В любом случае шаблон и пустота элементов результирующего массива (вообще сбор результатов в один результирущий массив) - слишком большая конкретизация, оправданная далеко не для всех задач. 

В некоторых ситуациях, например при первых вызовах (install/update/repare/test) ошибка запроса может оказаться вполне штатной ситуацией, которая требует совершенно конкретной реакции именно на нее и продолжения действий по общей программе. 

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

Я согласна, что во многих случаях, возможно и желательно отложить обработку ошибок на как можно более поздний момент. Это касается обычно ситуаций, когда на любые ошибки мы может отреагировать исключительно однообразно, сообщив об ошибке и/или переведя пользователя на какую-то умолчательную страницу. Да, если в такой ситации обрабатывать все возможные ошибки скопом в конце, основной код чище, а иногда и  быстрее. К такому подходу нас подводит логика обработки exceptions. Но обобщать это тип обработки на все возможные ситуации и рекомендовать для обработки ошибки mysql_query() в качестве общего правила я бы не советовала

Автор: Dmitry_177 13.1.2008, 05:02
по моему вопросу, наверно тогда лучше все же использовать связку первого и второго примера.. т.е. так:

Код

$select_q = mysql_query("select ...");
if($select_q)
  {
    if(mysql_num_rows($select_q) > 0)
      {
        .. что-то нашли
      }
  }


но тут вот какая вещь оказывается еще есть.. smile 
если нужно наоборот, сделать что-то если ничего не нашли.. например перекинуть на какую-то страницу, как лучше сделать? вот так как-то некрасиво:

Код

$select_q = mysql_query("select ...");
if(!$select_q)
  {
    header("Location: page.php");
    exit;
  }
if(mysql_num_rows($select_q) == 0)
  {
    header("Location: page.php");
    exit;
  }


ведь если mysql_query вернет false, то при выполнении mysql_num_rows будет ошибка.. чтобы этого не произошло решил так сделать..

а если сделать так:

Код

$select_q = mysql_query("select ...");
if(!$select_q || mysql_num_rows($select_q) == 0)
  {
    header("Location: page.php");
    exit;
  }


то я не совсем уверен что эта ошибка может невозникнуть..

Автор: Golda 13.1.2008, 10:13
можете быть уверены. PHP не будет проверять второй операнд ||, если первый - true. Так что ошибки не будет

Автор: Dmitry_177 14.1.2008, 11:27
получается что если что-то нашли, тогда тоже можно упростить вот так:

Код

$select_q = mysql_query("select ...");
if($select_q && mysql_num_rows($select_q) > 0)
  {
    .. что-то нашли
  }


и ошибки не будет? или я ошибаюсь?

Автор: Golda 14.1.2008, 14:44
Вы правы. Ошибки не будет

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)