Jump to content

Dynamically names variables and form name attributes not working correctly


Go to solution Solved by mac_gyver,

Recommended Posts

I have a form on my samplepage1.php page.  One part of the form needs to have the name attributes named dynamically because there could 1 to 25 rows in the table that are retrieved by the query and display them.  This part is working fine.  When I submit the form, it goes to samplepage1viewinclude.php and it's supposed to run updates queries to update the information the user changed.  I can't figure out how to dynamically declare the variables, then set the variables equal to a $_REQUEST[] value from the form and then run the update query.  Being that there could be 6 to 150 variable names and form name attirbutes, depending on how rows the query returned, I thought this would be the best way to name the variables and name attributes.  Any advice, suggestions or recommendations will be greatly appreciated

Here is the code for samplepage1.php queries the DB, then displays the data where the user can either view the results or make changes and submit them:

<?php
//==============================================================================================================================//
//==OPEN CONNECTION TO MYSQL ON LOCALHOST ======================================================================================//
$dbhost = 'localhost' ;
$username = 'some username' ;
$password = 'blahblahblah' ;
$conn = mysqli_connect("$dbhost", "$username", "$password");
if (!$conn) { 
die('Could not connect: ' . mysqli_error()); 
}
mysqli_select_db($conn, "courtdirectory");


//==============================================================================================================================//
//==DO THIS WHEN FORM IS SUBMITTED==============================================================================================//
if ($_SERVER["REQUEST_METHOD"] == "POST") 
{
    if (isset($_POST['submit'])){
        include('samplepage1viewinclude.php');
    }
}


    echo "
    <form class='form-container form' action= " .$_SERVER['PHP_SELF']. " method='post'>";
//==============================================================================================================================//
//  - FOR THIS EXAMPLE THERE ARE 2 ROWS IN THE CCAL TABLE WITH CCALCOUNTYID = 221
//==============================================================================================================================//

//==============================================================================================================================//
//  - FOR EACH CCALCOUNTYID THERE COULD BE 1 TO 25 ROWS RETRIEVED DEPENDING ON THE COUNTY THAT IS WHY I USED THE FOREACH LOOPS
//  TO NAME THE VARAIABLES AND FORM FIELD NAMES
//==============================================================================================================================//
        $sql1 = "SELECT * FROM cd006ccals
        WHERE cd006ccals.ccalcountyid = 221";
        $results1 = mysqli_query($conn, $sql1);	
        $datas = array();
        if (mysqli_num_rows($results1) > 0) {
            while($row = $results1->fetch_assoc()) {
                $datas[] = $row;
            }
        }
        $index = 1;
        foreach($datas as $data)
        {
            ${"varccal".$index."id"}       = $data['ccalid'];
            ${"varccal".$index."countyid"} = $data['ccalcountyid'];
            ${"varccal".$index."court"}    = $data['ccalcourt'];
            ${"varccal".$index."judge"}    = $data['ccaljudge'];
            ${"varccal".$index."address"}  = $data['ccaladdress'];
            ${"varccal".$index."phone"}    = $data['ccalphone'];
            ${"varccal".$index."fax"}      = $data['ccalfax'];
            ${"varccal".$index."notes"}    = $data['ccalnotes'];
            echo "
            <div class='ccalboxgrid'>
                <div class='ccalbox ccalcourt'>Court Type</div>
                <div class='ccalbox ccaljudge'>Judge</div>
                <div class='ccalbox ccaladdress'>Address</div>
                <div class='ccalbox ccalphone'>Phone</div>
                <div class='ccalbox ccalfax'>Fax</div>
                <div class='ccalbox ccalnotes'>Notes</div>
                <div class='ccalbox ccalcourt-textarea'><textarea class='ccalcourt-somebad' name=${"varccal".$index."court"} value=${"varccal".$index."court"}>${"varccal".$index."court"}</textarea></div>
                <div class='ccalbox ccaljudge-textarea'><textarea class='ccaljudge-somebad' name=${"varccal".$index."judge"} value=${"varccal".$index."judge"}>${"varccal".$index."judge"}</textarea></div>
                <div class='ccalbox ccaladdress-textarea'><textarea class='ccaladdress-somebad' name=${"varccal".$index."address"} value=${"varccal".$index."address"}>${"varccal".$index."address"}</textarea></div>
                <div class='ccalbox ccalphone-textarea'><textarea class='ccalphone' name=${"varccal".$index."phone"} value=${"varccal".$index."phone"}>${"varccal".$index."phone"}</textarea></div>
                <div class='ccalbox ccalfax-textarea'><textarea class='ccalfax' name=${"varccal".$index."fax"} value=${"varccal".$index."fax"}>${"varccal".$index."fax"}</textarea></div>
                <div class='ccalbox ccalnotes-textarea'><textarea class='ccalnotes' name=${"varccal".$index."notes"} value=${"varccal".$index."notes"}>${"varccal".$index."notes"}</textarea></div>
            </div>";
            $index++;
        }
            echo "
            <div class='formfieldgroup'>
                <button type='submit' class='courtdirectory-submit' name='submit' tabindex='6' data-submit='...Sendng'>Update</button>
            </div>";
    echo "
    </form>";


?>

 

IF the user changes any data on samplepage1.php and hits the Submit button, the sample1viewinclude.php code runs.  This is where I'm getting the errors.  Here is the code for saple1viewinclude.php:

<?php


//==============================================================================================================================//
//  - FOR THIS EXAMPLE THERE ARE 2 ROWS IN THE CCAL TABLE WITH CCALCOUNTYID = 100
//==============================================================================================================================//

$mycountyid = $this_id = "";

/*
$index = 1;
echo "TEST TO SEE IF CCALCOURT VALUE IS RETURNED: " . $_REQUEST['varccal'.$index.'court'];
*/



//==============================================================================================================================//
//  HERE IS THE CODE I HAVE TRIED SO FAR, BUT I KEEP GETTING ERRORS
//==============================================================================================================================//

//==============================================================================================================================//
//  QUERYING CCAL TABLE TO GET THE NUMBER OF ROWS RETRIEVED

$mycountyid = "221";

$sql1 = "SELECT * FROM cd006ccals
WHERE cd006ccals.ccalcountyid = " . $mycountyid;
$results1 = mysqli_query($conn, $sql1);	
$datas = array();
if (mysqli_num_rows($results1) > 0) {
    while($row = $results1->fetch_assoc()) {
        $datas[] = $row;
    }
}
//==============================================================================================================================//
//  START LOOPING THROUGH THE RESULTS TO SET VARIABLES AND GET FORM FIELD ENTRIES FROM SAMPLEPAG1.PHP;  THIS ALSO SETS THE VALUE
//  FOR $THIS_ID TO BE USED FOR THE UPDATE QUERY
//==============================================================================================================================//
$index = 1;
foreach($datas as $data)
{
$this_id = $data['ccalid'];
${"varccal".$index."id"}       = "";
${"varccal".$index."countyid"} = "";
${"varccal".$index."court"}    = "";
${"varccal".$index."judge"}    = "";
${"varccal".$index."address"}  = "";
${"varccal".$index."phone"}    = "";
${"varccal".$index."fax"}      = "";
${"varccal".$index."notes"}    = "";

//==============================================================================================================================//
//  THE LINES BELOW ARE WHERE THE ERRORS START
//==============================================================================================================================//
${"varccal".$index."court"}   = $_REQUEST['varccal'.$index.'court'];
${"varccal".$index."judge"}   = $_REQUEST['varccal'.$index.'judge'];
${"varccal".$index."address"} = $_REQUEST['varccal'.$index.'address'];
${"varccal".$index."phone"}   = $_REQUEST['varccal'.$index.'phone'];
${"varccal".$index."fax"}     = $_REQUEST['varccal'.$index.'fax'];
${"varccal".$index."notes"}   = $_REQUEST['varccal'.$index.'notes'];
//==============================================================================================================================//
//==============================================================================================================================//


//==============================================================================================================================//
/*  HERE THE ERRORS I KEEP GETING FROM THE 6 LINES OF CODE ABOVE
Warning: Undefined array key "varccal1court" in C:\xampp\htdocs\myreliantservices\samplepage1viewinclude.php on line 55

Warning: Undefined array key "varccal1judge" in C:\xampp\htdocs\myreliantservices\samplepage1viewinclude.php on line 56

Warning: Undefined array key "varccal1address" in C:\xampp\htdocs\myreliantservices\samplepage1viewinclude.php on line 57

Warning: Undefined array key "varccal1phone" in C:\xampp\htdocs\myreliantservices\samplepage1viewinclude.php on line 58

Warning: Undefined array key "varccal1fax" in C:\xampp\htdocs\myreliantservices\samplepage1viewinclude.php on line 59

Warning: Undefined array key "varccal1notes" in C:\xampp\htdocs\myreliantservices\samplepage1viewinclude.php on line 60

Warning: Undefined array key "varccal2court" in C:\xampp\htdocs\myreliantservices\samplepage1viewinclude.php on line 55

Warning: Undefined array key "varccal2judge" in C:\xampp\htdocs\myreliantservices\samplepage1viewinclude.php on line 56

Warning: Undefined array key "varccal2address" in C:\xampp\htdocs\myreliantservices\samplepage1viewinclude.php on line 57

Warning: Undefined array key "varccal2phone" in C:\xampp\htdocs\myreliantservices\samplepage1viewinclude.php on line 58

Warning: Undefined array key "varccal2fax" in C:\xampp\htdocs\myreliantservices\samplepage1viewinclude.php on line 59

Warning: Undefined array key "varccal2notes" in C:\xampp\htdocs\myreliantservices\samplepage1viewinclude.php on line 60

Fatal error: Uncaught mysqli_sql_exception: You have an error in your SQL syntax; check the manual that corresponds to your
MariaDB server version for the right syntax to use near ' ccaljudge = , ccaladdress = , ccalphone = ...' at line 2 in
C:\xampp\htdocs\myreliantservices\samplepage1viewinclude.php:118 Stack trace: #0 C:\xampp\htdocs\myreliantservices\samplepage1viewinclude.php(120):
mysqli->query('UPDATE ccal SET...') #1 C:\xampp\htdocs\myreliantservices\samplepage1.php(43): include('C:\\xampp\\htdocs...')
#2 {main} thrown in C:\xampp\htdocs\myreliantservices\samplepage1viewinclude.php on line 120
*/
//==============================================================================================================================//

$sql2 = "UPDATE ccal SET
ccalcourt             = ${"varccal".$index."court"},
ccaljudge             = ${"varccal".$index."judge"},
ccaladdress           = ${"varccal".$index."address"},
ccalphone             = ${"varccal".$index."phone"},
ccalfax               = ${"varccal".$index."fax"},
ccalnotes             = ${"varccal".$index."notes"}
WHERE ccalid          = ".$this_id;

$index++;
}
//==============================================================================================================================//
//  END LOOP 
//==============================================================================================================================//


//==============================================================================================================================//
//  DISPLAY SUCCESS OR ERROR MESSAGE WHEN EVERYTHING IS DONE RUNNING
//==============================================================================================================================//
//==============================================================================================================================//
/*  GET THE FOLLOWING ERROR BECAUSE THE VARIABLES ARE BEING SET IN THE UPDATE QUERY  */
if ($conn->query($sql2) === TRUE) {
    $success = "<p class='success'>Record updated successfully</p>";
/*
    $varid = $varcounty = "";
*/
} else {
    echo "Error updating record: " . $conn->error;
}


?>

 

  • Solution

the simple way of doing this is to use an array for the data, by using an array name for the form fields, with the array index being the row's unique id, e.g. name='court[{$data['ccalid']}]'. when the form is submitted, you can get the array indexes from the first field (see php's array_keys()), then loop over this array of indexes to access each set of data from the fields.

also, you should not put dynamic values directly into sql query statements, where any sql special character can break the sql query syntax. use a prepared query instead, prepared once, before the start of any looping, then simply supply each new set of data when you execute the query. if is seems like using the mysqli extension with prepared queries is overly complicated and inconsistent, it is. this would be a good time to switch to the much simpler and better designed PDO extension.

here's a list of general points for the posted code -

  1. modern php (8+) uses exceptions for database error handling by default. when using exceptions, no discrete error checking logic will be executed upon an error and should be removed. when using exceptions, your code will only 'see' error free execution. if execution continues past a statement that can throw an exception, you know there was no error without needing any logic to test the result of the statement.
  2. if this is the only form that can submit to this page, you don't need to test if the submit button is set. in fact, there are cases where the submit button won't be set and you should not attempt to test if it is.
  3. use 'require' for things you code must have.
  4. include/require are not functions. the () around the path/filename do nothing and should be removed.
  5. to get a form to submit to the exact same url of the current page, leave out the entire action attribute in the form tag.
  6. everything in the ...ccal table is for the ccal data. there's no good reason to include 'ccal' in every column name. this is just a bunch of extra typing you have to keep track of.
  7. you need to apply htmlentities to all dynamic values being output in a html context to prevent any html entity in a value from breaking the html syntax.
  8. textarea's don't have value attributes.

 

  • Great Answer 1

mac_guyer-

Thank you for the quick response!  I tried your suggestion.  For this example lets says the ccalid = 442

<div class='ccalbox ccalcourt-textarea'><textarea class='ccalcourt-somebad'   name='court[{$data['ccalid']}]'>" .$data['ccalcourt'].   "</textarea></div>
<div class='ccalbox ccalcourt-textarea'><textarea class='ccaljudge-somebad'   name='judge[{$data['ccalid']}]'>" .$data['ccaljudge'].   "</textarea></div>
<div class='ccalbox ccalcourt-textarea'><textarea class='ccaladdress-somebad' name=address[{$data['ccalid']}]>" .$data['ccaladdress']. "</textarea></div>
<div class='ccalbox ccalcourt-textarea'><textarea class='ccalphone-somebad'   name=phone[{$data['ccalid']}]  >" .$data['ccalphone'].   "</textarea></div>
<div class='ccalbox ccalcourt-textarea'><textarea class='ccalfax-somebad'     name=fax[{$data['ccalid']}]    >" .$data['ccalfax'].     "</textarea></div>
<div class='ccalbox ccalcourt-textarea'><textarea class='ccalnotes-somebad'   name=notes[{$data['ccalid']}]  >" .$data['ccalnotes'].   "</textarea></div>

 

Then run this code when the Submit button is pressed:

if ($_SERVER["REQUEST_METHOD"] == "POST") 
{
    $field_names = array_keys($_POST);
    echo "<h2>POST Form Field Names:</h2>";
    echo "<ul>";
    foreach ($_POST as $fieldName => $Value) {
        echo "<li>" . htmlspecialchars($fieldName) . "</li>";
    }
    echo "</ul>";
/*    include 'samplepage1reworkinclude.php';*/
}

 

It returns:

POST Form Field Names:

court

judge

address

phone

fax

notes

submit

Shouldn't it return:

POST Form Field Names:

court442

judge442

address442

phone442

fax442

notes442

submit442

Excellent summary for you from mac_gyver.  

You don't need to, and should never end your PHP scripts with the php end tag   " ?>"

Highly recommend you adopt the PER  coding style standard.

One of PHP's features is the ability to go in/out of HTML mode.  It is easy to take advantage of this native feature by moving your markup (aka "Views") into separate view/template files you can then include.  That alone can organize and make your code easier to read and improve.  Even if you don't do that it's much better to use alternative PHP syntax and markup when you need to intermix.  

For example:

<?php
    $fieldArray = $_POST['Some_input'];
?>
<form action="" class="data">
  <?php foreach ($fieldArray as $value): ?>
      <div class="main">
          <input type="text" name="name" value="<?= $value) ?>">
      </div>
  <?php endforeach; ?>
  <button class="btn" type="submit">Submit</button>
</form>

 

There is alternative syntax for all the PHP control structures.  I also used the <?= shorthand for "echo" here, which is often fine, but if you need something more complicated you can just use a php block where you need that logic.  

<?php
  $foo = 'bar';
  $fooVal = '';
?>

<input name="bar" value="<?= $foo ?? $foo ?>">
<input name="foo"<?php strlen($foo) > 0 ? '"value="' . $fooVal : '' ?>>

// Output

<input name="bar" value="bar">
<input name="foo">

 

 

9 minutes ago, mike3075 said:

mac_guyer-

Thank you for the quick response!  I tried your suggestion.  For this example lets says the ccalid = 442

<div class='ccalbox ccalcourt-textarea'><textarea class='ccalcourt-somebad'   name='court[{$data['ccalid']}]'>" .$data['ccalcourt'].   "</textarea></div>
<div class='ccalbox ccalcourt-textarea'><textarea class='ccaljudge-somebad'   name='judge[{$data['ccalid']}]'>" .$data['ccaljudge'].   "</textarea></div>
<div class='ccalbox ccalcourt-textarea'><textarea class='ccaladdress-somebad' name=address[{$data['ccalid']}]>" .$data['ccaladdress']. "</textarea></div>
<div class='ccalbox ccalcourt-textarea'><textarea class='ccalphone-somebad'   name=phone[{$data['ccalid']}]  >" .$data['ccalphone'].   "</textarea></div>
<div class='ccalbox ccalcourt-textarea'><textarea class='ccalfax-somebad'     name=fax[{$data['ccalid']}]    >" .$data['ccalfax'].     "</textarea></div>
<div class='ccalbox ccalcourt-textarea'><textarea class='ccalnotes-somebad'   name=notes[{$data['ccalid']}]  >" .$data['ccalnotes'].   "</textarea></div>

Then run this code when the Submit button is pressed:

Shouldn't it return:

POST Form Field Names:

court442

judge442

address442

phone442

fax442

notes442

submit442

 

You seem to be missing the point on html array syntax which you should use to replace your attempt to force some dynamic set of html markup.

<div class="ccalbox ccalcourt-textarea"><textarea class="ccalcourt-somebad" name="court[]"><?= $data['ccalcourt'] ?></textarea></div>

When submitted, $_POST['court'] will be an array.  Typically, if you are designing something to be dynamic, you would create some javascript code that adds new elements based on however you want the user to interact with it.  It could be as simple as a button that says "Add New" and you would then add the html element:

<div class="ccalbox ccalcourt-textarea"><textarea class="ccalcourt-somebad" name="court[]"></textarea></div>

 

have you examined what the form data is -

echo '<pre>'; print_r($_POST); echo '</pre>';

 

23 hours ago, mac_gyver said:

when the form is submitted, you can get the array indexes from the first field (see php's array_keys()), then loop over this array of indexes to access each set of data from the fields.

the first field is court. this code would be something like -

	// example code looping over the form data
	foreach(array_keys($_POST['court']) as $index)
	{
		// for demonstration purposes, echo the values
		echo 'Court: '.$_POST['court'][$index].'<br>';
		echo 'Judge: '.$_POST['judge'][$index].'<br>';
		// ...
	}

here's an additional list of points for the code -

  1. you can select the database in the connection statement.
  2. if the only thing in an overall double-quoted string is a php variable, don't put quotes around the variable at all.
  3. if you put the database connection code in its own file, you can just require it when needed and you won't need to redact the connection credentials when posting the code that uses the connection.
  4. if the update query can result in duplicate data for any column(s) that must be unique (you would define those columns as a unique index), you would have try/catch exception handling logic in your code, test in the catch branch is a duplicate index error (number) occurred, and setup a message for the user letting them know that duplicate data was submitted.
  5. don't echo blocks of static or mostly static html markup. simply drop out of php and put the markup in-line.
  6. if you use php's short open print tag <?= and leave out the closing ; right before a closing ?> tag, you can echo php variables in markup using <?=$var?> syntax.
  7. you should list out the columns you are SELECTing in a query.
  8. a SELECT query that can match more than one row of data needs to have an ORDER BY ... term so that the rows of data are in a specific order.
  9. if a query doesn't match any data, output a message stating so, instead of outputting nothing.
  10. you can directly loop/iterate over the result object from a query. for what you are doing, you don't need to first fetch the data into $datas.
  11. you should always quote html attribute values.
  12. you need to validate the resulting web pages at validator.w3.org
  • Like 1

mac_gyver & gizmola-

Thank you both for all the helpful suggestions and recommendations and for helping solve this issue.  I got the code working after rereading both your posts.  I now have the array being passed to my include page where I can start working on extracting the data from the array to run the update query

  • Like 1

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  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.

×
×
  • 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.