Как переделать или доделать фильтр поиска?

Как работает.
Вообщем, делаю анонс игровых серверов. В фильтре два параметра. С кодом, который ниже, при выборе одного параметра нечего не находит, при выборе двух, работает как необходимо: показывает только выбор по двум параметрам. Например, только хроники Interlude, только с рейтами x12.
for ($i = 0; $i < $count; $i++) {
    $servers[$i];
    if (($servers[$i][open_date] > $date) && ($servers[$i][allow] == 1)) {
        $servers_notopened[] = $servers[$i];
    } elseif (isset($_POST['chronicles']) && isset($_POST['raites'])) {
        for ($i = 0; $i < $count; $i++) {
            $servers[$i];
            if ((($servers[$i][open_date] > $date) && ($servers[$i][allow] == 1)) && 
                (($servers[$i][chronicles] == $_POST['chronicles']) && 
                 ($servers[$i][raite] == $_POST['raites']))) {
                $servers_notopened[] = $servers[$i];
            } 
        }
    } 
    if (($servers[$i][open_date] == $date) && ($servers[$i][allow] == 1)) {
        $servers_today[] = $servers[$i];
    } elseif (isset($_POST['chronicles']) && isset($_POST['raites'])) {
        for ($i = 0; $i < $count; $i++) {
            $servers[$i];
            if ((($servers[$i][open_date] == $date) && ($servers[$i][allow] == 1)) && 
                (($servers[$i][chronicles] == $_POST['chronicles']) && 
                 ($servers[$i][raite] == $_POST['raites']))) {
                $servers_today[] = $servers[$i];
            } 
        }
    }
    if (($servers[$i][open_date] < $date) && ($servers[$i][allow] == 1)) {
        $servers_opened[] = $servers[$i];
    } elseif (isset($_POST['chronicles']) && isset($_POST['raites'])) {
        for ($i = 0; $i < $count; $i++) {
            $servers[$i];
            if ((($servers[$i][open_date] < $date) && ($servers[$i][allow] == 1)) && 
                (($servers[$i][chronicles] == $_POST['chronicles']) && 
                 ($servers[$i][raite] == $_POST['raites']))) {
                $servers_opened[] = $servers[$i];
            } 
        }
    }
}

Когда меняю в коде "и" на "или", например,
....
                (($servers[$i][chronicles] == $_POST['chronicles']) ||
                 ($servers[$i][raite] == $_POST['raites'])))
....
, то он перестает выбирать по двум параметрам, как необходимо. При выборе двух, показывает все ссылки с данными параметрами. Например, если выбрал хроники interlude и рейты x1, то показывает все сервера с рейтами х1, и все сервера с хрониками Interlude.
Как должно работать.
Два фильтра, должны работать как по отдельности - либо, только хроники, либо только рейты, так и вместе, конкретно по заданным параметрам, не выбирая все, где есть один из параметров.

з.ы. Код пишу сам, так что, скорее всего он кривой и его можно улучшить. Так как во время написания кода, часто переписывал целые функции, находя уже готовые в самом php. Поэтому очень сильно прошу помочь, уже почти целые сутки ломаю голову, как заставить его работать так, как я хочу.
Если нужны еще какие части кода, пишите, выложу.
  • Вопрос задан
  • 248 просмотров
Решения вопроса 1
iiifx
@iiifx
PHP, OOP, SOLID, Yii2, Composer, PHPStorm
# Метки времени для группировки. Не забываем про часовой пояс ;)
$todayTimestamp = strtotime( date( 'd.m.Y' ) ); # Полночь, сегодня
$tomorrowTimestamp = $todayTimestamp + 86400; # Полночь, завтра

# Фильтруем по хроникам
if ( !empty( $_POST[ 'chronicles' ] ) ) {
    $chroniclesFilter = $_POST[ 'chronicles' ];
    foreach ( $servers as $i => $server ) {
        $chronicle = !empty( $server[ 'chronicles' ] ) ? $server[ 'chronicles' ] : false;
        if ( $chronicle !== $chroniclesFilter ) {
            unset( $server[ $i ] );
        }
    }
}

# Фильтруем по рейтингам
if ( !empty( $_POST[ 'raites' ] ) ) {
    $raitesFilter = $_POST[ 'raites' ];
    foreach ( $servers as $i => $server ) {
        $rate = !empty( $server[ 'raite' ] ) ? $server[ 'raite' ] : false;
        if ( $rate !== $raitesFilter ) {
            unset( $server[ $i ] );
        }
    }
}

# Формируем группы серверов по дате открытия
$todayList = [ ];
$closedList = [ ];
$openedList = [ ];
foreach ( $servers as $server ) {
    $isAllow = isset( $server[ 'allow' ] ) ? (bool) $server[ 'allow' ] : false;
    # Только разрешенные сервера
    if ( $isAllow ) {
        $openDate = DateTime::createFromFormat( 'Y-m-d', $server[ 'open_date' ] )->getTimestamp();
        if ( $openDate >= $tomorrowTimestamp ) {
            # Открывается завтра или позже
            $closedList[] = $server;
        } elseif ( $openDate >= $todayTimestamp ) {
            # Открывается сегодня
            $todayList[] = $server;
        } else {
            # Уже открыт
            $openedList[] = $server;
        }
    }
}

echo '<pre>';
# Все сервера, которые подходят по условиям
var_export( $servers );
# И разбитые по группам
var_export( $todayList );
var_export( $closedList );
var_export( $openedList );
Ответ написан
Пригласить эксперта
Ответы на вопрос 3
@heartdevil
плыву как воздушный шарик
Привет.

Зачем вы сразу весь кусок кода пытаетесь отладить. Сначала проверьте свой первый if (($servers[$i]['open_date'] > $date) && ($servers[$i]['allow'] == 1)) блок , а остальное уберите под комментарии. Попробуйте отдалить это блок, и выводящую результат логику снизу. Прям вардампом везде просматривайте что и как приходит. Если все ок, откройте следущий блок и смотрите его. И так далее.
Ответ написан
elevenelven
@elevenelven
Php Dev @ Amadeus
А у вас включено отображение ошибок?

$servers[ $i ][ open_date ] > $date

open_date - это строка или константа?
Строки пишутся в одинарных или двойных кавычках.
Константы - капсом.

$servers[ $i ][ 'open_date' ] > $date

UPD
А вообще, прочитайте комментарии к коду. Он не будет работать как вы задумали.
<?php

for($i = 0; $i < $count; $i++){
  $servers[ $i ];//Что это?
  if( ( $servers[ $i ][ 'open_date' ] > $date ) && ( $servers[ $i ][ 'allow' ] == 1 ) ){
    $servers_notopened[] = $servers[ $i ];
  }elseif( isset( $_POST['chronicles'] ) && isset( $_POST['raites'] ) ){
    for($i = 0; $i < $count; $i++){//У нас for $i, надо использовать $j 
      $servers[ $i ];
      if( ( ( $servers[ $i ][ 'open_date' ] > $date ) && ( $servers[ $i ][ 'allow' ] == 1 ) )//Мы тут \DateTime сравниваем?!
        && ( ( $servers[ $i ][ 'chronicles' ] == $_POST['chronicles'] )
          && ( $servers[ $i ][ 'raite' ] == $_POST['raites'] ) )
      ){
        $servers_notopened[] = $servers[ $i ];
      }
    }
  }
  if( ( $servers[ $i ][ 'open_date' ] == $date ) && ( $servers[ $i ][ 'allow' ] == 1 ) ){
    $servers_today[] = $servers[ $i ];
  }elseif( isset( $_POST['chronicles'] ) && isset( $_POST['raites'] ) ){
    for($i = 0; $i < $count; $i++){//Есть for по $i,$j используем $p 
      $servers[ $i ];
      if( ( ( $servers[ $i ][ 'open_date' ] == $date ) && ( $servers[ $i ][ 'allow' ] == 1 ) )
        && ( ( $servers[ $i ][ 'chronicles' ] == $_POST['chronicles'] )
          && ( $servers[ $i ][ 'raite' ] == $_POST['raites'] ) )
      ){
        $servers_today[] = $servers[ $i ];
      }
    }
  }
  if( ( $servers[ $i ][ 'open_date' ] < $date ) && ( $servers[ $i ][ 'allow' ] == 1 ) ){
    $servers_opened[] = $servers[ $i ];
  }elseif( isset( $_POST['chronicles'] ) && isset( $_POST['raites'] ) ){
    for($i = 0; $i < $count; $i++){//Есть for по $i,$j,$p используем $q 
      $servers[ $i ];
      if( ( ( $servers[ $i ][ 'open_date' ] < $date ) && ( $servers[ $i ][ 'allow' ] == 1 ) )
        && ( ( $servers[ $i ][ 'chronicles' ] == $_POST['chronicles'] )
          && ( $servers[ $i ][ 'raite' ] == $_POST['raites'] ) )
      ){
        $servers_opened[] = $servers[ $i ];
      }
    }
  }
}
Ответ написан
@Screpka Автор вопроса
Ну, во-первых, написание констант заглавными делается для того, чтобы выделить их на общем фоне переменных. И да, то строка. А также, как с кавычками, так и без них работает без изменений.
$servers[ $i ];//Что это? это просто забыл убрать.
Применил исправления в комментариях. Стало хуже. Теперь сортируется фиг пойми как, то он проходится по всем строкам в массиве и выводит запрашиваемые данные в количестве всех этих строк, повторами. Либо вообще не ищет нечего.

Выкладываю весь код
$link = db_connect();
$servers = servers_all($link);

$date = date('Y' . "-" . 'm' . "-" . 'd');

$count = count($servers);

for ($i = 0; $i < $count; $i++) {
	if (($servers[$i]['open_date'] > $date) && ($servers[$i]['allow'] == 1)) {
		$servers_notopened[] = $servers[$i];
	} elseif (isset($_POST['chronicles']) && isset($_POST['raites'])) {
		for ($i = 0; $i < $count; $i++) {
			if ((($servers[$i]['open_date'] > $date) && ($servers[$i]['allow'] == 1)) && 
				(($servers[$i]['chronicles'] == $_POST['chronicles']) && 
				 ($servers[$i]['raite'] == $_POST['raites']))) {
				$servers_notopened[] = $servers[$i];
			} 
		}
	} 
	if (($servers[$i]['open_date'] == $date) && ($servers[$i]['allow'] == 1)) {
		$servers_today[] = $servers[$i];
	} elseif (isset($_POST['chronicles']) && isset($_POST['raites'])) {
		for ($i = 0; $i < $count; $i++) {
			if ((($servers[$i]['open_date'] == $date) && ($servers[$i]['allow'] == 1)) && 
				(($servers[$i]['chronicles'] == $_POST['chronicles']) && 
				 ($servers[$i]['raite'] == $_POST['raites']))) {
				$servers_today[] = $servers[$i];
			} 
		}
	}
	if (($servers[$i]['open_date'] < $date) && ($servers[$i]['allow'] == 1)) {
		$servers_opened[] = $servers[$i];
	} elseif (isset($_POST['chronicles']) && isset($_POST['raites'])) {
		for ($i = 0; $i < $count; $i++) {
			if ((($servers[$i]['open_date'] < $date) && ($servers[$i]['allow'] == 1)) && 
				(($servers[$i]['chronicles'] == $_POST['chronicles']) && 
				 ($servers[$i]['raite'] == $_POST['raites']))) {
				$servers_opened[] = $servers[$i];
			} 
		}
	}
}

/* сортировка по дате, если нечего нет, то нечего не выводит. Ато таблицы крашаться*/
if (!empty($servers_opened)) {
	foreach ($servers_opened as $k => $v) {
		$r[$k] = $v['open_date'];
	}
}
if (!empty($servers_opened)) {
	array_multisort($r, SORT_ASC, $servers_opened);
}


if (!empty($servers_today)) {
	foreach ($servers_today as $k1 => $v1) {
		$r1[$k1] = $v1['open_date'];
	}
}
if (!empty($servers_today)) {
	array_multisort($r1, SORT_ASC, $servers_today);
}


if (!empty($servers_notopened)) {
	foreach ($servers_notopened as $k2 => $v2) {
		$r2[$k2] = $v2['open_date'];
	}
} 
if (!empty($servers_notopened)) {
	array_multisort($r2, SORT_ASC, $servers_notopened);
}
/* сортировка по дате*/



/* блок поиска*/
/* Рейты в right-box*/
if (!empty($servers)) {
	foreach ($servers as $key3 => $value3) {
		$raite_search[$key3] = $value3['raite'];
	}
} 
$servers_raite = array_unique($raite_search);
array_multisort($raite_search, SORT_ASC, $servers);

if (!empty($servers)) {
	foreach ($servers as $key4 => $value4) {
		$chronicle_search[$key4] = $value4['chronicles'];
	}
} 
$servers_chronicle = array_unique($chronicle_search);
array_multisort($chronicle_search, SORT_ASC, $servers);

/* блок поиска*/

Пример одной из таблиц, куда выводится инфа.
<table class="middle_container_table_1">
					<caption>
						<h2>Уже открылись</h2></caption>
					<? 
					if (empty($servers_opened)) {
						echo "<br>";
					} elseif (!empty($servers_opened)) {
						foreach($servers_opened as $a) { ?>
						<tr>
							<td>
								<!--<span><?=$a['vip']?></span>-->
							</td>
							<td>
								<a href="http://<?=$a['server_adres']?>">
									<?=$a['server_adres']?>
								</a>
							</td>
							<td>
								<span><?="x" . $a['raite']?></span>
							</td>
							<td>
								<span><?=$a['chronicles']?></span>
							</td>
							<td>
								<span><?=$a['open_date']?></span>
							</td>
							<td>
								<!--<span><?=$a['vip']?></span>-->
							</td>
						</tr>
						<? }} ?>
				</table>


выборка всех данных из таблицы
function servers_all($link) {
	//запрос 
	$query = "SELECT * FROM add_servers ORDER BY id_server DESC";
	$result = mysqli_query($link,$query);
	
	if (!$result) 
		die(mysqli_error($link));
	
	//Извлечени из БД
	$n = mysqli_num_rows($result);
	$servers = array();
	
	for ($i = 0; $i < $n; $i++)
	{
		$row = mysqli_fetch_assoc($result);
		$servers[] = $row;
		$servers1[] = $row;
		$servers2[] = $row;
		$servers3[] = $row;
	}
	return $servers;
	mysqli_free_result($result);
}


А это форма фильтра
<form method="post" action="">
						<label>
							<p>Версия игры</p>
							<select name="chronicles">
								<option></option>
								<? foreach ($servers_chronicle as $a): ?>
									<option>
										<?=$a?>
									</option>
									<? endforeach ?>
							</select>
							<br>
						</label>
						<label>
							<p>Рейты</p>
							<select name="raites">
								<option></option>
								<? foreach ($servers_raite as $a): ?>
									<option>
										<?=$a?>
									</option>
									<? endforeach ?>
							</select>
							<br>
						</label>
						<button type="submit" class="submit-search">Искать</button>
					</form>

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

По поводу вопроса: "Включено ли отображение ошибок?", то нет. Сам еще не знаю как, и не искал. Вроде php и так ошибки показывает, когда что-то не работает. Все эти ошибки я устраняю.

А как бы вы сделали фильтр?

Для Виталий IIIFX Хоменко:
array(6) { ["id_server"]=> string(3) "107" ["server_adres"]=> string(4) "test" ["chronicles"]=> string(9) "Interlude" ["raite"]=> string(2) "12" ["open_date"]=> string(10) "2016-01-12" ["allow"]=> string(1) "1" } 
array(6) { ["id_server"]=> string(3) "106" ["server_adres"]=> string(4) "test" ["chronicles"]=> string(7) "Classic" ["raite"]=> string(1) "1" ["open_date"]=> string(10) "2016-01-31" ["allow"]=> string(1) "1" } 
array(6) { ["id_server"]=> string(3) "105" ["server_adres"]=> string(8) "testtest" ["chronicles"]=> string(7) "Classic" ["raite"]=> string(1) "1" ["open_date"]=> string(10) "2016-01-31" ["allow"]=> string(1) "1" } 
array(6) { ["id_server"]=> string(3) "104" ["server_adres"]=> string(8) "testtest" ["chronicles"]=> string(7) "Classic" ["raite"]=> string(1) "1" ["open_date"]=> string(10) "2016-01-31" ["allow"]=> string(1) "1" } 
array(6) { ["id_server"]=> string(3) "103" ["server_adres"]=> string(4) "test" ["chronicles"]=> string(10) "Interlude+" ["raite"]=> string(2) "12" ["open_date"]=> string(10) "2016-01-29" ["allow"]=> string(1) "1" } 
array(6) { ["id_server"]=> string(3) "102" ["server_adres"]=> string(3) "545" ["chronicles"]=> string(9) "Interlude" ["raite"]=> string(3) "456" ["open_date"]=> string(10) "2016-01-22" ["allow"]=> string(1) "1" } 
array(6) { ["id_server"]=> string(3) "101" ["server_adres"]=> string(4) "2424" ["chronicles"]=> string(9) "Interlude" ["raite"]=> string(3) "234" ["open_date"]=> string(10) "2016-01-14" ["allow"]=> string(1) "1" } 
array(6) { ["id_server"]=> string(2) "93" ["server_adres"]=> string(5) "test1" ["chronicles"]=> string(5) "Final" ["raite"]=> string(2) "12" ["open_date"]=> string(10) "2015-12-31" ["allow"]=> string(1) "1" } 
array(6) { ["id_server"]=> string(2) "91" ["server_adres"]=> string(4) "test" ["chronicles"]=> string(10) "Interlude+" ["raite"]=> string(2) "12" ["open_date"]=> string(10) "2016-01-13" ["allow"]=> string(1) "1" } 
array(6) { ["id_server"]=> string(2) "90" ["server_adres"]=> string(4) "test" ["chronicles"]=> string(9) "Interlude" ["raite"]=> string(2) "12" ["open_date"]=> string(10) "2016-01-12" ["allow"]=> string(1) "1" } 
array(6) { ["id_server"]=> string(2) "89" ["server_adres"]=> string(4) "test" ["chronicles"]=> string(9) "Interlude" ["raite"]=> string(3) "123" ["open_date"]=> string(10) "2016-01-07" ["allow"]=> string(1) "1" } 
array(6) { ["id_server"]=> string(2) "87" ["server_adres"]=> string(4) "test" ["chronicles"]=> string(7) "Classic" ["raite"]=> string(2) "12" ["open_date"]=> string(10) "2016-01-13" ["allow"]=> string(1) "1" } 
array(6) { ["id_server"]=> string(2) "67" ["server_adres"]=> string(8) "testtest" ["chronicles"]=> string(7) "Classic" ["raite"]=> string(1) "1" ["open_date"]=> string(10) "2016-01-31" ["allow"]=> string(1) "1" } 
array(6) { ["id_server"]=> string(2) "66" ["server_adres"]=> string(9) "234234tes" ["chronicles"]=> string(2) "IO" ["raite"]=> string(1) "1" ["open_date"]=> string(10) "2016-01-14" ["allow"]=> string(1) "1" } 
array(6) { ["id_server"]=> string(2) "65" ["server_adres"]=> string(6) "234234" ["chronicles"]=> string(7) "Classic" ["raite"]=> string(3) "234" ["open_date"]=> string(10) "2016-01-11" ["allow"]=> string(1) "1" }

по строкам сделал, так глазу приятнее.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы