PHP: 如何使用 method=POST 将变量作为多维数组传递

PHP: how to pass a variable as a multidimensional array with method=POST

我有一个 PHP 脚本,允许最终用户使用动态表单 select 需要多少条目 he/she。 1组数据是3个条目。每个条目都将包含自己的字段。例如,如果 he/she 需要 4 组数据,最终用户会在下拉列表中显示 select 4,而 PHP 脚本将动态显示一个包含 4 行的空白表单,每行包含 3 个字段的行(因此,一个 4x3 矩阵,有 12 个字段)。

然后脚本必须将从 12 字段收集的数据写入文本文件。我正在努力将表单中收集的数据传递给实际写入 txt 文件的 PHP 脚本。

这是主页: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>';
?>

并且PHP脚本写入txt文件,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";
        }
    }
}
?>

我遇到的错误显示为:

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

第 9 行来自 WSCRIPT.php,其中:

$data = $_POST['.$Matrix['.$a.']['.$b.'].'] . "\r\n";

任何人都可以指出我如何前进的正确方向...我是一个 PHP 初学者并且在旅途中自学...

非常感谢!

朱利安

为表单输入元素命名 $Matrix = array(array()); 不是正确的方法。该元素应该有一个使用数组语法的正确名称,例如 banana[] 等,以便名称在发布的数据中可用。

我整理了一个单页演示来说明如何实现将从动态生成的表单收集的数据写入文本文件的目标,其中各个文本字段的名称使用具有数组语法的通用名称。由于上面的代码没有显示用于创建初始显示的 select 菜单,我使用了一些 javascript 和内容模板,如下所示。

<?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>&nbsp;</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>