2

ドロップダウン リストのあるフォームを使用してフィルターを作成しました。フィルターは、mySQL データベースからの結果をフィルター処理するために使用されます。フォームは結果と同じページで処理されます。結果がフィルタリングされた後、フィルタードロップダウンリストがフィルターパラメーターを保持するようにしたいと思います。

過去にセッションを使用してこれを行ったことがありますが、それは別のページを使用してクエリを処理したときでした。これと同じ理論を適用しようとしましたが、うまくいきません。このサイトと Google を検索しましたが、別の処理ページに関連する回答しか見つかりませんでした。

現在、私が持っているコードは、フォームが 2 回送信された後にのみ事前入力されます。初めて送信されると、「選択...」のデフォルト設定が表示されます

私のコードの関連セクションは次のとおりです。

session_start();
if(isset($_SESSION['submitted_filter_values']))
{
extract($_SESSION['submitted_filter_values']);
}

<form action="#filter" method="post" name="filter">
<table>

<tr>
<td>
<select name="prefix">
<option value="">Select...</option>
<option <?php if(isset($prefix) && $prefix == "PDM"){echo "selected=\"selected\"";} ?> value="PDM">PDM</option>
<option <?php if(isset($prefix) && $prefix == "TB"){echo "selected=\"selected\"";} ?> value="TB">TB</option>
<option <?php if(isset($prefix) && $prefix == "JNL"){echo "selected=\"selected\"";} ?> value="JNL">JNL</option>
</select>
</td>
</tr>

<tr align="center">
<td colspan="2"><input type="submit" class="btn_150x30" name="submit" value="Filter Results"></td>
</tr>

</table>
</form>

$_SESSION['submitted_filter_values'] = $_REQUEST;

セッション変数を別の場所に配置しようとしましたが、うまくいきませんでした。ページを更新するとうまくいくと思いましたが、フォームを2回送信したときのように、フィルターを効果的に削除できると考えました。注意すべき興味深い点は、送信するたびに文字通り機能するという点で非常に一貫性があることです。

4

5 に答える 5

3

これを試して:

<?php 
    session_start();

    if(isset($_POST['prefix'])){
        // if the form has been posted use it
        $prefix = $_POST['prefix']; // <------ RUN SOME VALIDATION HERE!!!!!!!
        $_SESSION['submitted_filter_values'] = $prefix; // update the session var

    }elseif(isset($_SESSION['submitted_filter_values'])){
        // if the form hasn't been posted then look in the $_SESSION
        $prefix = $_SESSION['submitted_filter_values']; // <------ RUN SOME VALIDATION HERE (trust no one!)!!!!!!!
    }



?>
    <form action="#filter" method="post" name="filter">
        <table>

            <tr>
                <td>
                    <select name="prefix">
                        <option value="">Select...</option>
                        <option<?php if($prefix == "PDM"){echo " selected=\"selected\"";} ?> value="PDM">PDM</option>
                        <option<?php if($prefix == "TB"){echo " selected=\"selected\"";} ?> value="TB">TB</option>
                        <option<?php if($prefix == "JNL"){echo " selected=\"selected\"";} ?> value="JNL">JNL</option>
                    </select>
                </td>
            </tr>
            <tr align="center">
                <td colspan="2">
                    <input type="submit" class="btn_150x30" name="submit" value="Filter Results" />
                </td>
            </tr>

        </table>
    </form>
于 2012-11-04T09:42:38.817 に答える
2

これは、リクエストとセッションの問題です。スクリプトの処理を正しく行うと、次のような状況になります。

最初の送信では、セッションsubmitted_filter_valuesは設定されていません。デフォルトのエントリが表示され、$prefix未設定のままです。

2 回目の送信では、select タグを出力したsubmitted_filter_values 後にセッションを設定します。その順序のため、デフォルトのエントリが引き続き表示されます。

3 回目の送信では、2 回目の送信のフィルターが表示されます。

4 番目の送信では、3 番目の送信のフィルターが表示されます。などなど。

送信せずに GET 経由でリクエストするだけの場合、その値は残りますが、含まれていないsubmitted_filter_valuesため、セッションをデフォルトに戻します。$_REQUESTprefix

この順序を確認すると、スクリプトを変更するのにも役立ちます。経験則の 1 つは、入力変数 (設定されているかどうかにかかわらず) をスクリプト上で処理することです。@Chris を書いているときに、このためのコードが既に提供されています。

まず最初にフィルタを定義し、リクエストとセッション ロジックの両方を使用してそれらを 1 つずつ処理し、フォームを出力します。これには、上部のデータロジックと出力の出力ロジックを変更するという利点があります。

<?php
session_start();

/**
 * define your filter(s)
 */
$filters = array(
    'prefix' => array(
        'value' => null,
        'list' => array('PDM', 'TB', 'JNL')
    )
);

$filtersSessionName = 'submitted_filter_values';

/**
 * process the state of your filter(s) with request input and
 * session state
 */
foreach($filters as $name => $filter) {

    // does request has filter value set?
    if (isset($_REQUEST[$name])) {
        $requestValue = $_REQUEST[$name];
        // does it validate?
        if (in_array($requestValue, $filter['list'])) {
            $filter['value'] = $requestValue;
            $_SESSION[$filtersSessionName][$name] = $requestValue;
            continue;
        }
    }

    // does the session has filter value set?
    if (isset($_SESSION[$filtersSessionName][$name])) {
        $sessionValue = $_SESSION[$filtersSessionName][$name];
        // does it validate?
        if (in_array($sessionValue, $filter[$list])) {
            $filter['value'] = $sessionValue;
            continue;
        }
    }
}


/**
 * output the filter(s) in the form
 */
?>

<form action="#filter" method="post" name="filter">
    <table>
        <?php foreach($filters as $name => $filter) { ?>
            <tr>
                <td>
                    <select name="<?php echo $name; ?>">
                        <option value="">Select ...</option>
                        <?php foreach($filter['values'] as $label) {
                            $selected = $filter['value'] === $label;
                        ?>
                            <option <?php if ($selected) { echo 'selected="selected"';} ?> value="<?php echo $label ?>">
                                <?php echo $label ?>
                            </option>
                        <?php } ?>
                    </select>
                </td>
            </tr>
        <?php } # foreach filters ?>
        <tr align="center">
            <td colspan="2"><input type="submit" class="btn_150x30" name="submit" value="Filter Results"></td>
        </tr>
    </table>
</form>

これは、フィルター リストにキーと値のペアを使用することでさらに改善できます。これにより、フィルターのラベルが送信される値と異なる場合があります。また、$_REQUEST変数にプレフィックスを付けて、セッションで既に行われているように、フィルターの名前がリクエスト変数で名前空間化されるようにすることもできます。

于 2012-11-04T09:43:37.007 に答える
1

結果の処理方法を変更する必要があります$REQUEST

<?php
session_start();
if (isset($REQUEST))  // do we have a submitted request?
{         // yes -> save it in session

    $_SESSION['submitted_filter_values']['prefix'] = $REQUEST['prefix'];
    $prefix = $REQUEST['prefix'];

} else {  // no -> try to retrieve it from the session

   if(isset($_SESSION['submitted_filter_values']))
   {
      $prefix = extract($_SESSION['submitted_filter_values']['prefix']);
   }

}
?>

<form action="#filter" method="post" name="filter">
<table>

<tr>
<td>
<select name="prefix">
<option value="">Select...</option>
<option <?php if(isset($prefix) && $prefix == "PDM"){echo "selected=\"selected\"";} ?> value="PDM">PDM</option>
<option <?php if(isset($prefix) && $prefix == "TB"){echo "selected=\"selected\"";} ?> value="TB">TB</option>
<option <?php if(isset($prefix) && $prefix == "JNL"){echo "selected=\"selected\"";} ?> value="JNL">JNL</option>
</select>
</td>
</tr>

<tr align="center">
<td colspan="2"><input type="submit" class="btn_150x30" name="submit" value="Filter Results"></td>
</tr>

</table>
</form>

に関してextractは、不要な値が含まれている可能性のある$REQUEST配列のような信頼できない入力で使用することは非常に悪い習慣です。$ REQUESTを使用しているため、スクリプト内の特定の値をオーバーライドするいくつかのパラメーターを使用して、そのページをターゲットとするURLを偽造していると想像してください。これらの値を抽出し、変数を危険な値で上書きする可能性があります。prefixそのため、$REQUEST配列から値をコピーするだけです。

于 2012-11-04T09:46:55.397 に答える
0

現在のスニペットコードに従って、コードのシーケンスを以下のように設定する必要があると思います

if(isset($_REQUEST))
{
   $_SESSION['submitted_filter_values'] = $_REQUEST;
}

if(isset($_SESSION['submitted_filter_values']))
{
   extract($_SESSION['submitted_filter_values']);
   unset($_SESSION['submitted_filter_values']);
}
于 2012-11-04T09:43:52.120 に答える
0

セッションは 1 つのページでのみ使用され、サイト全体では使用されていないため、私のアプリケーションには適していないことに気付いた後、この問題に対して新たなアプローチを取りました。

フィルターの上部には、各オプションに対して次のものがあります。

if(isset($_POST['prefix']))
    {
    $prefix = $_POST['prefix'];
    }

次に、ドロップダウン リストに、各オプションについて次のように表示します。

<option <?php if(isset($prefix) && $prefix == "PDM"){echo "selected=\"selected\"";} ?> value="PDM">PDM</option>
于 2012-11-05T04:39:50.057 に答える