I have the following within my foreach....this works but there are 2 sets of values per $value and it only shows the first
<?php
$info = simplexml_load_file("https://api.website.co.za/ACCESS_GetAccountSessions?");
echo "<ul info>";
foreach ($info->sessions as $sessions):
$count = $sessions->{'session-count'};
$ip = $sessions->session->{'ip-address'};
$nas = $sessions->session->{'nas-ip-address'};
$port = $sessions->session->{'nas-port'};
$phone = 'N/A';
?>
<?php
echo '<tr>',
'<td class="blockcontentwhite sessionicon">',
'<td class="blockcontentwhite center">' . ("$ip") . '</td>',
'<td class="blockcontentwhite center">' . ("$nas") . '</td>',
'<td class="blockcontentwhite center">' . ("$port") . '</td>',
'<td class="blockcontentwhite center">' . ("$phone") . '</td>',
'</tr>';
endforeach;
?>
so basically within a table on 1st row its showing the $ip , $nas, $port and $phone BUT it is not showing the second values on the 2nd row , any ideas?
Thanks Guys
You are trying to access an object as an array. $info->sessions is of type SimpleXMLElement Object which contains (as a property) the array you want to use in the foreach.
Change your foreach ( foreach ($info->sessions as $sessions): ) to foreach ($info->sessions->session as $sessions): and:
$count = $sessions->{'session-count'};
$ip = $sessions->session->{'ip-address'};
$nas = $sessions->session->{'nas-ip-address'};
$port = $sessions->session->{'nas-port'};
$phone = 'N/A';
to:
$count = $info->sessions->{'session-count'};
$ip = $sessions->{'ip-address'};
$nas = $sessions->{'nas-ip-address'};
$port = $sessions->{'nas-port'};
$phone = 'N/A';
I think Jueecy is correct regarding the question you asked about.
But I noticed something that looks like it might be a problem besides that. It looks like the code will generate multiple tables, but I think you just want multiple rows in the same table.
I would suggest moving your foreach down to where you are generating the rows:
<?php
$info = simplexml_load_file("https://api.website.co.za/ACCESS_GetAccountSessions?");
echo "<ul info>";
?>
<input type="hidden" name="ctl00$ctl00$contentDefault$contentControlPanel$hdnIsSecure" id="ctl00_ctl00_contentDefault_contentControlPanel_hdnIsSecure" value="false" />
<table id="active_sessions_table" class="blocktable centered" cellpadding="0" cellspacing="0">
<tr class="blockheader">
<td id="active_sessions_title" class="left" colspan="2">
<label class="floatleft">Current connections</label></td>
</tr>
<tr id="trconnections">
<td class="blockcellnopadding" colspan="2">
<table cellpadding="4" cellspacing="0" width="100%" style="border-bottom:solid 1px #bfbfbf;">
<tr>
<td class="columntitle center"> </td>
<td class="columntitle center">IP Address</td>
<td class="columntitle center">NAS IP Address</td>
<td class="columntitle center">Line Port</td>
<td class="columntitle center">Telephone Number</td>
</tr>
<?php
foreach ($info->sessions->session as $session) {
$ip = $session->{'ip-address'};
$nas = $session->{'nas-ip-address'};
$port = $session->{'nas-port'};
$phone = 'N/A';
echo '<tr>',
'<td class="blockcontentwhite sessionicon">',
'<td class="blockcontentwhite center">' . ("$ip") . '</td>',
'<td class="blockcontentwhite center">' . ("$nas") . '</td>',
'<td class="blockcontentwhite center">' . ("$port") . '</td>',
'<td class="blockcontentwhite center">' . ("$phone") . '</td>',
'</tr>';
};
?>
Related
I am using a foreach to elaborate some values scraped from a web site. It works but I have the follow problem (I put screens to explain my problem in the best way).
In the first screen, you can see that Derry City - Limerick doesn't have 1 X 2 odds
But when I get that values, my code fill empty odds with the first odds available, see the screen below:
This is the HTML code:
<table class="table-main js-tablebanner-t js-tablebanner-ntb">
<tr><th class="h-text-left" colspan="2">2. Round</th><th> </th><th class="table-main__bs">B's</th><th class="h-text-center">1</th><th class="h-text-center">X</th><th class="h-text-center">2</th></tr>
<tr>
<td class="table-main__datetime">21.03.2017 20:45</td>
<td class="h-text-left"><span>Derry City</span> - <span>Limerick</span></td>
<td class="h-text-right">
<ul class="list-tags"><li class="list-tags__item"><i class="icon icon__stream"></i><div class="list-tags__window list-tags__window--streams"><ul class="list-tags__window__in">
<li>Live streams</li>
<li>bwin</li>
<li>Sportingbet</li>
</ul></div></li></ul>
</td>
<td class="table-main__bs"> </td>
<td class="table-matches__odds" data-oid=""> </td>
<td class="table-matches__odds" data-oid=""> </td>
<td class="table-matches__odds" data-oid=""> </td>
</tr>
<tr><th class="h-text-left" colspan="2">5. Round</th><th> </th><th class="table-main__bs">B's</th><th class="h-text-center">1</th><th class="h-text-center">X</th><th class="h-text-center">2</th></tr>
<tr>
<td class="table-main__datetime">18.03.2017 15:00</td>
<td class="h-text-left"><span>Limerick</span> - <span>Finn Harps</span></td>
<td class="table-matches__odds" data-oid="2kou5xv464x0x5uaff"></td>
<td class="table-matches__odds" data-oid="2kou5xv498x0x0"></td>
<td class="table-matches__odds" data-oid="2kou5xv464x0x5uafg"></td>
</tr>
<tr>
<td class="table-main__datetime">18.03.2017 16:00</td>
<td class="h-text-left"><span>Derry City</span> - <span>Drogheda</span></td>
<td class="table-main__bs">23</td>
<td class="table-matches__odds" data-oid="2kp2nxv464x0x5uaoj"></td>
<td class="table-matches__odds" data-oid="2kp2nxv498x0x0"></td>
<td class="table-matches__odds" data-oid="2kp2nxv464x0x5uaok"></td>
</tr>
and, at least, this is my code:
$match_dates = $html->find("td[class=table-main__datetime]");
$titles = $html->find("a[class=in-match]"); // 1 per match
$odds = $html->find("td[class=table-matches__odds]/a"); // 2
function print_odd($odd) {
if (array_key_exists('data-odd', $odd->attr)) {
return $odd->attr['data-odd'];
}
return $odd->children(0)->children(0)->children(0)->attr['data-odd'];
}
$c=0; $b=0; $o=0; $z=0; // two counters
foreach ($titles as $match) {
list($num1, $num2) = explode(':', $res->innertext); // <- explode
list($home, $away) = explode('-', $titles[$z++]->innertext); // <- explode
list($date, $time) = explode('-', $match_dates[$o++]->innertext); // <- explode
$odd1 = print_odd($odds[$b++]);
$odd2 = print_odd($odds[$b++]);
$odd3 = print_odd($odds[$b++]);
$home = strip_tags($home);
$away = strip_tags($away);
$uniquefield = $home . ' ' . $away;
echo "<tr><td class='rtitle'>".
//"<td class='last-cell'>".$match_dates[$o++]->innertext. "</td> " .
"<td> ".$date.'</td><td> : </td><td>'.$time . " / " .
"<td> ".$home.'</td><td> : </td><td>'.$away . " / " .
"<td class='odds'>".$odd1 . ";" .
"".$odd2 . ";" .
"".$odd3 . "</td>" .
"".$uniquefield."</td></tr><br/>";
I have this php codes:
$main_url = "http://www.sports-reference.com/olympics/countries/DEN/summer/1896/";
$main_html=file_get_html($main_url);
$link = $main_html->getElementById('div_sports');
foreach ($link->find('td') as $element){
foreach($element->find('href') as $node){
echo $node->item(0)->nodeValue . "\n";
//$link_clean = $node->getAttribute('href');
echo $link_clean . "\n";
}
}
If I print out $element, I get this output:
<td align="left" >Athletics</td>
<td align="left" >Fencing</td>
<td align="left" >Gymnastics</td>
<td align="left" >Shooting</td>
<td align="left" >Weightlifting</td>
I need to extract this info:
/olympics/countries/DEN/summer/1896/ATH/
/olympics/countries/DEN/summer/1896/FEN/
..........
and so on. the code above is not working. CAn you helpme?
href is not a tag, it is a tag attribute.
So, you have to search for <a>:
foreach( $element->find('a') as $a)
{
echo $a->href . "\n";
(...)
}
My idea is to create a Q&A section under a product profile, just like on eBay or Amazon or whatever. The idea is to send a question and then get the owner of the article to reply.
The table has these columns: pid (product ID), id (question ID), question, answer, date (date posted), username.
So if I post a question, I get the ID of the product in which I'm posting and create a question. The the owner just sends the answer to the row that matches the question.
Here's my PHP code to retrieve all the info from that table:
$qanda = '';
$link = mysql_connect("localhost", "youknowwhat", "youknowwhat");
mysql_select_db("youknowwhat", $link);
$qandaq = mysql_query("SELECT * FROM questions WHERE id='$id2' ORDER BY date", $link);
$count = mysql_num_rows($qandaq);
if($count >= 1){
while($rows = mysql_fetch_array($qandaq)){
$date = $rows['date'];
$q = $rows['question'];
$a = $rows['answer'];
$usrname = $rows['username'];
}
$qanda .= '<div id="answers" align="center">
<table cellspacing="0" align="center">
<tr align="center">
<td width="200">' . $date . '</td>
<td rowspan="2" width="400"><strong>' . $q . '</strong><br>' . $a . '</td>
<td width="200">Delete</td>
</tr>
<tr align="center">
<td>' . $usrname . '</td>
<td>Report</td>
</tr>
</table>
</div>';
} else {
$qanda = '<div id="answers" align="center">
No questions for this product.
</div>';
}
Now... what you see as a table in the variable $qanda I want to repeat it over and over again but displaying different row data but the concatenation isn't working and I can only get the last row to be displayed. I just can't seem to find out why this isn't working! Am I missing something?
All you have to do is append your divs (.=) while you're inside the while loop that mysql_fetch_array() rows.
Then you'll have a new div for each row your database returns, and you can populate it easily.
$qanda = '';
while($rows = mysql_fetch_array($qandaq)){
$date = $rows['date'];
$q = $rows['question'];
$a = $rows['answer'];
$usrname = $rows['username'];
$qanda .= '<div id="answers" align="center">
<table cellspacing="0" align="center">
<tr align="center">
<td width="200">' . $date . '</td>
<td rowspan="2" width="400"><strong>' . $q . '</strong><br>' . $a . '</td>
<td width="200">Delete</td>
</tr>
<tr align="center">
<td>' . $usrname . '</td>
<td>Report</td>
</tr>
</table>
</div>';
}
Here is the table below that I'm trying to delete rows out of:
<form method="POST" >
<table class="sortable">
<thead>
<tr>
<th id="makehead">Make </th>
<th id="modelhead">Model </th>
<th id="idhead">Delete </th>
</tr>
</thead>
<tbody>
<?php
$i = 0;
foreach ($carArray as $k => $carInfo) {
$i++;
echo '<tr>';
if ($i % 2) {
echo '<td class="make">' . $carInfo['make'] . '</td>
<td class="model">' . $carInfo['model'] . '</td>
<td class="id"><input type="checkbox" name="id" value="' . $carInfo['id'] . '">' . $carInfo['id'] . '</td>';
} else {
echo '<td class="makelight">' . $carInfo['make'] . '</td>
<td class="modellight">' . $carInfo['model'] . '</td>
<td class="idlight"><input type="checkbox" name="id" value="' . $carInfo['id'] . '">' . $carInfo['id'] . '</td>';
}
}
?>
</tr>
</table>
</tbody>
<td>
<input Onclick="return ConfirmDelete();" name="delete" type="submit" id="delete" value="Delete"></input>
</td>
</table></form>
As you can see i'm using checkboxes to tick each row then the delete button will have a confirm message then should delete but it doesn't here is my if statement:
if ($_REQUEST['delete']) {
$dbid = $_REQUEST['id'];
$db->setdbid($dbid);
So when this wasn't working I had a look on here and on other questions people said I need a setter function so i did this: EDIT: this is my class file.
public function setdbid($dbid){
$this->dbid=$dbid;
}
for this main function to delete things:
public function delete($dbid) {
try {
$sql = "DELETE FROM cars WHERE id = '$dbid'";
$this->db->exec($sql);
echo "Car has been deleted.";
} catch (PDOException $e) {
echo $e->getMessage();
}
}
So that's all the relevant code I think, please help me if you can.
You just have to replace some piece of code in PHP :
if ($_REQUEST['delete']) {
$dbid = $_REQUEST['id'];
$db->delete($dbid); //Assuming delete is well a $db method, else replace it by the correct delete call
}
As you are using checkboxes with the same name, you have to change it so it's an array (and this way you'll be able to delete multiple rows at once) :
<td class="id"><input type="checkbox" name="ids[]" value="' . $carInfo['id'] . '">' . $carInfo['id'] . '</td>';
Then in your php code, treat this data as such :
if ($_REQUEST['delete']) {
foreach($_REQUEST['ids'] as $id){
$xxx->delete(intval($id)); //convert to integer to avoid sql injection.
}
}
Note that you don't need to set $db->setdbid since you pass that id as a parameter of your delete method.
I have 2 small questions I need help on which deals with the code below:
echo "<table border='1' id='markstbl'>
<tr>
<th class='questionth'>Question No.</th>
<th class='questionth'>Question</th>
<th class='answerth'>Answer</th>
<th class='answermarksth'>Marks per Answer</th>
<th class='noofmarksth'>Total Marks</th>
</tr>\n";
$previous_question_id = null;
foreach ($searchQuestionContent as $key=>$question) {
if ($previous_question_id == $searchQuestionId[$key]) {
$searchQuestionId[$key] = '';
$question = '';
$searchMarks[$key] = '';
}else{
$previous_question_id = $searchQuestionId[$key];
}
echo '<tr class="questiontd">'.PHP_EOL;
echo '<td class="optiontypetd">'.htmlspecialchars($searchQuestionId[$key]).'</td>' . PHP_EOL;
echo '<td>'.htmlspecialchars($question).'</td>' . PHP_EOL;
echo '<td class="answertd">';
echo $searchAnswer[$key];
echo '</td>' ;
echo '<td class="answermarkstd"><input class="individualMarks" name="answerMarks[]" id="individualtext" type="text" "/></td>' . PHP_EOL;
echo '<td class="noofmarkstd">'.htmlspecialchars($searchMarks[$key]).'</td>' . PHP_EOL;
}
echo '</tr>';
echo "</table>" . PHP_EOL;
Question 1: If you look at the table above, I have a a column where it will contain text inputs. Now each text input will belong to each answer in the "Answer" column. My question is that is the text input set up correctly with me including a [] in the name attribute to set up an array? Should I include [] and is there anything else I should include in the text input code?
Question 2: At the moment the code above makes the table look like this example in JSFIDDLE1. But I want the table to be displayed as this example JSFIDDLE2. As you can see the blank rows in the other table have been rowspan so that it looks like the question and the total marks looks like its in one cell. How can I get the table above to look like JSFIDDLE2?
UPDATE:
Below is the full code, I am still receiving undefined index whenver $rowspans[.... is used. Is the code below correct:
$assessment = $_SESSION['id'] . $sessionConcat;
$query = "SELECT q.SessionId, s.SessionName, q.QuestionId, q.QuestionContent, an.Answer, q.QuestionMarks
FROM Session s
INNER JOIN Question q ON s.SessionId = q.SessionId
JOIN Answer an ON q.QuestionId = an.QuestionId AND an.SessionId = q.SessionId
WHERE s.SessionName = ?
ORDER BY q.QuestionId, an.Answer
";
// prepare query
$stmt=$mysqli->prepare($query);
// You only need to call bind_param once
$stmt->bind_param("s", $assessment);
// execute query
$stmt->execute();
// This will hold the search results
$searchQuestionId = array();
$searchQuestionContent = array();
$searchAnswer = array();
$searchMarks = array();
// Fetch the results into an array
// get result and assign variables (prefix with db)
$stmt->bind_result($dbSessionId, $dbSessionName, $dbQuestionId, $dbQuestionContent, $dbAnswer, $dbQuestionMarks);
while ($stmt->fetch()) {
$searchQuestionId[] = $dbQuestionId;
$searchQuestionContent[] = $dbQuestionContent;
$searchAnswer[] = $dbAnswer;
$searchMarks[] = $dbQuestionMarks;
}
?>
</head>
<body>
<form id="QandA" action="<?php echo htmlentities($_SERVER['PHP_SELF']); ?>" method="post">
<?php
echo "<table border='1' id='markstbl'>
<tr>
<th class='questionth'>Question No.</th>
<th class='questionth'>Question</th>
<th class='answerth'>Answer</th>
<th class='noofmarksth'>Total Marks</th>
</tr>\n";
$previous_question_id = null;
$rowspans = array_count_values($searchQuestionId);
foreach ($searchQuestionContent as $key=>$question) {
if ($previous_question_id == $searchQuestionId[$key]) {
$searchQuestionId[$key] = '';
$question = '';
$searchMarks[$key] = '';
}else{
$previous_question_id = $searchQuestionId[$key];
}
echo '<tr class="questiontd">'.PHP_EOL;
echo '<td class="optiontypetd">'.htmlspecialchars($rowspans[$searchQuestionId[$key]]).'</td>' . PHP_EOL;
echo '<td>'.htmlspecialchars($question).'</td>' . PHP_EOL;
echo '<td class="answertd">';
echo $searchAnswer[$key];
echo '</td>'; echo '<td class="noofmarkstd">'.htmlspecialchars($searchMarks[$key]).'</td>' . PHP_EOL;
}
echo '</tr>';
echo "</table>" . PHP_EOL;
?>
<p><input id="submitBtn" name="submitMarks" type="submit" value="Submit Marks" /></p>
</form>
Q1. Yes, you could even specify a name between the [].
Q2. It seems that $searchQuestionId is filled before your loop, right? In that case you could use array_count_values to store the frequency of each ID and access that array during the loop:
before your loop: $rowspans = array_count_values($searchQuestionId);
access rowspan value during loop with: $rowspans[$searchQuestionId[$key]].
You'll have to remove the line $searchQuestionId[$key] = ''; or else you won't be able to access the correct $rowspan key.
Finally, you'll have to set up some more if statements to skip the <td>s on certain rows.
$previous_question_id = null;
$rowspans = array_count_values($searchQuestionId);
foreach ($searchQuestionContent as $key=>$question) {
// removed logic, not necessary to set empty strings if you're skipping them
echo '<tr class="questiontd">'.PHP_EOL;
if ($previous_question_id != $searchQuestionId[$key]) {
echo '<td class="optiontypetd" rowspan="'.$rowspans[$searchQuestionId[$key]].'">'.htmlspecialchars($searchQuestionId[$key]).'</td>' . PHP_EOL;
echo '<td rowspan="'.$rowspans[$searchQuestionId[$key]].'">'.htmlspecialchars($question).'</td>' . PHP_EOL;
}
echo '<td class="answertd">';
echo $searchAnswer[$key];
echo '</td>' ;
echo '<td class="answermarkstd"><input class="individualMarks" name="answerMarks[]" id="individualtext" type="text" "/></td>' . PHP_EOL;
if ($previous_question_id != $searchQuestionId[$key]) {
echo '<td class="noofmarkstd" rowspan="'.$rowspans[$searchQuestionId[$key]].'">'.htmlspecialchars($searchMarks[$key]).'</td>' . PHP_EOL;
}
// moved this to the end
if ($previous_question_id != $searchQuestionId[$key]) {
$previous_question_id = $searchQuestionId[$key];
}
}