I'm new to OOP (and programming for that matter, started a few months ago) so classes and objects are still a bit of a foreign concept to me. Anyhow, I'm attempting to store a mix of strings and variables in an array for later processing. See method drawtable(). drawtable() prints the tableheaders just fine, but tableheaders is just an array of strings. The issue comes when I try to print the tablelink, and text properties, which I've attempted to include variables in. What am I doing wrong here? Note: the session variables output fine.
I would also appreciate any general critiques of the code below, as I'm new and attempting to nip any bad habits in the bud. Many thanks.
<?php
class table{
function __construct($type){
if($type == "submittals"){
$this->tableheaders = array('Specification Section', 'Submittal #', 'Description', 'Vendor or Manufacturer', 'Date Received By GC', 'File', 'Date Submitted', 'File', 'Date Requested for Review', 'Date Returned to GC', 'File', 'Status', 'Date Returned to Subcontractor or Vendor');
$this->query = "***SELECT Query***";
$this->tablelink = array("/pd/upload/" . $_SESSION['current_project'] . "/s/" . $row['file'], "edit_submittal.php?submittal_id=", "edit_submittal.php?submittal_id=" . $row['submittal_id']);
$this->text = array($row['number'] . " - " . $row['name'], $this->row['submittal_num']);
}
}
function drawtable() {
$this->numheaders = count($this->tableheaders);
$this->db = mysqli_connect(***db connection info***);
$this->results = mysqli_query($this->db, $this->query);
$this->num_results = mysqli_num_rows($this->results);
echo " <table border=\"1\">
<tr>";
for ($i = 0; $i < $this->numheaders; $i++) {
echo "<th>" . $this->tableheaders[$i] . "</td>";
}
echo " </tr>";
for ($j=0; $j < $this->num_results; $j++) {
$row = mysqli_fetch_assoc($this->results);
echo " <tr>";
for($k = 0; $k < $this->numheaders; $k++) {
echo " <td>" . $this->text[$k] . "xxx</td>";
}
}
echo " </tr>
</table>";
}
}
?>
Update:Okay well this works, but I'm sure it's still has an air of noob sloppiness. Suggestions? Thanks
<?php
class Table{
function __construct($type){
if($type == "submittals"){
$this->table_headers = array('Specification Section', 'Submittal #', 'Description', 'Vendor or Manufacturer', 'Date Received By GC', 'File', 'Date Submitted', 'File', 'Date Requested for Review', 'Date Returned to GC', 'File', 'Status', 'Date Returned to Subcontractor or Vendor');
$this->query = "***SELECT query***";
}
}
function draw_table($type) {
$this->num_headers = count($this->table_headers);
$this->db = mysqli_connect(***db connection***);
$this->results = mysqli_query($this->db, $this->query);
$this->num_results = mysqli_num_rows($this->results);
echo " <table border=\"1\">
<tr>";
for ($i = 0; $i < $this->num_headers; $i++) {
echo "<th>" . $this->table_headers[$i] . "</td>";
}
echo " </tr>";
for ($j=0; $j < $this->num_results; $j++) {
$row = mysqli_fetch_assoc($this->results);
if($type == "submittals") {
$this->table_link = array("/pd/upload/" . $_SESSION['current_project'] . "/s/" . $row['file'], "edit_submittal.php?submittal_id=", "edit_submittal.php?submittal_id=" . $row['submittal_id']);
$this->text = array($row['number'] . " - " . $row['name'], $row['submittal_num'], $row['description']);
}
echo " <tr>";
for($k = 0; $k < $this->num_headers; $k++) {
echo " <td>" . $this->text[$k] . "</td>";
}
}
echo " </tr>
</table>";
}
function get_table_headers() {
echo $this->table_headers;
}
function get_query() {
echo $this->query;
}
function get_table_link() {
echo $this->table_link;
}
function get_text() {
echo $this->text;
}
}
?>
It doesn't work like this. You can't access $row in the constructor as over there the variable is undefined. You expect PHP to realize that it should replace the content of $row['name'] etc. later when you actually use the string. However, why should it? Instead PHP can't find $row at all and everything goes wrong. Actually, you should get an error telling you that $row is undefined.
Overall there is quite a lot wrong with your code. Sorry to say so, but you do not yet grasp the general concept of OOP at all. And it would take way too long to explain this here. And apparently there are some thing not even related to OOP, which you don't know. Scopes for example and about when and where variables exist.
Related
Hi guys i am trying to display the first td values as static so i have keep those values in one array and i try to increase the values and try to display but when i get it is displaying depending on foreach values if i have one record in foreach it is displaying one value and if i have 2 records it is displaying 2 values.
But i want to display all td value if i have values in foreach or not also.
Here is my code:
<tbody>
<?php
$arr = array(0=>'On Hold',1=>'Asset Incomplete',2=>'SME Discussion',3=>'a',4=>'b',5=>'c',6=>'d',7=>'e',8=>'f',9=>'g',10=>'h');
$i = 0;
foreach($getCourse as $report)
$status= $report->status;
{
?>
<tr>
<td><?php echo $arr[$i]; ?>
<?php $i++; ?></td>
<td><?php
if($status==1)
{
echo "On Hold";
}
elseif($status==2)
{
echo "Asset Incomplete";
}
elseif($status==3)
{
echo "Yet to Start";
}
elseif($status==4)
{
echo "SME Discussion";
}
elseif($status==5)
{
echo "Development";
}
elseif($status==6)
{
echo "PB Review";
}
elseif($status==7)
{
echo "PB Fixes";
}
elseif($status==8)
{
echo "PB2 Review";
}
elseif($status==9)
{
echo "PB2 Fixes";
}
elseif($status==10)
{
echo "Alpha Development";
}
elseif($status==11)
{
echo "Alpha Review";
}
elseif($status==12)
{
echo "Alpha Fixes";
}
elseif($status==13)
{
echo "Beta Review";
}
elseif($status==14)
{
echo "Beta Fixes";
}
elseif($status==15)
{
echo "Gamma";
}
?></td>
<td><?php echo $report->coursename; ?></td>
<td><?php echo $report->statuscount;?></td>
<td></td>
</tr>
<?php
}
?>
</tbody>
Here is my controller:
public function index()
{
if ($this->session->userdata('is_logged')) {
$data['getCourse']=$this->Report_model->getTopicReports();
$this->load->view('template/header');
$this->load->view('reports/report',$data);
$this->load->view('template/footer');
}
else {
redirect("Login");
}
}
Here is my model:
public function getTopicReports()
{
$this->db->select('count(t.status) as statuscount,t.topicName as topicname,c.coursename,t.status')
->from('topics t')
->join('course c', 't.courseId = c.id')
->where('t.courseid',1)
->where('t.status',5);
$query = $this->db->get();
return $query->result();
}
This is how i want to display here is my referrence image:
Can anyone help me how to do that thanks in advance.
FINAL UPDATED & WORKING VERSION
For me this was tricky. This turned out to be what I felt to be a awkward indexing issue.
The problem is that your data is not optimized very well to accommodate the task you are asking for. You have to make odd comparisons as you traverse the table. I was able to get it accomplished.
I would actually be very interested in seeing a more refined approach. But until that happens this code will dynamically generate a table that matches the output of the sample pictures that you posted in your question.
I have tested this code with some sample data that matches the array structure that you posted in your comments.
Here is the code:
//Create an array with your status values.
$rowName = array(
'On Hold',
'Asset Incomplete',
'Yet to Start',
'SME Discussion',
'Development',
'PB Review',
'PB Fixes',
'PB2 Review',
'PB2 Fixes',
'Alpha Development',
'Alpha Review',
'Alpha Fixes',
'Beta Review',
'Beta Fixes',
'Gamma'
);
//Generate a list of class names and get rid of any duplicates.
foreach($getCourse as $report){
$courseNames[] = $report->coursename;
}
$courseNames = array_unique($courseNames);
//Create the header.
echo
'<table>
<thead>
<tr>
<th>#</th>';
foreach($courseNames as $course){
echo '<th>' . $course . '</td>';
}
echo
'<th>Total</th>
</tr>
</thead>
<tbody>';
//Iterate across the array(list) of status values.
for($i = 0; $i < count($rowName); $i++){
echo
'<tr>';
echo '<td>' . $rowName[$i] . '</td>';
//Iterate through all combinations of class names and status values.
for($j = 0; $j < count($courseNames); $j++){
//Set flags and intial values.
$found = FALSE;
$total = 0;
$value = NULL;
for($k = 0; $k < count($getCourse); $k++){
//***Note - The ""$getCourse[$k]->status - 1" is because the status values in your data do not appear
//to start with an index of 0. Had to adjust for that.
//Sum up all the values for matching status values.
if(($getCourse[$k]->status - 1) == $i){
$total += $getCourse[$k]->statuscount;
}
//Here we are checking that status row and the status value match and that the class names match.
//If they do we set some values and generate a table cell value.
if(($getCourse[$k]->status - 1) == $i && $courseNames[$j] == $getCourse[$k]->coursename){
//Set flags and values for later.
$found = TRUE;
$value = $k;
}
}
//Use flags and values to generate your data onto the table.
if($found){
echo '<td>' . $getCourse[$value]->statuscount . '</td>';
}else{
echo '<td>' . '0' . '</td>';
}
}
echo '<td>' . $total . '</td>';
echo
'</tr>';
}
echo '</tbody>
</table>';
Try this. I am storing course status in $used_status then displaying the remaining status which are not displayed in foreach.
$arr = array ( '1' =>'On Hold', '2' => 'Asset Incomplete', '3' => 'SME Discussion', '4' => 'a', '5' => 'b', '6' => 'c', '7' =>'d', '8' => 'e', '9' => 'f', '10' => 'g', '11' => 'h' );
$used_status = array();
foreach($getCourse as $report) { ?>
<tr>
<td>
<?php $course_status = isset($arr[$report->status]) ? $arr[$report->status] : "-";
echo $course_status;
$used_status[] = $course_status; ?>
</td>
<td>
<?php echo $report->coursename; ?>
</td>
<td>
<?php echo $report->statuscount; ?>
</td>
</tr>
<?php }
foreach($arr as $status) {
if(!in_array($status, $used_status)) { ?>
<tr>
<td>
<?php echo $status; ?>
</td>
<td>
<?php echo "-"; ?>
</td>
<td>
<?php echo "-"; ?>
</td>
</tr>
<?php }
} ?>
I try to display every each data on the specific td, but I dont know where to fix my code. Please check the screenshop below to understand the clearly problems. Please any help to solve this problems.
<table class="table table-hover table-bordered ">
<tr><th>Day</th><th colspan="2">08:00-08:40</th><th colspan="2">8:40-09:20</th><th colspan="2">09:20-10:00</th><th>10:00-10:15</th><th colspan="2">10:15-10:55</th><th colspan="2">10:55-11:35</th><th colspan="2">11:35-12:15</th><th>12:15-01:15</th><th colspan="2">01:15-01:55</th><th colspan="2">01:55-02:35</th></tr>
<?php
$timesVariants = array("08:00-08:40", "08:40-09:20", "09:20-10:00", "10:00-10:15", "10:15-10:55", "10:55-11:35", "11:35-12:15", "12:15-01:15", "01:15-01:55","01:55-02:35");
$sqlquery = "SELECT * FROM timetable,classroom,subprogramme WHERE classroom.classid = timetable.classid AND subprogramme.subid = timetable.subid";
$res = $connect->query($sqlquery);
$classes = array();
while($row = $res->fetch_assoc()) {
$classes[$row['day']][$row['tid']][$row['time']] = array('courseid'=> $row['cid'], 'classname' => $row['classname'], 'subname' => $row['subname']);
}
//This is a loop
foreach($classes as $day => $daySchedule) {
foreach($daySchedule as $teacher) {
print '<tr>';
print "<td>$day</td>";
foreach($timesVariants as $time) {
if (empty($teacher[$time])){
print "<td>*</td><td>*</td>";
}
else{
print '<td>' . $teacher[$time]['courseid'] . '</td><td>' . $teacher[$time]['subname'] . ''. $teacher[$time]['classname'] . '</td>';
}
}
print '</tr>';
}
}
?>
</table>
Output
Results display on the webpage
You trouble is in the GROUP BY. MySql have no strict restrictions (by default) that each column should use aggregation function, so the result is the first row, instead of complicating SQL use PHP, your result seems not to be huge, so another loop will not affect performance:
$timesVariants = array("08:00-08:40", "08:40-09:20", "09:20-10:00", "10:00-10:15", "10:15-10:55", "10:55-11:35", "11:35-12:15", "12:15-1:15", "01:15-01:55","01:55-02:35");
$sqlquery = "SELECT * FROM timetable";
$classes = array();
while($row = $res->fetch_assoc()) {
$classes[$row['day']][$row['tid']][$row['time']] = array('subject'=> $row['subject'], 'class' => $row['class'], 'progid' => $row['progid']);
}
//This is a loop
foreach($classes as $day => $daySchedule) {
foreach($daySchedule as $teacher) {
print '<tr>';
print "<td>$day</td>";
foreach($timesVariants as $time) {
if (empty($teacher[$time]))
print "<td>None</td><td>None</td>";
else
print '<td>' . $teacher[$time]['subject'] . '</td><td>' . $teacher[$time]['class'] . '</td>';
}
print '</tr>';
}
}
<?php
if(isset($_POST["tid"])){
$tid = $connect->real_escape_string($_POST["tid"]);
$sqlquery = "SELECT * FROM timetable,classroom,subprogramme WHERE classroom.classid = timetable.classid AND subprogramme.subid = timetable.subid AND timetable.tid = ".$tid." ORDER BY timetable.timid ASC";
$res = $connect->query($sqlquery);
if($res->num_rows > 0){
?>
<table class="table table-bordered table-striped">
<tr><th>Day</th><th colspan="2">8:00-8:40</th><th colspan="2">8:40-9:20</th><th colspan="2">9:20-10:00</th><th colspan="2">10:00-10:15</th><th colspan="2">10:15-10:55</th><th colspan="2">10:55-11:35</th><th colspan="2">11:35-12:15</th><th colspan="2">12:15-1:15</th><th colspan="2">1:15-1:55</th><th colspan="2">1:55-2:35</th></tr>
<?php
$timesVariants = array("8:00-8:40", "8:40-9:20", "9:20-10:00", "10:00-10:15", "10:15-10:55", "10:55-11:35", "11:35-12:15", "12:15-01:15", "1:15-1:55","1:55-2:35");
$classes = array();
while($row = $res->fetch_assoc()) {
$classes[$row['day']][$row['tid']][$row['time']] = array('courseid'=> $row['cid'], 'classname' => $row['classname'], 'subname' => $row['subname']);
}
//This is a loop
foreach($classes as $day => $daySchedule) {
foreach($daySchedule as $teacher) {
print '<tr>';
print "<td>$day</td>";
foreach($timesVariants as $time) {
if (empty($teacher[$time])){
print "<td>*</td><td>*</td>";
}
else{
print '<td>' . $teacher[$time]['courseid'] . '</td><td>' . $teacher[$time]['subname'] . ''. $teacher[$time]['classname'] . '</td>';
}
}
print '</tr>';
}
}
?>
</table>
<?php
}
else{ print "<div class='alert alert-danger col-md-4'><span class='glyphicon glyphicon-remove'></span> Not yet set timetable</div>"; }
} ?>
</div>
The problems was on td I forgot to put colspan = 2, and other problem on sql query I forgot to inner join the tables in order to get all right that i want to display on the page.
I have this function:
function get_content($text_to_match) {
$query = "SELECT * ";
$query .= "FROM table_name ";
$query .= "WHERE one_column_name LIKE '%{$text_to_match}%' OR another_column_name LIKE '%{$text_to_match}%'";
$cont = mysqli_query($connection, $query);
if($content = mysqli_fetch_assoc($cont)) {
return $content;
} else {
return null;
}
}
But when I call it like:
<div>
<?php
for ($i = 1; $i < count(get_content("text_to_match")); $i++) {
echo '<article>' .
'<h3>' . get_content("text_to_match")["string1"] . '</h3>'.
'<p>' . get_content("text_to_match")["string2"] . '</p>' .
'</article>';
}
?>
</div>
I only get the first match in the DB repeated as many times as the number of found items.
Where have I gone wrong?
use this code then fetch data properly
while($content = mysql_fetch_array($cont))
{
return $content;
}
Your logic is at fault. You are calling get_content function to get all matches for the loop, as well as to get individual elements out of the list. This is:
bad logic - the 2nd use case doesn't make sense
excessive - you shouldn't need to run a database query just to output an already retrieved result
What you probably want to do is:
foreach (get_content('text_to_match') as $content) {
echo '<article>';
echo '<h3>' . $content['string1'] . '</h3>';
echo '<p>' . $content['string2'] . '</p>';
echo '</article>';
}
With a few modifications in combination with tips from #Anant and #Unix One's answer, I arrived at this working solution:
Function definition
function get_content($text_to_match, $multiple=false) {
$query = "SELECT * ";
$query .= "FROM table_name ";
$query .= "WHERE one_column_name LIKE '%{$text_to_match}%' OR another_column_name LIKE '%{$text_to_match}%'";
$cont = mysqli_query($connection, $query);
if ($multiple) {
$content_array = [];
while($content = mysqli_fetch_array($cont)) {
$content_array[] = $content;
}
return $content_array;
} else {
if($content = mysqli_fetch_assoc($cont)) {
return $content;
} else {
return null;
}
}
}
Function calls
<?php
/* multiple items */
foreach(get_content("text_to_match", true) as $content) {
echo '<article>' .
'<h3>' . $content["string1"] . '</h3>' .
'<p>' . $content["string2"] . '</p>' .
'</article>';
}
?>
<?php
/* one item */
echo get_content("text_to_match")["string"];
?>
I have question referring to the session in PHP.
I've coded in PHP for setting the session and I want to delete it , but I got some errors and confusing with using the UNSET(variable $_SESSION). Perhaps anyone could help me to show what should I do with this matter. Thanks in advance
$_SESSION['chart'] = array();
$_SESSION['chart'][0]['index'] = 0
$_SESSION['chart'][0]['type'] = $type;
$_SESSION['chart'][0]['idanimal'] = $iddog;
$_SESSION['chart'][0]['price'] = $price;
printdata(); // <== this is the function to print out the data
All I want to do is just delete based on the index in this session
Here's the function :
function printdata()
{
$totalharga = 0;
if(is_array($_SESSION['chart']))
{
echo "<h3>"."Berikut adalah keranjang belanja anda" . "</h3>". "<br>";
$max = count($_SESSION['chart']);
$th1 = "<th>" . "No" . "</th>";
$th2 = "<th>" . "Animal Type" . "</th>";
$th3 = "<th>" . "ID Binatang" . "</th>";
$th4 = "<th>" . "Harga" . "</th>";
$th5 = "<th>" . "Hapus Data" . "</th>";
echo "<table border=1>";
echo "<tr>";
echo $th1 ;
echo $th2;
echo $th3;
echo $th4;
echo $th5;
echo "</tr>";
for ($indexo = 0; $indexo < $max; $indexo++)
{
echo "<tr>";
echo "<td>" . $indexo."</td>";
echo "<td>" . $_SESSION['chart'][$indexo]['type']."</td>";
echo "<td>" . $_SESSION['chart'][$indexo]['idanimal']."</td>";
echo "<td>" . "Rp. " . $_SESSION['chart'][$indexo]['harga']. ",-" ."</td>";
echo "<td>" . "<a href='deletesession.php?session=$indexo'>" ."Proses ". "</a>"."</td>";
$totalharga += $_SESSION['chart'][$indexo]['harga'];
echo "</tr>";
}
echo "</table>" . "<br/>";
echo "<blockquote>" . "Total Pembelian Item Yang Anda Pesan =". "<h2>". "Rp." . $totalharga . ",-" ."</h2>" . "</blockquote>";
}else
{
echo "Chart is still Empty";
}
}
I've already tried this :
Suppose that there is a chart already filled by the contents then I tried to delete within this code, I've received error with the unset variable
unset($_SESSION['chart'][1])
Thank you
I spot several things that could be improved in your code:
Don't echo in your functions, return instead (then echo what the function returns). This gives you more flexibility regarding what you do with your result.
PHP has a built-in loop for iterating arrays, the foreach loop. You should be using that instead of for.
So here's what I have:
function print_session_data($session) {
if (!is_array($session)) {
return "Array is empty";
}
$table_data = "";
$total_harga = 0;
foreach ($session as $index => $data) {
$table_data .= <<<TABLE_DATA
<tr>
<td>$index</td>
<td>{$data["type"]}</td>
<td>{$data["idanimal"]}</td>
<td>Rp. {$data["harga"]}</td>
<td>Proses</td>
</tr>
TABLE_DATA;
$total_harga += $data["harga"];
}
$result = <<<RESULT
<h3>Berikut abalah keranjang belanja anda</h3>
<table border="1">
<thead>
<tr>
<th>No</th>
<th>Animal Type</th>
<th>ID Binatang</th>
<th>Harga</th>
<th>Hapus Data</th>
</tr>
</thead>
<tbody>
$table_data
</tbody>
</table>
<blockquote>Total Pembelian Item Yang Anda Pesan = <strong>Rp. $total_harga</strong></blockquote>
RESULT;
return $result;
}
$_SESSION['chart'] = array();
$_SESSION['chart'][0]['type'] = "Type";
$_SESSION['chart'][0]['idanimal'] = 6;
$_SESSION['chart'][0]['price'] = '$25';
$_SESSION['chart'][0]['harga'] = 25;
echo print_session_data($_SESSION["chart"]); // <== this is the function to print out the data
Suppose that there is a chart already filled by the contents then I
tried to delete within this code, I've received error with the unset
variable unset($_SESSION['chart'][1])
From what I can see from your code the best way to unset the data correctly is as follow:
DEMO.
You have to check if the $_SESSION['chart'][0] was set before using the session variable index again. If it $_SESSION['chart'] array still contains other indexes then you can call printdata(); else indicate that the session was empty.
I created classes Rankings and DateFilter.
Each rankings class has a DateFilter class that should produce the cutoff date. I am trying to be able to create a filter so that everything created after that date will be displayed in a table.
However, the comparison does not work. Can you see a problem?
Here is my DateFilter class:
<?php
include ("Filter.php");
class DateFilter extends Filter
{
//#param daysOld: how many days can be passed to be included in filter
//Ex. If daysOld = 7, everything that is less than a week old is included
private $interval;
public function DateFilter($daysOld)
{
$this->interval = new DateInterval('P'.$daysOld.'D');
}
//#Return: Returns a DateTime that is the earliest possible date to be included in the filter
function createLimitDate()
{
$now = new DateTime();
return $now->sub($this->interval);
}
//generates SQL code for checking date
//Ex. WHERE limitDate > created... if > means before
function genSQL()
{
$limitDate = $this->createLimitDate();
return $limitDate->format('Y-m-d') . " < 'created'";
}
}
?>
And my Rankings Class:
<?php
class Rankings
{
private $filter;
//#params: $filty is the filter given to these rankings
public function Rankings($filty)
{
$this->filter = $filty;
}
//#return: returns the html code for the rankings
public function display()
{
echo '<table border="1" align="center">'.
'<tr align="center" style="font-weight:bold;">
<b><td>#</td><td>NAME</td><td>Date</td></b>
</tr>
';
//hardcoding DB
$where = $this->filter->genSQL();
$qry = mysql_query("SELECT * FROM `pix`
WHERE $where
");
if (!$qry)
die("FAIL: " . mysql_error());
$i = 1;
while($row = mysql_fetch_array($qry))
{
$name = $row['uniquename'];
$created = $row['created'];
echo ' <tr>
<td>'. $i . '</td>'.
'<td>' . $name . '</td>'.
'<td>'. $created . '</td>'.
'</tr>';
$i += 1;
}
echo '</table>';
echo $where;
}
}
?>
I'm calling it like this:
$test = new DateFilter(100);
$rankings = new Rankings($test);
$rankings->display();
In that example, nothing is displayed, even though I'm sure everything in my datebase was uploaded less than 100 days ago.
Throw in some quotes around the date you're passing to MySQL, and drop the quotes around your column name:
return "'" . $limitDate->format('Y-m-d') . "' < created";