3

I am new to programming. I can't seem to fix it after how many hours as I am still student and this is for my thesis.

I am trying to fetch the records from two tables

  1. prisoner table
  2. visitations table - this table has prisoner_id foreign key so If I click a prisoner it will also show his visitation records.

Here's my code:

<?php

include "connect.php";

$id = $_GET['id'];

$result = $connect->query(
    "SELECT * FROM prisoner                                                                
       INNER JOIN visitations ON prisoner.prisoner_id = visitations.prisoner_id
       WHERE prisoner.prisoner_id = $id"
) or die($connect->error);

$visit = $connect->query(
     "SELECT visitor,date_of_visit,time_of_visit,affinity,homeAddress FROM visitations 
        INNER JOIN prisoner ON prisoner.prisoner_id = visitations.prisoner_id 
        WHERE visitations.prisoner_id = $id"
) or die($connect->error);

PRISONER TABLE

while($row = $result->fetch_assoc()){

    $id = $row['prisoner_id'];
    $photo = $row['photo'];
    $gname = $row['givenName'];
    $mname = $row['middleName'];
    $lname = $row['lastName'];
    $aname = $row['nickname'];

<div class="row text-center">
                <?php echo "<img style = 'width: 16%;height: 16%;margin-top:30px;'src='images/".$photo."' >";  
                        echo "<br><br>$gname $mname $lname";
                ?>
           </div>

            <?php

            echo "<div class='col-lg-3'>Nickname: $aname </div>";
}

VISITATIONS

<h4>Visitations</h4>
            </div>

            <table border = 1>
            <tr>
                <th>Visitor Name</th>
                <th>Date of Visit</th>
                <th>Time of Visit</th>
                <th>Affinity</th>
                <th>Home Address</th>
            <tr>

            <?php


            while($row2 = $visit->fetch_assoc()){

                $v_visitor = $row2['visitor'];
                $v_date = $row2['date_of_visit'];
                $v_time = $row2['time_of_visit'];
                $v_affinity = $row2['affinity'];
                $v_address = $row2['homeAddress'];

            echo "
             <tr>
                <td>$v_visitor</td>
                <td>$v_date</td>
                <td>$v_time</td>
                <td>$v_affinity</td>
                <td>$v_address</td>
             </tr>

             </table>";

             }

It only fetches the records from visitations table and also I don't know why the other records are not inside the HTML table.

This is what it displays:

visitationtble

Can someone point out the problem with my code, please

Kee
  • 35
  • 6
  • 2
    Your code is vulnerable to [SQL injection](https://en.wikipedia.org/wiki/SQL_injection) attacks. You should use [mysqli](https://secure.php.net/manual/en/mysqli.prepare.php) or [PDO](https://secure.php.net/manual/en/pdo.prepared-statements.php) prepared statements with bound parameters as described in [this post](https://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php). –  Apr 29 '18 at 08:51
  • Ok noted I will keep that in mind @Dominik – Kee Apr 29 '18 at 08:55
  • Can you answer my problem? I really need some help :( @Dominik – Kee Apr 29 '18 at 09:00
  • @Kee: This might not be the issue, but often if code is open to SQL injection that prominently, it is also a sign that there is a general problem with stable data-processing. So if you could address in your question for example why you expected to have a different outcome than you see, that would help to get a better understanding of how you would like your data to be processed. And just a hint: Instead of die()'s just switch your database adapter to throw exceptions on error and you can safely spare that boilerplate. – hakre Apr 29 '18 at 09:29
  • @kee: I can understand the hope it creates seen an answer w/ steps that look easy to follow to apply on your original question, but this is of no use for the person who answered that way as the question now changed (and least for the fellow member who did answer). Just saying so you perhaps can better understand from the point of view from somebody answering your question. And have you considered that this might be a display (and not a query) problem? – hakre Apr 29 '18 at 10:14
  • I'm sorry and I really appreciate for the hints and information that you've said, I will really keep all that in mind. :) @hakre – Kee Apr 29 '18 at 10:31
  • @kee: But look now what happened: You edited your original question ins such a way that it does not contain your (furthermost) problem any longer. That is, future visitors won't understand what this is about. It actually has overlived it's time as a question for a Q&A site one could perfectly argue. Any idea how to solve that? – hakre Apr 29 '18 at 10:36
  • 1
    Again I'm sorry. I'll edit my question back to it's original so it would still help other visitors. I edited my question so that sir jspcal could see the progress of my code and I realize that it was wrong to do so. Thanks for the info – Kee Apr 29 '18 at 10:47

2 Answers2

2

Only one active statement per connection can be used in this context, so you'll want to consume the entire result set of the first query with fetch_all before moving on to a new query.

$result1 = $connect->query(...)
$rows1 = $result1->fetch_all(MYSQLI_ASSOC);

$result2 = $connect->query(...)
$rows2 = $result2->fetch_all(MYSQLI_ASSOC);

foreach ($rows1 as $row) ...

foreach ($rows2 as $row) ...

It's also possible to execute multiple queries in a single batch using multi_query.

jspcal
  • 50,847
  • 7
  • 72
  • 76
  • I've added mysqli_fetch_all($result,MYSQLI_ASSOC); into my question before the first while loop. Nothing happened or I might be wrong again? – Kee Apr 29 '18 at 09:28
  • @jspcal I have edited my question, kindly check it, no records have been fetched and have errors Notice: Undefined index: firstName, Undefined index: middleName, Undefined index: lastName and etc – Kee Apr 29 '18 at 10:16
  • @jspcal The records have been fetched! Thank you. Can you also point what's the problem with my HTML table, other visitation records are still outside the table. – Kee Apr 29 '18 at 10:22
  • @jspcal Thank you very much! I really appreciate your help :) – Kee Apr 29 '18 at 10:31
1

Next to the mentioned SQL injection problem (which boils down to: How do I properly encode a SQL query) there are more things that can go wrong and another one is a HTML injection problem (which boils down to: How do I properly encode HTML).

So in short: A HTML table can only be closed once, and it is always for the first matching closing </table> tag. As in the OPs code there is output of one closing table tag per row (inside the while body), after the first row the table is closed and further data is rendered following the rules of HTML on how to render text-data within tags that are out of scope (that is as text below the table here).

So not only do your SQL homework regarding the SQL injections, but first of all get comfortable on how to improve writing PHP template files. You could for example benefit from the <?= $variable ?> notation, and as this is HTML and not plain text, the more correct <?= htmlspecialchars($variable) ?> variant.

hakre
  • 193,403
  • 52
  • 435
  • 836
  • @jspcal: Well whether or not it answers the question is up to the OP to say in the end, but apart of that and regarding your comment, feel free to read the answer in whole, I use the SQL injection only as an introduction topic to make the answer not that disconnected to the comments stream below OP. – hakre Apr 29 '18 at 09:54
  • @jspcal: sure, OP has problems to put the three results into one html table. – hakre Apr 29 '18 at 09:56
  • well: "and also I don't know why the other records are not inside the HTML table" - for the first part it is not visible from the question so I asked the OP for more info, but for that second part I was able to answer so I did. don't think that is wrong. – hakre Apr 29 '18 at 10:04
  • The answer to the title is simple: Because only one record is fetched and displayed. But that's not a helpful answer, so I needed to ask for more. – hakre Apr 29 '18 at 10:07
  • @jspcal: Oh come on, at least this answers the second part what is asked for. If yours fixes the first part then, this is all fine, isn't it? – hakre Apr 29 '18 at 10:19
  • Thanks for the help :) @hakre – Kee Apr 29 '18 at 10:33