I have a PHP script that allows end-users, using a dynamic form, to select how many entry he/she needs. 1 set of data is 3 entries. Each entry will contain its own field. For example, if he/she needs 4 set of data, the end-user will select 4 in a drop down list and the PHP script will dynamically display a blank form with 4 lines, each line containing 3 fields (so, a 4x3 matrix, with 12 fields).
Then the script has to write the data collected from the 12 field into a text file. I am struggling to pass the data collected in the form, to the PHP script that will actually write into the txt file.
Here is the main page: MAIN.php:
<?php
$Matrix = array(array());
$data = $name*3; //1 line entry contains 3 columns of data; total $name line entry
$block=null;
$entry=null;
for ($n = 0; $n <= $data-1; $n =1) {
$block=fmod($n,$name);
$entry=($n-$block)/$name;
$block=$block 1; //line (horizontal)
$entry=$entry 1; //column (vertical); 3 in this case
}
for ($a = 0; $a <= $block-1; $a =1) { //line (horizontal)
for ($b = 0; $b <= $entry-1; $b =1) { //column (vertical)
$Matrix[$a][$b]=null;
}
}
echo '
<form action="WSCRIPT.php" method="POST">
<table style="width:40%">
<col style="width:5%">
<col style="width:20%">
<col style="width:10%">
<col style="width:10%">
<tr>
<td><center>#</center></td>
<td><center>Item / Description</center></td>
<td><center>Start date</center></td>
<td><center>End date</center></td>
</tr>';
echo '<tr>';
for ($a = 0; $a <= $block-1; $a =1) { //line (horizontal)
$line=$a 1;
echo '<td><center>'.$line.'</center></td>';
for ($b = 0; $b <= $entry-1; $b =1) { //column (vertical)
echo '<td><center><input name="'.$Matrix[$a][$b].'" type="text" /></center></td>';
}
echo '</tr>';
}
echo '
</table>
<br>
<input type="submit" name="submit" value="Save Data">
</form>';
?>
And the PHP script writing to the txt file, WSCRIPT.php:
<?php
$block = 10; //max
$entry = 3; //constant
for ($a = 0; $a <= $block-1; $a =1) { //line (horizontal)
for ($b = 0; $b <= $entry-1; $b =1) { //column (vertical)
$data = $_POST['.$Matrix['.$a.']['.$b.'].'] . "\r\n";
$ret = file_put_contents('WSCRIPT.txt', $data, FILE_APPEND | LOCK_EX);
if($ret === false) {
die('Error writing this file');
}
else {
echo "$ret bytes written to file";
}
}
}
?>
The error I'm having is showing up as:
Notice: Undefined index: .$Matrix[0][0]. in C:\TEST\WSCRIPT.php on line 9
Notice: Undefined index: .$Matrix[0][1]. in C:\TEST\WSCRIPT.php on line 9
Notice: Undefined index: .$Matrix[0][2]. in C:\TEST\WSCRIPT.php on line 9
Notice: Undefined index: .$Matrix[1][0]. in C:\TEST\WSCRIPT.php on line 9
etc...
where line 9 is the line from the WSCRIPT.php, with:
$data = $_POST['.$Matrix['.$a.']['.$b.'].'] . "\r\n";
Can anybody point me in the right direction on how to move forward... I'm a PHP beginner and self-learning on the go...
Thank you very much!
Julien
CodePudding user response:
Naming a form input element $Matrix = array(array());
is not the correct approach. The element should have a proper name that uses the array syntax, such as banana[]
etc so that name becomes available within the POSTed data.
I put together a single page demo to illustrate how one might accomplish the goal of writing to textfile the data collected from a dynamically generated form where the names of individual text fields use a common name with an array syntax. As the code above does not show the select
menu used to create the initial display I used some javascript and a template for content as you'll see below.
<?php
error_reporting( E_ALL );
if( $_SERVER['REQUEST_METHOD']=='POST' && isset( $_POST['matrix'] ) ){
/**************************
WSCRIPT.php emulator
*/
/* Split the matrix data into chunks of 3 ( 3 inputs per table row! ) */
$chunks=array_chunk( $_POST['matrix'], 3 );
$file='wscript.txt';
@unlink( $file );
foreach( $chunks as $trio ){
/*
Each row as shown in the HTML table will be written to it's own line in the text file.
The individual values are separated with the pipe character here - but could obviously be
formatted completely differently.
*/
file_put_contents( $file, implode( ' | ', $trio ) . PHP_EOL, FILE_APPEND | LOCK_EX );
}
exit( sprintf( '%s bytes written to file',filesize( $file ) ) );
}
?>
<!DOCTYPE html>
<html lang='en'>
<head>
<meta charset='utf-8' />
<title>write dynamically generated form element content to text file</title>
<style>
:root{ counter-reset:rows; }
tbody tr{ counter-increment:rows; }
tr td:first-of-type:before{ content:counter(rows) }
</style>
</head>
<body>
<!--
dropdown to select the number of rows the user
wishes to add to the table.
Data added by javascript.
-->
<select name='qty'>
<option selected hidden disabled>Please select
</select>
<!--
action='WSCRIPT.php'
~ removed for single page demo where
php acts as wscript.php
-->
<form method='POST'>
<table>
<colgroup>
<col style='width:5%'>
<col style='width:20%'>
<col style='width:10%'>
<col style='width:10%'>
</colgroup>
<thead>
<tr>
<th>#</th>
<th>Item / Description</th>
<th>Start date</th>
<th>End date</th>
</tr>
</thead>
<tbody>
<!-- dynamic content added here -->
</tbody>
</table>
<input type='submit' value='Save Data' />
</form>
<!--
a simple template holding the new table row and 3 input fields
to be added in whatever quantity is selected from the dropdown.
The name of the element uses the array syntax but importantly
it is a proper name rather than a PHP reference to an array!
The name `matrix` will appear in the POST array when the form
is submitted after the user has added whatever content they
need to.
-->
<template>
<tr>
<td> </td>
<td><input type='text' name='matrix[]' /></td>
<td><input type='text' name='matrix[]' /></td>
<td><input type='text' name='matrix[]' /></td>
</tr>
</template>
<script>
let oSel=document.querySelector('select[name="qty"]');
let tbl=document.querySelector('form > table > tbody');
let tmpl=document.querySelector('template');
/* add new options to the select menu */
for( let i=1; i <=25; i )oSel.append(new Option(i,i));
/* add the event listener that clones the template N times and adds to the table */
oSel.addEventListener('change',function(e){
tbl.innerHTML='';
for( let i=0; i < this.value; i ){
let tr=tmpl.content.cloneNode( true );
tbl.append( tr );
/**********************************************
add some junk data to each input element
- only because I'm lazy
*/
document.querySelectorAll('td input').forEach((n,j)=>{
n.value=[
`cell:${j 1}`,
window.URL.createObjectURL(new Blob([])).split('/').pop().substr(0,16)
].join( ' ' );
})
}
})
</script>
</body>
</html>