Ситуация с курицей и яйцом в печатных строках при поиске в них - PullRequest
0 голосов
/ 03 апреля 2011

Допустим, у меня есть две таблицы SQL:

QYZ: id, uid<user id, FK*>, somedatacolumn
USERS: id<FK*>, name, surname

И $rows - это просто список строк из QYZ, когда я запускаю SELECT * FROM qyz.

Цель - сгенерироватьHTML-таблица, которая выглядит следующим образом:

ID (of QYZ) | User    | Data
    1       | Aaa Bbb | xyzfghh
    2       | Ccc Ddd | dfash
    3       | Aaa Bbb | sdafdfa

Следующий код позволяет мне искать в Data, но не User ...

Пожалуйста, рассмотрите следующий код:

// index.php?q=Something
// Note: the following could have been done through SQL,
// but let's consider it wasn't (I'm well aware of the consequences).
$search=$_REQUEST['q'];
foreach($rows as $i=>$row){
    $found=false;
    foreach((array)$row as $k=>$v){
        if(stripos($v,$search)!==false){
            $found=true;
            break; // <- optimization
        }
    }
    if(!$found)unset($rows[$i]);
}

// And somewhere later on...
echo '<table>';
foreach($rows as $row){
    echo '<tr>';
    foreach((array)$row as $k=>$v){
        echo '<td>';
        echo formatter($row,$k,$v); // <- in truth, I'm using call_user_func(),
                               // but for the sake of argument...
        echo '</td>';
    }
    echo '</tr>';
}
echo '</table>';

// And maybe somewhere earlier, perhaps passed as a function argument...
function formatter($row,$column,$cell){
    switch($column){
        case 'uid':
            $cell=getUser($cell)->name().' '.getUser($cell)->surname();
    }
    return htmlspecialchars(''.$cell,ENT_QUOTES);
}

Я знаю, что это немного перемешано.Надеюсь, это не так сложно понять.Вкратце, вот что он делает:

  • сначала мы отфильтровываем результаты базы данных ($ строк) по поисковому запросу (система поиска очень проста, не предлагают альтернативные поисковые системы, этоне точка ).
  • далее мы печатаем таблицу результатов поиска, используя функцию форматирования ...
  • ..., которую мы могли бы определить где-то ранее *
  • и которые, используя методы кэширования, распечатывают смешанные данные в БД без каких-либо дополнительных запросов (поэтому я не сделал SELECT * FROM xyz, users WHERE xyz.uid=users.id
  • , важно отметить, что в качестве побочного эффекта, Я использую getUser ()

Проблема? Я не могу найти пользователя "John Doe", поскольку во время поиска только идентификаторы пользователя известны (форматированиекак будет сделано позже) [а также тот факт, что пользователь John Doe не существует = P ].

В этом конкретном случае мы могли бы легко исправить это с помощью некоторого специального кодирования (например: добавление getUser к коду поискового фильтра). Но иногда форматированиеЭто довольно сложно, гораздо больше, чем просто преобразование идентификатора в имя (например, разбор WikiMarkup или те же сложные вычисления).

Логическим решением было бы выполнить поиск в конце, то есть после рендерингастрок.С выходной буферизацией (необходимо, так как некоторые вещи в formatter () пишутся напрямую) и strip_tags, это будет так просто:

ob_start();
foreach($rows as $row){
    foreach((array)$row as $k=>$v){
        echo '<td>'.formatter($row,$k,$v).'</td>';
        stripos(strip_tags(ob_get_contents()),$search)!==false
            ? ob_flush() : ob_clean();
    }
}
ob_end_clean();

В основном, мы очищаем буфер, если поисковый запрос соответствует, в противном случае,мы очищаем буфер.

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

О, и подумайте об этомОчистите буферизацию вывода - это абсолютно бессмысленно, если бы мне пришлось вводить нумерацию страниц (что я и собираюсь сделать).

Видите, в чем проблема?Он должен манипулировать / искать сгенерированные данные (поиск), чтобы на самом деле генерировать правильные.Звучит крайне неэффективно по нескольким причинам.

PS : Это важно. Эта система является общей , поэтому я не могу сделать ее конкретной для определенной ситуации.

1 Ответ

0 голосов
/ 03 апреля 2011

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

Почему?Ваш доступ к данным должен получить всю информацию, необходимую для выбора строк в одном раунде запросов.Если вы используете базу данных, вы должны просто иметь возможность объединять таблицы.Если вы не используете базу данных, я бы поставил под сомнение это решение.

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...