为啥 foreach 循环显示来自其他用户的数据?

Posted

技术标签:

【中文标题】为啥 foreach 循环显示来自其他用户的数据?【英文标题】:Why is the foreach loop showing the data from other users?为什么 foreach 循环显示来自其他用户的数据? 【发布时间】:2021-09-06 01:27:20 【问题描述】:

简历表包含提交给不同雇主的 3 个数据和 3 个文件。当我登录到 Employer (2 (in resumes table fk_user_id = 2)) 时,我还获得了其他 2 个雇主的 3 个下载按钮。

可能是什么原因?

我只需要根据简历表的下载按钮,并且也提交给特定的雇主。当我以 Employer (2) 身份登录时,我得到了 3 个不同的下载按钮。

resume_manage.php

    <?php
     include 'includes/header.php';
      include 'filesLogic.php';
     
      include 'includes/sidebar.php';
    ?>
    
            <div class="content-wrapper">
                <!-- START PAGE CONTENT-->
                <div class="page-heading">
                    <h1 class="page-title">Applied Jobs List</h1>
                    <ol class="breadcrumb">
                        <li><a href="../../../index.php"><i class="fa fa-dashboard"></i> Home</a></li>
                        <li class="active">Applied Jobs List</li>
                    </ol>
                </div>
                <div class="page-content fade-in-up">
                    <div class="ibox">
                        <div class="ibox-head">
                            <div class="ibox-title">Data Table</div>
                        </div>
                        <div class="table-responsive ibox-body">
                            <table class="table table-striped table-bordered table-hover" id="example-table" cellspacing="0" >
                                <thead>
                                    <tr>
                                        <th>User Id</th>
                                        <th>Resume</th>
                                        <th>Employer Id</th>
                                        <th>User Email</th>
                                        <th>Reply</th>
                                        <th>Status</th>
                                        <th>Actions</th>
                                    </tr>
                                </thead>
                                <tfoot>
                                    <tr>
                                        <th>User Id</th>
                                        <th>Resume</th>
                                        <th>Employer Id</th>
                                        <th>User Email</th>
                                        <th>Reply</th>
                                        <th>Status</th>
                                        <th>Actions</th>
                                    </tr>
                                </tfoot>
                                <tbody>
                                    <?php
                                    $detail="SELECT * FROM resumes where fk_user_id = '$user_id'";
                                    $detailqry = mysqli_query($conn, $detail);
                                    while($row = mysqli_fetch_array($detailqry))
                                        $id = $row['resume_id'];
                                    ?>
                                    <tr>
                                        <td><?php echo $row['user_id'];?></td>
                                        <td><?php echo $row['name'];?></td>
                                        <td><?php echo $row['job_id'];?></td>
                                        <td><?php echo $row['user_email'];?></td>
                                        <td>
                                        <?php
                                        foreach ($files as $file)?>
                                            <a href="resume_manage.php?file_id=<?php echo $file['resume_id'] ?>">Download</a>
                                        <?php  ?>
                                        </td>         
                                        <td>                            
                                            <a class="btn btn-danger" href="write_resume_reply.php?sid=<?php echo $row['resume_id']; ?>"><b>Write Reply</b>
                                            </a>                            
                                        </td>   
                                        <?php
                                        if($row['active']==1)
                                            
                                            echo '<td>';
                                            echo "<font color='#8ed100'><b>Already Sent</b></font>";
                                            $buttonText = "SENT";
                                        else
                                            echo '<td>';
                                            echo "<font color='#750000'><b>Not Sent</b></font>";
                                            $buttonText = "SEND";
                                        
                                        echo "</td>";
                                        ?>  
                                        <td class="text-center">                            
                                            <a class="btn btn-danger" href="action_resume.php?sid=<?php echo $row['resume_id']; ?>"><b><?php echo $buttonText; ?></b>
                                            </a>                            
                                        </td>
                                    </tr>
                                    <?php ?>
                                </tbody>
                            </table>
                        </div>
                    </div>            
                </div>
                <!-- END PAGE CONTENT-->    
                <footer class="page-footer">
                    <div class="font-13">2021 © <b>Job4Students</b> - All rights reserved.</div>
                    <div class="to-top"><i class="fa fa-angle-double-up"></i></div>
                </footer>
            </div>
        </div>    
           
        <!-- BEGIN PAGA BACKDROPS-->
        <div class="sidenav-backdrop backdrop"></div>
        <div class="preloader-backdrop">
            <div class="page-preloader">Loading</div>
        </div>
        <!-- END PAGA BACKDROPS-->
        <!-- CORE PLUGINS-->
        <script src="./assets/vendors/jquery/dist/jquery.min.js" type="text/javascript"></script>
        <script src="./assets/vendors/popper.js/dist/umd/popper.min.js" type="text/javascript"></script>
        <script src="./assets/vendors/bootstrap/dist/js/bootstrap.min.js" type="text/javascript"></script>
        <script src="./assets/vendors/metisMenu/dist/metisMenu.min.js" type="text/javascript"></script>
        <script src="./assets/vendors/jquery-slimscroll/jquery.slimscroll.min.js" type="text/javascript"></script>
        <!-- PAGE LEVEL PLUGINS-->
        <script src="./assets/vendors/DataTables/datatables.min.js" type="text/javascript"></script>
        <!-- CORE SCRIPTS-->
        <script src="assets/js/app.min.js" type="text/javascript"></script>
        <!-- PAGE LEVEL SCRIPTS-->
        <script type="text/javascript">
            $(function() 
                $('#example-table').DataTable(
                    pageLength: 10,
                    //"ajax": './assets/demo/data/table_data.json',
                    /*"columns": [
                         "data": "name" ,
                         "data": "office" ,
                         "data": "extn" ,
                         "data": "start_date" ,
                         "data": "salary" 
                    ]*/
                );
            )
        </script>
        
    
    </body>
    
    </html>

filesLogic.php

     <?php
        // connect to the database
        
        
          include '../includes/connection.php';
          
          $conn = mysqli_connect("localhost","root");
          
         // Select Database   
            if (!$conn) 
                error_log("Failed to connect to MySQL: " . mysqli_error($connection));
                die('Internal server error');
              
             
              // 2. Select a database to use 
              $sql = mysqli_select_db($conn, 'Students_Jobsite');
              if (!$sql) 
                error_log("Database selection failed: " . mysqli_error($connection));
                die('Internal server error');
              
              $detail = mysqli_select_db($conn, 'Students_Jobsite');
        
        
              $sql = "SELECT * FROM resumes";
              $result = mysqli_query($conn, $sql);
         
              $files = mysqli_fetch_all($result, MYSQLI_ASSOC);
        
        
        
        
        
        // Downloads files
        if (isset($_GET['file_id'])) 
            $id = $_GET['file_id'];
        
            // fetch file to download from database
            $sql = "SELECT * FROM resumes WHERE resume_id=$id";
            $result = mysqli_query($conn, $sql);
        
            $file = mysqli_fetch_assoc($result);
            $filepath = '../uploads/' . $file['name'];
        
            if (file_exists($filepath)) 
                header('Content-Description: File Transfer');
                header('Content-Type: application/octet-stream');
                header('Content-Disposition: attachment; filename=' . basename($filepath));
                header('Expires: 0');
                header('Cache-Control: must-revalidate');
                header('Pragma: public');
                header('Content-Length: ' . filesize('uploads/' . $file['name']));
                readfile('uploads/' . $file['name']);
        
                // Now update downloads count
                $newCount = $file['downloads'] + 1;
                $updateQuery = "UPDATE files SET downloads=$newCount WHERE resume_id=$id";
                mysqli_query($conn, $updateQuery);
                exit;
            
        
        

后端(php)中的输出:

【问题讨论】:

在调用 DB 获取文件 ($sql = "SELECT * FROM resumes";) 时,我没有看到任何限制,在执行 foreach 时也没有看到任何限制。由于您已经在$files 对象中有fk_user_id,您可以过滤foreach 中的文件列表,不是吗? 您正在通过循环 $files 来创建下载按钮,并且您根据查询 SELECT * FROM resumes 填写的那个按钮,您对任何特定用户都没有任何限制。 警告:您对SQL Injections 持开放态度,应该使用参数化的prepared statements,而不是手动构建查询。它们由PDO 或MySQLi 提供。永远不要相信任何形式的输入!即使您的查询仅由受信任的用户执行,you are still in risk of corrupting your data。 Escaping is not enough! 【参考方案1】:

您实际使用的查询是filesLogic.php 中的"SELECT * FROM resumes",它返回所有简历,而不仅仅是当前用户的简历。

手动将值插入 SQL 语句(如"SELECT * FROM resumes where fk_user_id = '$user_id'")是非常危险的;它往往会导致被称为SQL Injection 的安全问题,目前在most dangerous software weaknesses 列表中排名第6。

如果可能,请使用其中一个库函数,该函数采用带有占位符和单独参数列表的 SQL 语句; msqli,即prepare,后跟bind_param

$stmt = $conn->prepare("SELECT * FROM resumes where fk_user_id = ?");
$stmt->bind_param("i", $user_id);
$stmt->execute();

【讨论】:

致命错误:未捕获的错误:调用第 28 行 C:\xampp\htdocs\Student_Job\employer\filesLogic.php 中 bool 上的成员函数 prepare() (!) 错误:调用第 28 行 C:\xampp\htdocs\Student_Job\employer\filesLogic.php 中 bool 上的成员函数 prepare() 注意:未定义变量:C:\xampp\htdocs\Student_Job\employer\filesLogic.php 中第 28 行中的 mysqli @Sandhya 你的mysqli实例叫$conn 糟糕,抱歉;我的答案中更新了变量名 警告:mysqli_fetch_all() 期望参数 1 为 mysqli_result,布尔值在 C:\xampp\htdocs\Student_Job\employer\filesLogic.php 第 33 行中给出【参考方案2】:

我可以通过以下方法简单地解决问题:

 <?php
                                $detail="SELECT * FROM resumes where fk_user_id = '$user_id'";
                                $detailqry = mysqli_query($conn, $detail);
                                while($row = mysqli_fetch_array($detailqry))
                                    $id = $row['resume_id'];
                                    $sql = "SELECT * FROM resumes where fk_user_id = $user_id and resume_id = $id";
                                    $result = mysqli_query($conn, $sql);

                                    $files = mysqli_fetch_all($result, MYSQLI_ASSOC);
                                ?>

【讨论】:

以上是关于为啥 foreach 循环显示来自其他用户的数据?的主要内容,如果未能解决你的问题,请参考以下文章

以列方式而不是行方式显示来自 foreach 循环的数据

PHP foreach 循环显示特定项目

jquery 循环和分配来自 Asp.net 核心 Razor 页面 foreach 的数据

为啥 .forEach() 有效但 for 循环无效? [复制]

为啥我不能访问这个数组 ForEach 循环中的数据? SwiftUI

为啥我不能使用 foreach 循环更新数组中的数据?