2017-02-19 32 views
0

美好的一天@全部。 我有这段代码片段,其目的是根据注册的课程显示此用户有资格参加的考试。它会显示考试名称,可用日期,通过成绩和考试链接,如果他/她没有写过或者如果他/她之前已经写过查看结果。如何使用PHP动态显示网页中的链接

/*Connection String */ 
global $con; 

$user_id = $_SESSION['user_id']; //user id 

$courses = parse_course($user_id); //parse course gets the list of registered courses (Course Codes) in an array 

foreach ($courses as $list) 
{ 
    $written = false; 
    $list = parse_course_id($list); //parse_course_id gets the id for each course 
    $ers = mysqli_query($con, "Select * from exams where course_id = '$list'"); 
    while ($erows = mysqli_fetch_assoc($ers)) { 
     $trs = mysqli_query($con, "Select * from result_data where user_id = '$user_id'"); 
     while ($trows = mysqli_fetch_assoc($trs)) { 
      if ($trows['user_id'] == $user_id && $trows['exam_id'] == $erows['exam_id']) 
       $written = true; 
      else 
       $written = false; 
     } 

     if($written) 
     { 
      echo "<tr><td>".$erows['exam_name']."</td><td>".$erows['exam_from']." To ".$erows['exam_to']."</td><td>".$erows['passing_grade']."%</td><td><a href=proc_result.php?id=".$erows['exam_id'].">".'View Result '."</a></td></tr>"; 
      $written = false; 
     } 
     else 
     { 
      echo "<tr><td>".$erows['exam_name']."</td><td>".$erows['exam_from']." To ".$erows['exam_to']."</td><td>".$erows['passing_grade']."%</td><td><a href=Exam3.php?id=".$erows['exam_id'].">".'Take Exam '."</a></td></tr>"; 
      $written = false; 
     } 

    } 

} 

但它只显示一个查看结果条目,即使我已经参加了多个考试。它显示最近的条目。请问我错过了什么?

+2

** WARNING **:当使用'mysqli'你应该使用[参数化查询](http://php.net/manual/en/mysqli.quickstart.prepared-statements.php)和['bind_param'](http://php.net/manual/en/mysqli- stmt.bind-param.php)将用户数据添加到您的查询中。 **不要**使用字符串插值或连接来完成此操作,因为您创建了严重的[SQL注入漏洞](http://bobby-tables.com/)。 **绝不**将'$ _POST'或'$ _GET'数据直接放入查询中,如果有人试图利用您的错误,这会非常有害。 – tadman

+1

要点。我会立即改变这一点。谢谢@tadman。 – Andromadus

+0

我不确定为什么要比较行的'user_id'列到''user_id'变量,因为您只是在'WHERE'子句中只请求该行的值。 – tadman

回答

0

未经测试,但这里是我会怎么做。

我假设$ user_id是一个整数。我有点担心它在没有任何消毒的情况下在SQL中使用。我无法保证你所做的其他事情都是安全的,因为我看不到你的其他代码。请阅读:http://php.net/manual/en/security.database.sql-injection.php

(哦,我看到有人已经评论上 - 不要掉以轻心!)

无论如何,我的做法是收集用户的笔试ID添加到一个数组第一。然后循环检查可用的考试,并检查每个考试编号,看看它是否在我们之前制作的数组中。

除非你发现这个表现不佳,否则我不会打扰到加入建议。在许多系统中,在这种情况下有3个函数是常见的,其中一个产生$ users_written_exam_ids,这个函数引发了像$ all_available_exams之类的东西,然后是用于比较这两者的代码。但由于人们在这里看到这两个查询起来有很强的诱惑力来优化它,这是很酷,但你可能只是希望它的工作:)

<?php 
global $con; 

// Get the user id. Pass through intval() so no SQL injection is possible. 
$user_id = intval($_SESSION['user_id']); 

// Parse course gets the list of registered courses (Course Codes) in an array 
$courses = parse_course($user_id); 

foreach ($courses as $list) 
{ 
    // Gets the id for each course 
    $list = parse_course_id($list); 

    $users_written_exam_ids = array(); 
    $trs = mysqli_query($con, "SELECT exam_id FROM result_data WHERE user_id = '$user_id'"); 
    while ($trows = mysqli_fetch_assoc($trs)) 
    { 
     $users_written_exam_ids[] = $trows['exam_id']; 
    } 

    $ers = mysqli_query($con, "SELECT * FROM exams WHERE course_id = '$list'"); 
    while ($erows = mysqli_fetch_assoc($ers)) { 
     echo '<tr><td>' . $erows['exam_name'] . '</td><td>' . $erows['exam_from'] 
      . ' To ' . $erows['exam_to'] . '</td><td>' . $erows['passing_grade'] 
      . '%</td><td>'; 
     if (in_array($erows['exam_id'], $users_written_exam_ids)) 
     { 
      echo '<a href="proc_result.php?id=' . $erows['exam_id'] . '">View Result</a>'; 
     } 
     else 
     { 
      echo '<a href="Exam3.php?id=' . $erows['exam_id'] . '">Take Exam</a>'; 
     } 
     echo '</td></tr>'; 

    } 

} 
+0

事实上,如果你想成为所有专业人士,请将其放入3个函数中,将从数据库中提取数据的函数放入包含文件中,并且不要将执行数据库查询的代码与执行HTML输出的代码混合在一起。需要思考的东西。这样你就可以在你的网站的其他区域重复使用数据库功能:)你可以将参数传递给函数,以便通过用户ID,考试ID等来限制它们......无论你需要什么。 – braks

+0

谢谢@ Braks。它可以工作,但我必须将<$ users_written_exam_ids = [];>更改为<$ users_written_exam_ids = array();>。它完美后工作。我一直在以错误的方式去讨论。掌握这一点我还有很长的路要走。感谢所有评论/浏览过的人。 – Andromadus