0

I have a PHP/mysqli generated form that uses ORDER BY rand() in the mysqli query to randomise options in a decision task (using the code found here).

I came up with a way to validate the user input to match a predefined set of values (see answer for the linked question), which triggers a page reload if the validation conditions aren't met. However, this leads to the form table being generated using a different random order. I would like to display the form table in the same order as in the first page load using php. Additionally, I would like to echo the user input values in the input fields (so the user can see what s/he entered).

Is there a relatively simple way I can achieve this? I've looked into using multidimensional arrays and storing the data in $_SESSION, but none of the solutions seem to be applicable to this problem.

Community
  • 1
  • 1
Wombat
  • 3
  • 5
  • You can use JS-based validation. Check this: http://plugins.jquery.com/validate/ – Heavy May 20 '14 at 07:41
  • Thanks, I am familiar with jQuery validation methods. I am looking for a server-side solution for now. – Wombat May 20 '14 at 07:44
  • You also can add hidden fields to the form to store all necessary information in them. – Heavy May 20 '14 at 07:44
  • And you definitely shouldn't just reload the page after failure. Use $_POST data to populate fields with user's input. This also solves your problem of losing form state. – Heavy May 20 '14 at 07:50
  • I don’t see any reason why storing the necessary info in the session should _not_ work. Another approach you could try, is seed the `RAND()` function with a value of your own choosing (probably determined via PHP’s `rand` beforehand) – same seed value will yield in the same “random” result every time. You can pass that value with your form (or put it into the session), and if you have to re-generate the same form, you pass it to MySQL’s RAND(), otherwise you just get a new random value. – CBroe May 20 '14 at 07:54
  • @CBroe That's what I thought (re: storing info in session), but after searching extensively, I couldn't find any example code or explanation/guidance that could help me understand how to apply this method to this type of problem, which I hope I can find by asking here. – Wombat May 20 '14 at 08:14
  • Fairly easy, instead of outputting your query data directly, put it into an array first – then you put that into the session, and access it from there whenever necessary. – CBroe May 20 '14 at 08:20
  • by the way, RAND() is not such a good idea: http://www.titov.net/2005/09/21/do-not-use-order-by-rand-or-how-to-get-random-rows-from-table/ Maybe you should better get all id's from the db, randomize them in PHP and save the order in session. Then use ORDER BY FIELD(id, yourorder) – lvil May 20 '14 at 08:46
  • @lvil I have seen that article before but consider it irrelevant since my table has a total of four rows. What's your judgement in this instance? – Wombat May 21 '14 at 02:37

1 Answers1

0

I worked out a way to output the identical table to the original using this answer to Sort multidimensional array based on another array, but populated with user input data upon failing validation checks. This is possible thanks to array_column in PHP 5 >= 5.5.0.

if(isset($_SESSION['origVals']) && $_SESSION['origVals'] == true){
    $postOrd = array();
        foreach($_POST["alt_ord"] as $order){
            $postOrd[] = $order;
        }
    $postId = ($_POST['alt_id']);
    $postRnk = array();
        foreach($_POST['rank_'] as $inputRnk){
            $postRnk[] = $inputRnk;
        }

    function resToArray($result){
        $rws = array();
        while($rw = $result->fetch_assoc()){
            $rws[] = $rw;
        }
            return $rws;
}

    $postsql = "SELECT id, alttext FROM `altrank`";
    $result = $link->query($postsql) or die(mysql_error($link));

    $rws = resToArray($result);

    $row = array_column($rws, null, 'id');
    $rows = array();
    foreach ($postId as $k => $id){
        $rows[] = $row[$id];
    }

    for($i = 0; $i < count($rows); $i++){
        $rows[$i]['rank'] = $postRnk[$i];
    }

    $result->close();
    unset($_SESSION['origVals']);

This works for what I want to achieve. I welcome any feedback on how I could improve this code.

Community
  • 1
  • 1
Wombat
  • 3
  • 5