While loop stopping after one time - php

Noob alert here. I'm just (trying to) teaching myself PHP because I need it on my internship job. Now I am creating a survey and I am trying to use while loops to show the questions and their respective answers onto my XAMPP. I am using this code:
<?php
mysqli_select_db($conn, "surveyordina");
//code hier schrijven
$sql = "SELECT questions_body FROM survey_questions where subthema_id = 1";
$sql2 = "SELECT answer_body FROM survey_answers where answer_id = 1 or answer_id = 2 or answer_id = 3";
$result = mysqli_query($conn, $sql);
$result2 = mysqli_query($conn, $sql2);
if(mysqli_num_rows($result2) > 0){
while($row = mysqli_fetch_assoc($result)) {
echo "<br>" ."Vraag: <br>" . $row["questions_body"]. "<br>";
while($row_answer = mysqli_fetch_assoc($result2)) {
echo $row_answer["answer_body"]. "<br>";
}
}
}
else{
echo "No results";
}
Now the returning part of this code looks like this:
Vraag:
Is the organization aware of where all the personal data is stored? Be it on-site or in the cloud, hosted by the company or by a third party?
Yes
No
I don't know
Vraag:
Is the organization able to locate and find personal data of a particular data subject?
Vraag:
Does the organization have technology in place to return all personal data on a given data subject, given a single search from personnel?
Vraag:
testerino kekkerino
I am trying to get the Yes, No, and I don't know parts under each and every question but only seem to get it under one of the questions.
Is there a method to return the whole answer part under each question? If so, am I on the right path or am I doing something completely wrong?
Thanks in advance.

Once you hit the end of a result-set, mysqli_fetch_assoc() doesn't just keep cycling through. So you're hitting the end of the $result2 set within the first outer loop, and then that's it, there are no more results to fetch.
You should fetch all of the $result2 results outside of the $result loop, assign the results to a variable, and then loop through that array within the $result loop.
Something like:
if(mysqli_num_rows($result2) > 0){
$result2Set = mysqli_fetch_all($result2, MYSQLI_ASSOC);
while($row = mysqli_fetch_assoc($result)) {
echo "<br>" ."Vraag: <br>" . $row["questions_body"]. "<br>";
foreach($result2Set as $row_answer) {
echo $row_answer["answer_body"]. "<br>";
}
}
}

Related

Styling output of database from php loop

I'm trying to display data from database and it is important to me that this output is placed on different sides of website. I used php to connect to database, and ajax jquery to refresh data because every 20second values change.
I tried to
echo <div styles='position: absolute; top: 0px' class='text'>{$row['id']}</div>
in a foreach loop but when I do this all 6 of my id's are stacked on top each other.
Making <div> outside loop was unsuccessful too. I guess my problem is in reading data from database because I read all at once but I don't know any other way to do this except wrtiting 6 connection files to gather only the one value that I want to display and then styling it, but I feel like there is smarter way of doing this.
This is my code. Just want to say this is my first contact with php.
<?php
$hostname = "someinfo";
$username = "someinfo";
$password = "someinfo";
$db = "someinfo";
$dbconnect = mysqli_connect($hostname,$username, $password,$db) or die("cant");
if ($dbconnect->connect_error) {
die("Database connection failed: " . $dbconnect->connect_error);
}
$sensor_names = array();
$query2 = mysqli_query($dbconnect,"show tables");
while($row2 = mysqli_fetch_array($query2)){
if($row2[0] == 'sensors' or $row2[0] == 'measurments'){
break;
}
else{
array_push($sensor_names,$row2[0]);
}
}
$query = mysqli_query($dbconnect, "select s.id, s.sensor_name, max(dev.id), dev.temprature, dev.date from sensors s, `{$sensor_names[0]}` dev where s.id=dev.sensor_id gro
up by s.id, s.sensor_name order by s.id asc");
while($row = mysqli_fetch_array($query)){ //i konw this is ugly but this is working placeholder
foreach($sensor_names as $sn){
$query = mysqli_query($dbconnect, "select s.id, s.sensor_name, dev.temprature, dev.date from sensors s, `{$sn}` dev where s.id=dev.sensor_id order by dev.id desc limit 1");
$row = mysqli_fetch_array($query);
echo "
{$row['id']}
{$row['sensor_name']}
{$row['temprature']}
{$row['date']}
<br>";
}
}
?>
This is off-the-cuff from a guy who hasn't touched PHP in a long while, so watch for major bugs. But the basic idea is like this: build the code in a variable, and when done, echo out the entire variable. Makes it easier to add the structure/formatting you want. Note that you can also stick in a style tag along with that code and blurp out the style along with the "table" (Personally, I wouldn't use a table for styling, this is just for demo).
Note: I didn't style the output so that it puts the data on either side of the page - I left that for you to do. It's basic HTML - divs, styles, maybe css grid or flexbox. The point is to create your CSS/HTML/PHP mashup in a string variable and output the entire thing when done.
$out = '<style>.cell_id{font-weight:bold;}</style>';
$out .= '<table><tr><th>Label 1</th><th>Label 2</th><th>Etc</th></tr>'; //<=== ADDED!
while($row = mysqli_fetch_array($query)){
foreach($sensor_names as $sn){
$query = mysqli_query($dbconnect, etc. etc. etc.);
$row = mysqli_fetch_array($query);
$out .= "
<tr>
<td class='cell_id'>{$row['id']}</td>
<td>{$row['sensor_name']}</td>
<td>{$row['temprature']}</td>
<td>{$row['date']}</td>
</tr>";
}
}
echo $out;
Ok I think I got it. Cssyphus's answer got me thinking and I wrote something like that array_push($data, $row) and $data is two dimentional array that hold all data I need and now I can style it easily.

Fetching rows in array using SELECT * FROM table WHERE IN

Hi I am trying to fetch data from a particular coloumn from all rows.
Eg Situation:
DB Data: id, fbid, name
$sql = 'SELECT id FROM table WHERE table.fbid IN (1234,5678,4321)';
$sql_run = mysql_query($sql);
$sql_fetch = mysql_fetch_assoc($sql_run);
print_r($sql_fetch);
This returns the data when I test it using Sequel PRO or PHPmyAdmin.
But when I print the array it only displays one value.
Can you help me with a solution or tell me where I'm going wrong?
<?php
$con=mysqli_connect("example.com","peter","abc123","my_db");
// Check connection
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
$result = mysqli_query($con,"SELECT * FROM Persons");
while($row = mysqli_fetch_array($result))
{
echo $row['FirstName'] . " " . $row['LastName'];
echo "<br>";
}
mysqli_close($con);
?>
Before using a function, or - at least - when it does not what you expect - it's always a good idea to read the function description in the manual page.
PHP provides extremely easy access to its manual pages. All you need to type in the address bar is php.net/function name. It takes less time than typing whole question on Stack Overflow, yet you will get exactly the same answer. Think of efficiency.
You need to loop through each row
$sql_run = mysql_query($sql) or die(mysql_error());
while ($sql_fetch = mysql_fetch_assoc($sql_run)) {
print_r($sql_fetch);
}

How to select certain fields from table in mySQL using PHP

I'm trying out my hand at php at the moment - I'm very new to it!
I was wondering how you would go about selecting all items from a mySQL table (Using a SELECT * FROM .... query) to put all data into an array but then not displaying the data in a table form. Instead, using the extracted data in different areas of a web page.
For example:
I would like the name, DOB and favorite fruit to appear in one area where there is already say 'SAINSBURYS' section hardcoded into the page. Then further down the next row that is applicable to 'ASDA' to appear below that.
I searched both here and google and cant seem to find an answer to my strange questions! Would this involve running the query multiple times filtering out the sainsburies data and the asda data where ever I wanted to place the relevant
echo $row['name']." ";
echo $row['DOB']." "; etc etc
next to where it should go?
I have got php to include data into an array (I think?!)
$query = "SELECT * FROM people";
$result = mysql_query($query) or die(mysql_error());
$row = mysql_fetch_array($result) or die(mysql_error());
while($row = mysql_fetch_assoc($result))
{
echo $row['name']." ";
echo $row['DOB']." ";
echo $row['Fruit']." ";
}
?>
Just place this (or whatever your trying to display):
echo $row['name']." ";
Anywhere you want the info to appear. You can place it within HTML if you want, just open new php tags.
<h1>This is a the name <?php echo $row['name']." ";?></h1>
If you want to access your data later outside the while-loop, you have to store it elsewhere.
You could for example create a class + array and store the data in there.
class User {
public $name, $DOB, $Fruit;
}
$users = new array();
$query = "SELECT * FROM people";
$result = mysql_query($query) or die(mysql_error());
while($row = mysql_fetch_array($result)) {
$user = new User;
$user->name = $row["name"];
$user->DOB = $row["DOB"];
$user->Fruit = $row["Fruit"];
$users[$row["name"]] = $user;
}
Now you can access the user-data this way:
$users["USERNAME"]->name
$users["USERNAME"]->DOB
$users["USERNAME"]->Fruit

Can these database calls be optimized?

I'm working on a project to further learn php and how it can be used to interface with a mysql database. The project is a forum, with the page in question displaying all the topics in a category. I'd like to know if I am handling my calls efficiently, and if not, how can I structure my queries so they are more efficient? I know its a small point with a website that isn't used outside of testing, but I'd like to get a handle on this early.
<?php
$cid = $_GET['cid'];
$tid = $_GET['tid'];
// starting breadcrumb stuff
$catname = mysql_query("SELECT cat_name FROM categories WHERE id = '".$cid."'");
$rcatname = mysql_fetch_array( $catname );
$topicname = mysql_query("SELECT topic_title FROM topics WHERE id = '".$tid."'");
$rtopicname = mysql_fetch_array( $topicname );
echo "<p style='padding-left:15px;'><a href='/'> Home </a> » <a href='index.php'> Categories </a> » <a href='categories.php?cid=".$cid."'> ".$rcatname['cat_name']."</a> » <a href='#'> ".$rtopicname['topic_title']. "</a></p>";
//end breadcrumb
$sql = "SELECT * FROM topics WHERE cat_id='".$cid."' AND id='".$tid."' LIMIT 1";
$res = mysql_query($sql) or die(mysql_error());
if (mysql_num_rows($res) == 1) {
echo "<input type='submit' value='Reply' onClick=\"window.location = 'reply.php?cid=".$cid."&tid=".$tid."'\" />";
echo "<table>";
if ($_SESSION['user_id']) { echo "<thead><tr><th>Author</th><th>Topic » ".$rtopicname['topic_title']."</th></thead><hr />";
} else {
echo "<tr><td colspan='2'><p>Please log in to add your reply.</p><hr /></td></tr>";
}
echo "<tbody>";
while ($row = mysql_fetch_assoc($res)) {
$sql2 = "SELECT * FROM posts WHERE cat_id='".$cid."' AND topic_id='".$tid."'";
$res2 = mysql_query($sql2) or die(mysql_error());
while ($row2 = mysql_fetch_assoc($res2)) {
echo "<tr><td width='200' valign='top'>by ".$row2['post_creator']." <hr /> Posted on:<br />".$row2['post_date']."<hr /></td><td valign='top'>".$row2['post_content']."</td></tr>";
}
$old_views = $row['topic_views'];
$new_views = $old_views + 1;
$sql3 = "UPDATE topics SET topic_views='".$new_views."' WHERE cat_id='".$cid."' AND id='".$tid."' LIMIT 1";
$res3 = mysql_query($sql3) or die(mysql_error());
echo "</tbody></table>";
}
} else {
echo "<p>This topic does not exist.</p>";
}
?>
Thanks guys!
Looks like a classic (n+1) query mistake that could die a latent death. You get a key using one round trip, then you loop over the results to get n values based on it. If the first result set is large you'll have a lot of network round trips.
You could bring it all back in one go with a JOIN and save yourself a lot of network latency.
The statements themselves are fairly simple so there's not much you can do to optimize them further that I know of. However, if you create some business objects and cache the data into them on a single call and then access data from the business objects then it could be faster.
In other words, 1 SQL call for 1,000 rows is going to be much faster than 1,000 calls for a single row.
Here are some of extra things I would do when I write a code like above:
Never use * in SELECT statement when you know the columns you are going to use.
Always use or die(mysql_error()) when executing the query.
Unset the result sets once the result sets has served its purpose.
Use mysql_real_escape_string() to escape the injections when using some substitutions in your queries.

Displaying results after MySQL JOIN query with PHP

$sql = "SELECT messages.text, users.name FROM messages INNER JOIN users ON messages.user_id=users.id ORDER BY messages.ms_id DESC LIMIT 10";
$result = mysql_query($sql);
$rows = array();
while($row = mysql_fetch_array($result))
{
$rows[]=$row;
}
echo $rows[0][1].$rows[0][0];
/* for($i=0;$i<=10;$i++)
{
echo $rows[i][1].$rows[i][0];
}
*/
This script is supposed to show the last 10 messages in a chat.What I'm doing is getting the Name of the user from the users table and the text from the message table and I want to display them in my chat window.Right now I have only 4 messages recorded and don't know how this affects the whole script I should implement a check for this too, but the bigger problem is that when i use echo $rows[0][1].$rows[0][0]; the info is displayed correctly, but when I try to make a loop so I can show tha last 10 (I tried the commented one) then nothing is displayed.I thought at least when I use this loop I'll see the 4 recorded messages but what really happen is a blank window.Obvously I have the info recorded in $rows[] and can echo it, but don't understand why this loop don't work at all.I'll appreciate if someone can help me with this and with the check if the messages are less then 10.
Thanks.
Leron
P.S
Here is the edited script, thanks to all of you, I need the array because otherwise the most recent message is shown at the top which is not an opiton when I use it for diplaying chat masseges.
for($i=10;$i>=0;$i--)
{
if($rows[$i][1]!="" || $rows[$i][0]!="")
{
echo $rows[$i][1].' : '.$rows[$i][0];
echo "</br>";
}
}
Your FOR loop was running 11 times even if only 10 records. The second clause should be a < instead of <=. Plus the $ was missing on the i variable.
For example sake, you don't really need to make an array from the rows, and you can refer to the fields by name:
while($row = mysql_fetch_array($result))
{
echo $row['name'] . ' says: ' . $row['message'] . '<BR>';
}
why not just do
while($row = mysql_fetch_array($result))
{
echo $row[1]." ".$row[0];
}
Your query, auto limits it to the last 10, this will then show anything from 0 to 10 which get returned.
PS I added a space between username and message for readability
You need $ symbols on your i variable:
for($i=0;$i<10;$i++)
{
echo $rows[$i][1].$rows[$i][0];
}
A more robust solution would be like this:
$sql = "SELECT messages.text, users.name FROM messages INNER JOIN users ON messages.user_id=users.id ORDER BY messages.ms_id DESC LIMIT 10";
$result = mysql_query($sql);
while($row = mysql_fetch_array($result))
{
echo $row[1].$row[0];
}

Categories