如何使用 PHP 以动态形式上传文件并将路径/文件名与其他数据一起保存到 mysql

Posted

技术标签:

【中文标题】如何使用 PHP 以动态形式上传文件并将路径/文件名与其他数据一起保存到 mysql【英文标题】:How to upload files with a dynamic form and save path/filename to mysql together with other data using PHP 【发布时间】:2016-05-30 20:43:39 【问题描述】:

我有一个动态表单,看起来很像这样:

这个想法是每次单击“添加行”时添加一个新行(在此处使用 JQuery),并且每个新行都应包含一个“浏览”按钮,允许为每个新添加的用户上传文件。删除按钮只是删除不需要的行。

我正在使用 phpmysql 来存储输入字段数据和文件路径。

我的问题是我无法弄清楚如何正确实现“上传文件”以及如何将路径/文件名添加到 php/mysql 查询中。

到目前为止,我的代码如下所示:

<?php
$mysql_db_hostname = "localhost";
$mysql_db_user = "root";
$mysql_db_password = "password";
$mysql_db_database = "dynamic";

$dbc = mysql_connect($mysql_db_hostname, $mysql_db_user, 

$mysql_db_password) or die("Could not connect database");
mysql_select_db($mysql_db_database, $dbc) or die("Could not select database");
?>


<?
if (isset($_POST['add_account']))  
    if ($_POST['fields']) 
        foreach( $_POST['fields'] as $key=>$fieldArray )                           
           // new code added from here
            if (!empty($_FILES)) 

                $uploaddir = 'upload/';
                $uploadfile = $uploaddir . basename($_FILES['userfiles']['name']);


                if (move_uploaded_file($_FILES['userfiles']['tmp_name'], $uploadfile)) 
                    echo "File is valid, and was successfully uploaded.<br />";
                 else 
                    echo "File not uploaded!<br />";
                               

            
            // new code added until here

            $keys = array_keys($fieldArray);
            $values = array_map("mysql_real_escape_string",$fieldArray);                
            $q = "INSERT INTO accounts (".implode(',',$keys).", file_uploaded) VALUES ('".implode('\',\'',$values)."', ".$uploadfile." )";
            $r = mysql_query($q, $dbc );                                            

        
    
    echo "<i><h2><strong>" . count($_POST['fields']) . "</strong> Account(s) Added</h2></i>";       

?>

<?php if (!isset($_POST['add_account']))  ?> 

<form method="post" action="" enctype="multipart/form-data">

<p id="add_field"><a class="btn btn-default" href="#">Add Rows</a></p>
<table id="myTable">
<thead>
    <tr>
        <th>#</th>
        <th>First Name:</th>
        <th>Last Name:</th>
        <th>E-mail:</th>
        <th>Upload file</th>            
        <th></th>           
    </tr>
</thead>
<tbody id="container">
</tbody>
</table>

<input class="btn btn-default" type="submit" name="add_account"  value="Submit"  />
</form>
<?php  ?>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script type="text/javascript">

    $(function()
        var counter = 0;
        $('p#add_field').click(function()
            counter += 1;
            $('#container').append(
            '<tr><td>' + counter + '</td><td><input name="fields['+counter+'][first]" type="text"  placeholder="First Name" required/></td><td><input name="fields['+counter+'][last]" type="text"  placeholder="Last Name" required/></td><td><input name="fields['+counter+'][email]" type="email"  placeholder="email" required/></td><td><input id="userfile" name="fields['+counter+'][file_uploaded][]" type="file" /></td><td><input button" value="Remove" onclick="delRow(this)"></td></tr>');

        );
    );

    function delRow(currElement) 
         var parentRowIndex = currElement.parentNode.parentNode.rowIndex;
         document.getElementById("myTable").deleteRow(parentRowIndex);
    

</script>

如果我尝试回显$uploadfile,我不会得到任何结果...

print_r($_FILES) 的结果是:

    Array
(
    [fields] => Array
        (
            [name] => Array
                (
                    [1] => Array
                        (
                            [file_uploaded] => Array
                                (
                                    [0] => a4.jpg
                                )

                        )

                )

            [type] => Array
                (
                    [1] => Array
                        (
                            [file_uploaded] => Array
                                (
                                    [0] => image/jpeg
                                )

                        )

                )

            [tmp_name] => Array
                (
                    [1] => Array
                        (
                            [file_uploaded] => Array
                                (
                                    [0] => /tmp/phpIaNYYD
                                )

                        )

                )

            [error] => Array
                (
                    [1] => Array
                        (
                            [file_uploaded] => Array
                                (
                                    [0] => 0
                                )

                        )

                )

            [size] => Array
                (
                    [1] => Array
                        (
                            [file_uploaded] => Array
                                (
                                    [0] => 6063
                                )

                        )

                )

        )

)

mysql 表(帐户)如下所示:

 id | first | last | email | file_uploaded 

id 字段设置为 Primary with Autoincrement ,其余为 Varchar (300 )。

我不知道如何使用这种动态形式上传文件并将路径保存在mysql中。

其他一切都很完美。

有人可以给我一些代码示例,让我在这个特定案例的上传文件问题上走上正确的道路吗?

免责声明:我知道我应该使用 PDO 和 mysqli。我现在正在学习 PDO,但我还远远不知道,这就是我在这里使用旧/经典 mysql 的原因。 此外,大部分代码都是从本网站上发现的类似问题的各种答案中汇总而成的。

【问题讨论】:

尝试打印查询以查看它们是否正确:echo $q; 嗨,我这样做了,但文件部分没有打印任何内容。这是输出:codeArray ([0] => first [1] => last [2] => email) Array ([first] => aa [last] => ss [email] => ddd@ x.com ) 数组 ( [first] => aa [last] => ss [email] => ddd@x.com ) INSERT INTO accounts (first,last,email) VALUES ('aa','ss',' ddd@x.com') code 不确定是否相关,但在我看来,您正在添加多个具有相同 ID 的 tds,这绝对是不对的。 @Aioros - 不相关,完全删除 tds 上的 ID 不会影响结果。测试并更新了我的问题中的代码以反映此更改。 好的。反正上传的文件信息不在$_POST数组中。我建议你通读文档:php.net/manual/en/features.file-upload.post-method.php 【参考方案1】:

你快到了。您现在的问题只是您正在使用

$_FILES['userfiles']['name']

但您的文件输入根本不称为userfiles。查看您的 $_FILES 转储,您应该执行以下操作:

$_FILES['fields']['name'][$key]['file_uploaded']

如果我正确阅读了您的表单和代码,那就是。这有点奇怪的数组结构,因为您在表单中选择了一种奇怪的输入名称,但它应该可以工作。

【讨论】:

你是对的。我的脚本现在可以工作了。我会尽快用工作代码更新帖子。谢谢!【参考方案2】:

@Aioros - 在你的帮助下,我有一个功能齐全的代码:

<?php
$mysql_db_hostname = "localhost";
$mysql_db_user = "root";
$mysql_db_password = "password";
$mysql_db_database = "dynamic";

$dbc = mysql_connect($mysql_db_hostname, $mysql_db_user, 

$mysql_db_password) or die("Could not connect database");
mysql_select_db($mysql_db_database, $dbc) or die("Could not select database");
?>


<?
if (isset($_POST['add_account']))  
    if ($_POST['fields']) 
        foreach( $_POST['fields'] as $key=>$fieldArray )                           

           if (!empty($_FILES)) 

                $uploaddir = 'upload/';  // Upload directory 

                if (!is_dir($uploaddir)) // Check if upload directory exist
                
                    mkdir($uploaddir);  // If no upload directory exist, create it
                

                $newname = time(); // Returns the current time measured in the number of seconds since the Unix Epoch (January 1 1970 00:00:00 GMT),  to use it as part of the name
                $random = rand(100,999); // Getting some random numbers to add in the file names, to avoid files with the same name         

                $name =  $newname.'-'.$random.'-'.$_FILES['fields']['name'][$key]['file_uploaded'][0];  // File Name Construction 

                $tempFile = $_FILES['fields']['tmp_name'][$key]['file_uploaded'][0];  // Getting temporary file location and temporary name ( e.g. /tmp/random_string__here )

                $uploadfile = $uploaddir . $name; // Concatenating upload dir name with the file name               

                if (move_uploaded_file($tempFile, $uploadfile))   // If file moved from temp to upload location with the name we constructed above
                    echo 'File uploaded to '.$uploadfile.'.<br />';
                 else 
                    echo 'File not uploaded!<br />';
                               

            

            $keys = array_keys($fieldArray);
            $values = array_map("mysql_real_escape_string",$fieldArray);                
            $q = "INSERT INTO accounts (".implode(',',$keys).", file_uploaded) VALUES ('".implode('\',\'',$values)."', ".$uploadfile." )";
            $r = mysql_query($q, $dbc );                                            

        
    
    echo "<i><h2><strong>" . count($_POST['fields']) . "</strong> Account(s) Added</h2></i>";       

?>

<?php if (!isset($_POST['add_account']))  ?> 

<form method="post" action="" enctype="multipart/form-data">

<p id="add_field"><a class="btn btn-default" href="#">Add Rows</a></p>
<table id="myTable">
<thead>
    <tr>
        <th>#</th>
        <th>First Name:</th>
        <th>Last Name:</th>
        <th>E-mail:</th>
        <th>Upload file</th>            
        <th></th>           
    </tr>
</thead>
<tbody id="container">
</tbody>
</table>

<input class="btn btn-default" type="submit" name="add_account"  value="Submit"  />
</form>
<?php  ?>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script type="text/javascript">

    $(function()
        var counter = 0;
        $('p#add_field').click(function()
            counter += 1;
            $('#container').append(
            '<tr><td>' + counter + '</td><td><input name="fields['+counter+'][first]" type="text"  placeholder="First Name" required/></td><td><input name="fields['+counter+'][last]" type="text"  placeholder="Last Name" required/></td><td><input name="fields['+counter+'][email]" type="email"  placeholder="email" required/></td><td><input id="userfile" name="fields['+counter+'][file_uploaded][]" type="file" /></td><td><input type="button" value="Remove" onclick="delRow(this)"></td></tr>');

        );
    );

    function delRow(currElement) 
         var parentRowIndex = currElement.parentNode.parentNode.rowIndex;
         document.getElementById("myTable").deleteRow(parentRowIndex);
    

</script>

【讨论】:

以上是关于如何使用 PHP 以动态形式上传文件并将路径/文件名与其他数据一起保存到 mysql的主要内容,如果未能解决你的问题,请参考以下文章

用php上传文件并将路径保存到sql

如何获取上传文件的文件路径以创建ReadStream

PHP和Ajax将文件路径上传到Mysql并将重命名的图像保存到文件夹失败

PHP如何通过CURL上传文件

无法在视图中显示或检索文件,该文件以路径的形式上传到数据库中。 (使用 laravel )

如何防止以正常(纯文本)形式上传文件