Jump to content
  • 0

Как обойти while


root666
 Share

Question

Здравствуйте помогите пожалуйста, есть календарь, при клике на число всплывает окно с предложением выбрать время на определенный день, вариантов времени штук для дня 10, например 10:15, 12:20 и т.д


Создал таблицу для учета занятости времени с двумя ячейками day,time


day - число


time - время


Соответственно если в условиях к определенному числу время занято то оно просто не предлагается для выбора (это видно в коде) но я сталкнулся с такой проблемой что выводится только последнее время, а не все которые заняты в этот день


Вот таблица


 


Дата          Время


14032014 | 1214032014 | 11 


14032014 | 16


 

Это все конечно решается while, но это все и так уже находится в этом цикле, а два цикла дают левый результат


$ttime = mysql_query("SELECT * FROM time"); // Все варианты времени


while($ttimes = mysql_fetch_array($ttime)) // выводим время циклом
{
$dmy = $days.''.$month.''.$year; // сегодняшняя дата
$etime = mysql_query("SELECT * FROM employ WHERE date=$dmy"); // смотрим все значения с указанной датой

$eetime = mysql_fetch_array($etime); // ВОТ КАК ЗДЕСЬ СДЕЛАТЬ ТАК ЧТОБЫ БЕЗ ЦИКЛА WHILE МОЖНО БЫЛО ПРОЙТИСЬ ПО ВСЕМ ЗНАЧЕНИЯМ?

if($eetime['time'] == $ttimes['id'])
{ } // если время уже занята в этот день то ничего не выводим
else
{
echo '<input type="checkbox" id="check1" name="time" value="'.$ttimes['time'].'"> <br>'; // если свободно то предлагаем записатся
}
}

Помогите пожалуйста


Link to comment
Share on other sites

12 answers to this question

Recommended Posts

  • 0

1) если нужно выводить не конкретные данные из массива, а все, то без цикла никак не обойтись, иначе как вы собираетесь разбирать массив с данными?

2) помимо цикла while, есть еще циклы for и foreach

3) не понятно использования вот этого цикла: while($ttimes = mysql_fetch_array($ttime)) // выводим время циклом

т.к. переменная $ttimes, в которой хранится массив - в коде нигде не используется.

4) а, вот, нашел где она используется, но ради этого так делать - тоже не айс..., к тому же можно было и без условия else написать, вот так:

if($eetime['time'] != $ttimes['id']) {

echo '<input type="checkbox" id="check1" name="time" value="'.$ttimes['time'].'"> <br>'; // если свободно то предлагаем записатся

}

Link to comment
Share on other sites

  • 0

Совет: старайтесь не делать запросы к sql-бд в цикле. Лучше немного продумать и усложнить sql-запрос, чем в цикле опрашивать бд. На то она и бд, чтоб быстро ворочать массивами данных.

 

Если есть таблица с шаблонными временами приемов(time, c колонками id, time) и таблица(employ, c колонками date,time - ссылается на колонку id таблицы time), где на конкретную дату отмечается запись на прием на конкретное время. Тогда лудше написать запрос сразу на получение не занятых часов приемов на указанную дату.
 

SELECT      tm.timeFROM      `time` AS tmLEFT JOIN      `employ` AS epON      tm.id = ep.timeWHERE      ep.date = 'дата' -- отсекаем все даты записей кроме нас интересующей      AND ep.time IS NULL -- отсекаем все часы приема уже заняятые
Link to comment
Share on other sites

  • 0

 

1) если нужно выводить не конкретные данные из массива, а все, то без цикла никак не обойтись, иначе как вы собираетесь разбирать массив с данными?

2) помимо цикла while, есть еще циклы for и foreach

3) не понятно использования вот этого цикла: while($ttimes = mysql_fetch_array($ttime)) // выводим время циклом

т.к. переменная $ttimes, в которой хранится массив - в коде нигде не используется.

4) а, вот, нашел где она используется, но ради этого так делать - тоже не айс..., к тому же можно было и без условия else написать, вот так:

if($eetime['time'] != $ttimes['id']) {

echo '<input type="checkbox" id="check1" name="time" value="'.$ttimes['time'].'"> <br>'; // если свободно то предлагаем записатся

}

Это понятно, спасибо конешн, но если например я напишу так 

while($eetime = mysql_fetch_array($etime)){$eetime['time'];}

То есть в цикле то все равно выводится последнее значение а не все, я так понимаю это нужно записать в начале в массив а потом уже с этим массивом работать, не подскажите как это правильно сделать а то я как не пробовал ничего не выходит

 

Совет: старайтесь не делать запросы к sql-бд в цикле. Лучше немного продумать и усложнить sql-запрос, чем в цикле опрашивать бд. На то она и бд, чтоб быстро ворочать массивами данных.

 

Если есть таблица с шаблонными временами приемов(time, c колонками id, time) и таблица(employ, c колонками date,time - ссылается на колонку id таблицы time), где на конкретную дату отмечается запись на прием на конкретное время. Тогда лудше написать запрос сразу на получение не занятых часов приемов на указанную дату.

SELECT

tm.time

FROM

`time` AS tm

LEFT JOIN

`employ` AS ep

ON

tm.id = ep.time

WHERE

ep.date = 'дата' -- отсекаем все даты записей кроме нас интересующей

AND ep.time IS NULL -- отсекаем все часы приема уже заняятые

Спасибо! А не подскажешь как это теперь практически использовать, т.е в коде, а то я сам ставлю и выходит ошибка, а что это за префиксы "tm"?

Link to comment
Share on other sites

  • 0
А не подскажешь как это теперь практически использовать, т.е в коде.

 

 

Для этого мне нужно знать структуру данных. Вышли результат работы запросов:

SHOW CREATE TABLE `time`;SHOW CREATE TABLE `employ`;
что это за префиксы "tm"?

 

Это псевдоним для таблицы, которая используется в запросе. Если есть запрос с объединением нескольких таблиц, то для конкретизации какой столбик какой именно таблицы нужно(не всегда) указать имя_таблицы.имя_столбца. Имя таблицы может в дальнейшем изменится и его придется править во всем запросе; или имя таблицы может быть ОЧ. длинным и текст запроса сильно вырастет. Поэтом я, обычно, в мультитабличных запросах таблицам даю псевдонимы и при указании на колонку пользую псевдоним таблицы а не ее имя.

 

 

Вот так примерно должно это выглядеть в итоге

<?php/** * */ $date = date('Y.m.d');$sql = 'SELECT      tm.time AS timeFROM      `time` AS tmLEFT JOIN      `employ` AS epON      tm.id = ep.timeWHERE      ep.date = \''. $date .'\'      AND ep.time IS NULL';$result = mysql_query($sql);while ( $tmp = mysql_fetch_assoc($result) ) {  echo '<input type="checkbox" id="check1" name="time" value="'. $tmp['time'] .'"> <br>';}
Edited by CoDy
Link to comment
Share on other sites

  • 0

Спасибо за помощь. 

Таблицы простые, time содержит 2 значения это сообственно time (указанное время например 16:30) и id (уникальный интендификатор)

Структура таблицы time 

time      id

12:00    1

13:00    2

и т.д

Таблица employ содержит занятое время на конкретное число всего 3 значения date (формат даты аля 14032014), time (уникальный интендификатор с таблицы time) и id, всё, больше ничего нету.

Структура таблицы employ 

date            time                   id

14032014   2 (т.е 13:00)     1 (уникальный интендификатор)

 

Логика простая, когда пользователь кликает на дату на календаре в ход идет переменная $dmy (d - дата, m - месяц, y - год, формата 14032014) которая через условие WHERE date=$dmy ищет в таблице employ все айдишнеки time, вот ещё раз код

$ttime = mysql_query("SELECT * FROM time"); // Это выборка по всему времени, то есть оно генерирует все варианты времени предложенные пользователю из таблицы time (12:00, 13:00)$dmy = $days.''.$month.''.$year; // Это число выбранное пользователем, на которое он кликнул$etime = mysql_query("SELECT * FROM employ WHERE date=$dmy"); //Запрос который выводит из таблицы employ (занятое время) варианты уже забронированного времени на конкретную дату на которую кликнул пользователь$eetime = mysql_fetch_array($etime); // Ну это думаю понятноwhile($ttimes = mysql_fetch_array($ttime)) // Этот цикл создает выборку из базы всего времени которое вбито (т.е 12:00, 13:00 и т.д){if($eetime['time'] != $ttimes['id']) // Условие которое при совпадении id времени на конкретную дату с вариантами предложенного общего времени из таблицы time, т.е если на число $dmy в таблице employ id времени из общей таблицы time будет занято то предложенное время из таблицы time не выводится{echo '<input type="checkbox" id="check1" name="time" value="'.$ttimes['time'].'"> <label for="check1">'.$ttimes['time'].'</label><br>'; // Это вывод всего времени из таблицы time}}

Всё бы ничего если бы переменная $eetime['time'] из таблицы занятости времени employ выводила не последнее значение а как бы обходила циклом while и в условии if($eetime['time'] != $ttimes['id']) сравнивала со всеми значениями занятого времени а не с последним, но когда вписываешь цикл while в цикл while который выводит все вписанное время то получается полная фигня

Edited by root666
Link to comment
Share on other sites

  • 0

Ваш вариант с правками:

$ttime = mysql_query("SELECT * FROM time"); // Это выборка по всему времени, то есть оно генерирует все варианты времени предложенные пользователю из таблицы time (12:00, 13:00)$dmy = $year .''. $month .''. $days;$etime = mysql_query("SELECT * FROM employ WHERE date='$dmy'"); //Запрос который выводит из таблицы employ (занятое время) варианты уже забронированного времени на конкретную дату на которую кликнул пользователь// Ваш вариант просто берет одно единственное значение из полученной выборки, а нужно их получить все.// $eetime = mysql_fetch_array($etime); // Ну это думаю понятно // Формируем массив идентификаторов времен, которые уже заняты.$bookedTime = array ();while ( $tmp = mysql_fetch_array($etime) ) {	  $bookedTime[] = $tmp['time'];}while($ttimes = mysql_fetch_array($ttime)) // Этот цикл создает выборку из базы всего времени которое вбито (т.е 12:00, 13:00 и т.д){if( array_search($ttimes['id'], $bookedTime) === false ) // Условие которое при совпадении id времени на конкретную дату с вариантами предложенного общего времени из таблицы time, т.е если на число $dmy в таблице employ id времени из общей таблицы time будет занято то предложенное время из таблицы time не выводится{echo '<input type="checkbox" id="check1" name="time" value="'.$ttimes['time'].'"> <label for="check1">'.$ttimes['time'].'</label><br>'; // Это вывод всего времени из таблицы time}}

Если в таблице дата хранится как тип DATE, тогда дату нужно передавать в формате 'год.месяц.день', закавычивать ЖЕЛАТЕЛЬНО, разделитель частей даты: точка, тире или можно без разделителя.

Мой вариант:

$dmy = $year .''. $month .''. $days;$sql = 'SELECT      tm.time AS timeFROM      `time` AS tmLEFT JOIN      `employ` AS epON      tm.id = ep.time      AND ep.date = \''. $dmy .'\'WHERE            ep.time IS NULL';$result = mysql_query($sql);while ( $tmp = mysql_fetch_assoc($result) ) {  echo '<input type="checkbox" id="check1" name="time" value="'. $tmp['time'] .'"> <br>';}

Немного напортачил с запросом в первом посте.

Link to comment
Share on other sites

  • 0

С одной стороны все работает, ошибок нет, а с другой ну не работает в смысле того что время не убавляется:)

Мой вариант с правками ничего не меняет (время не убирается)

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

В принципе мне все что нужно это вывести массив занятого времени за пределы цикла while а там я дальше думаю разберусь

Вот проблемная часть кода

while($eetime = mysql_fetch_array($etime)) {$test[] = $eetime['time'];} var_dump($test); // Как вывести массив правильно?// Пробовал так $test[0] - ерунда// foreach ($test as $test2) { echo $test2; } - вроде и выводит но очень странно, например на 3 число есть запись на время с id 4 и если кликать на числа до 3 числа то выходит Invalid argument а если после 3 числа то выводится id времени этого числа то есть цифра 4, потом на 14 число есть 2 записи с id времени 1 и 5, после 14 числа куда не кликни выводится уже 415 то есть сумма всех записей в таблице, объясните пожалуйста что не так?

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

$dmy = $days.''.$month.''.$year; // Выбранная дата$etime = mysql_query("SELECT * FROM employ WHERE date=$dmy");

И за пределы выбранной даты скрипт уйти не может это проверялось без цикла while т.е

$eetime = mysql_fetch_array($etime);echo $eetime['time'];

Все выводится правильно, но как только закутываешь в массив в цикле начинают появляться левые значения т.е в этом случае

while($eetime = mysql_fetch_array($etime)) {$test[] = $eetime['time'];} var_dump($test); // Как вывести массив правильно?// Пробовал так $test[0] - ерунда// foreach ($test as $test2) { echo $test2; } - вроде и выводит но очень странно, например на 3 число есть запись на время с id 4 и если кликать на числа до 3 числа то выходит Invalid argument а если после 3 числа то выводится id времени этого числа то есть цифра 4, потом на 14 число есть 2 записи с id времени 1 и 5, после 14 числа куда не кликни выводится уже 415 то есть сумма всех записей в таблице, объясните пожалуйста что не так?
Link to comment
Share on other sites

  • 0
Хехе, все получилось просто ты немного исковеркал формат даты 

 

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

Link to comment
Share on other sites

  • 0

 

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

Не, там такое точно не потребуется :) Ещё раз спасибо

Link to comment
Share on other sites

  • 0
"SELECT      tm.time AS timeFROM      `time`  tmLEFT JOIN      `employ`  epON      tm.id = ep.time      AND ep.date = '". $dmy ."'WHERE            ep.time IS NULL"

И проверь соответствие индексов, по которым таблицы склеиваешь, не думаю что так

tm.id = ep.time , особенно после этого 

WHERE

ep.time IS NULL

Edited by Николя223
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue. See more about our Guidelines and Privacy Policy