为啥 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 循环显示来自其他用户的数据?的主要内容,如果未能解决你的问题,请参考以下文章
jquery 循环和分配来自 Asp.net 核心 Razor 页面 foreach 的数据
为啥 .forEach() 有效但 for 循环无效? [复制]