Return number of rows php mvs - php

I am trying to return the number of results found on my page above an html table. I am using an mvc framework for the first time so it's very new to me how the process works.
My query works and displays the tabular results successfully, my issue is [probably] with the positioning of my return code?
I have included my code for reference;
Model
public function categoryView()
{
$sth = $this->db->prepare("SELECT
b.id,
b.title,
b.category,
FROM book
WHERE status != 'Archive' AND category = :cat ORDER BY id DESC LIMIT 15");
$sth->bindValue(':cat', $_GET['category']);
$sth->execute();
$result = $sth->fetchAll(PDO::FETCH_ASSOC); // won't run when included
return count($result); // won't run when included
$all_books = array();
foreach ($sth->fetchAll() as $book) {
$all_books[$book->id] = new stdClass();
$all_books[$book->id]->id = $book->id;
$all_books[$book->id]->title = $book->title;
$all_books[$book->id]->category = $book->cat_name;
}
return $all_books;
}
View
Found <?php echo count($result); ?> records
<table>
<?php
foreach ($this->books as $book) {
echo "<tr>";
echo '<td>'.$book->id.'</td>';
echo '<td>'.$book->title.'</td>';
echo '<td>'.$book->category.'</td>';
echo "</tr>";
}
?>
</table>
Controller
function categoryView()
{
$categoryView_model = $this->loadModel('Books');
$this->view->books = $categoryView_model->categoryView();
$this->view->render('books/categoryView');
}
I receive the error errors on my view page
Warning: `Invalid argument supplied for foreach() ... on line 51`
and
Found
Notice: Undefined variable: result in ... on line 47
0 records
Line 47 contains Found <?php echo count($result); ?> records
Line 51 contains foreach ($this->books as $book) { ... }
Any advice or help is appreciated.

Remove these two lines
$result = $sth->fetchAll(PDO::FETCH_ASSOC); // won't run when included
return count($result); // won't run when included
In your view change
Found <?php echo count($result); ?> records
to
Found <?php echo count($this->books); ?> records
The reason you have to do this is because you're storing the results returned from categoryView() into the books property of the view when you run the following line
$this->view->books = $categoryView_model->categoryView();
Note that the count will always be a maximum of 15. If you want to display the total # of found results you should issue a separate select count(*) without a limit clause.

It would help us a lot if you specified the framework. Honestly I have only worked in Zend as a php framework but over there you have to assign the property to your view:
$this->view->property = $all_books; //or any other property
and to retrieve it in the view
<?php echo $this->property; ?>
I find it hard to beleive that your MVC calls the function (action),which in zend needs to be named in a specific way, from the view and so uses a return. I an tell you one thing, your way of sending the variable to the view is wrong, the return must not be the correct way of sending it. Without your framework this is the only way I can help you in addition I would tell you to actually echo an isset f both variables and you will see my theory is right you are not sending the variables from the controller, action or function correctly

Related

PHP function Array Returning One records many times

I have My code Below. I have a function "getdet" that return array of record,but i cant able to print the all records the codes displaying only the first records may time. Pls help to solve this issue.
<?php
function getdet($qry){
global $con;
$Selecting=mysqli_query($con,$qry);
$Fetch=mysqli_fetch_array($Selecting);
return $Fetch;
}
$qry="SELECT * FROM `tbs_employee` WHERE EmpId='1' limit 1";
$GetData=getdet($qry);
$i=0;
while($GetData){
echo $i."-".$GetData['EmpId'].":".$GetData['EmpName']."<br>";
$i++;
}
?>
Below is my Table
Here is my result
0-1:Fst Employee
1-1:Fst Employee
2-1:Fst Employee
3-1:Fst Employee
4-1:Fst Employee
5-1:Fst Employee
6-1:Fst Employee
.
.
.
infinity
You are running the same query ($Selecting=mysqli_query($con,$qry);) over and over again inside your getDet-Function, so it will never quit the while-loop:
while($GetData){
Should be:
$qry="SELECT * FROM `tbs_employee` WHERE EmpId='1' limit 1";
$Selecting=mysqli_query($con,$qry);
$i=0;
while($GetData = mysqli_fetch_array($Selecting)){
echo $i."-".$GetData['EmpId'].":".$GetData['EmpName']."<br>";
$i++;
}
mysqli_fetch_array will return null, if all results are returned, then the while-loop can exit.
Well, your function only return a data. Here's the right way:
<?php
function getdet($qry){
global $con;
$Selecting=mysqli_query($con,$qry);
while($row=mysqli_fetch_array($Selecting, MYSQLI_ASSOC)){
$Fetch[] = $row;
}
return $Fetch;
}
$qry="SELECT * FROM `tbs_employee`";
$GetData=getdet($qry);
foreach($GetData as $i=>$row){
echo $i."-".$row['EmpId'].":".$row['EmpName']."<br/>";
}
?>
In your query you filtered employers by the ID
WHERE EmpId='1' limit 1
If you wants to get all records, delete this statement.
The reason this happens, is because you have created an endless loop. The way you use it, is the same as 'true', small example:
$example = 'some value';
if ($example) {
echo 'You will see this echo!';
}
If we now take it one step further; you have a while loop. But the way you use it now, is as above. In other words it's always true:
$example = 'some value';
while ($example) {
echo 'You will see this echo! At least untill the server runs out of resources';
}
What you have, is that you set $GetData before the loop. This way, after the loop has run one itteration, the value does not change. You only set it's value before the while, so you never move to the next line!
Luckily, the solution is very simple. We need to assign it every itteration. The following snippet is a common way to do it:
while($GetData = getdet($qry)){
// Now, after every run, we set $GetData to the next line
}
The last run, the mysqli_fetch_array function returns null, so your function does too, so the while loop stops.
Offtopic: We have a few coding standards which make reading code easier. One of them is indentation; as you can see, my code reads easier. This is because I use 4 spaces (1 tab) in an if-statement for example. I strongly recommend you do this too (possible start with editting your topic here).

PHP while loop to fetch post data from database

I am creating my own blog from scratch with a homepage that loads the latest posts in order of time published. I call the posts using a front controller and store the data on a MySQL database. The website itself is great and the posts all load perfectly with no issue. The issue is getting the homepage to work.
I created a few PHP functions for the homepage. They generally order the posts (database rows) by ID in descending order, since it's an autoincrement field, and call their data. And then to show the latest post as a sort of 'featured post' right at the top, by fetching the data from the very top row in the database, which is the latest post.
And that works fine - when I echo the result it shows the latest post just as I want it.
Below that I want two boxes, side by side, for the two posts before the first one. So I made this function to call them:
function fetch_rest_posts_1($conn) {
$stuff = $conn->query("SELECT * FROM table WHERE is_post = 1 ORDER BY id DESC LIMIT 1,2");
while ($row = $stuff->fetch_array()) {
$i=1;
return '<div id="post_'.$i.'" style="width:308px;height:215px;padding:5px">
<h2>'.$row['title'].'</h2>
<p>'.date('d/m/Y',strtotime($row['published_date'])).' by '.$row['author'].' | </p>
<p>'.$row['meta_description'].'</p>
</div>';
$i++;
} // style="white-space:nowrap;width:100%;overflow:hidden;text-overflow:ellipsis"
}
And it actually does work great when I echo the result, shows everything I want, but it only shows one div, not two. When I take the SQL query and directly enter it into phpMyAdmin, it gives me two rows. Have I done something wrong?
(I put the auto-increasing $i in there so that I could isolate each box and alter the style later.)
Your problem is caused by the return statement in the loop. You should add $return = '' at the top of your function, replace return by $result .=, and return $result at the end of your function.
In addition, the loop counter $i is reset in every iteration. Move the initial assignment out of the loop.
EDIT: The .= is intentional to append to $result instead of replacing it with another value constructed from the next dataset.
initiate $i outside the loop and use echo() instead of return()
return() breaks the loop
or use
$result .= '<div id="post_'.$i.'" style="width:308px;height:215px;padding:5px">
<h2>'.$row['title'].'</h2>
<p>'.date('d/m/Y',strtotime($row['published_date'])).' by '.$row['author'].' | </p>
<p>'.$row['meta_description'].'</p>
</div>';
and return $result; after the loop
That's because return will stop execution of the function try this approach:
function fetch_rest_posts_1($conn) {
$stuff = $conn->query("SELECT * FROM table WHERE is_post = 1 ORDER BY id DESC LIMIT 1,2");
$post = array();
while ($row = $stuff->fetch_array()) {
$post[] = $row;
}
return $post;
}
So the function purpose is to just get the data, so you can later print it:
$row = fetch_rest_posts_1($conn);
for($i = 0; count(row); $i++){
echo '<div id="post_'.$i.'" style="width:308px;height:215px;padding:5px">
<h2>'.$row[$i]['title'].'</h2>
<p>'.date('d/m/Y',strtotime($row['published_date'])).' by '.$row[$i]['author'].' | </p>
<p>'.$row[$i]['meta_description'].'</p>
</div>';
}

Returning multiple database rows from php object class

I am trying to follow help found in this question: how can i return multiple database record from a class in OOP programming but I cannot seem to get it working properly.
I have a database table called 'jobs' and I want to retrieve all the data from that table display it to my users.
As of right now, when I use this code:
/* Get All Jobs */
public function getJobs($page) {
$db = new DBConnection;
$str = new str_format;
$validate = new data_validation;
$sql = "SELECT * FROM jobs ORDER BY job_id DESC";
$paginate = new Paginate($db, $sql, $page);
$result = $paginate->get_results();
$jobArr = array();
while($row = $result->fetch_array(MYSQLI_ASSOC)) {
$row = $validate->escapeArray($row);
$job = new Job($db);
$job->$row['job_id'];
$job->$row['job_title'];
$job->$row['date'];
$job->$row['industry'];
$job->$row['company'];
$job->$row['photo'];
$job->$row['content'];
$jobArr[] = $job;
return $jobArr ;
}//close while loop
/*=== build the pagination links ===*/
echo "<div class='pagination_container'>";
echo "<span class='pagination'>";
echo $paginate->show_pages();
echo "</span>";
echo "</div>";
/*=== end build pagination links ===*/
}
I only get 1 entry and a bunch of errors that look like this Notice: Undefined property: Job::$4 in /home/hirestar/public_html/builder/classes/job.class.php on line 54
The class is named Job if that has anything to do with it. But I cannot seem to get this work properly.
How can I return all the jobs in my database from this function?
First off, you are calling return within your while loop, so it will bail out on the first loop execution. This is why you are only getting one result. You should call return after the while loop so that you can build your entire array.
Second, you are likely getting the Undefined property errors because of this code:
$job->$row['job_id'];
$job->$row['job_title'];
$job->$row['date'];
$job->$row['industry'];
$job->$row['company'];
$job->$row['photo'];
$job->$row['content'];
Here you are probably wanting to do something like:
$job->job_id = $row['job_id'];
Right now what you are trying to do is read the property from $job with a name equal to the value of $row[*]. So say the row_id is 4, you are in essence performing:
$job->4;
which is obviously meaningless.

php query does not retrieve any data?

well, i wanna pull out some data from a mysql view, but the wuery dos not seem to retrieve anything ( even though the view has data in it).
here is the code i've been "playing" with ( i'm using adodb for php)
$get_teachers=$db->Execute("select * from lecturer ");
//$array=array();
//fill array with teacher for each lesson
for($j=0;$j<$get_teachers->fetchrow();++$j){
/*$row2 = $get_lessons->fetchrow();
$row3=$row2[0];
$teach=array(array());
//array_push($teach, $row3);
$teach[$j]=mysql_fetch_array( $get_teachers, TYPE );
//echo $row3;*/
$row = $get_teachers->fetchrow();
//$name=$row[0]+" "+$row[0]+"/n";
//array_push($teach, $row1);
echo $row[0]; echo " ";echo $row[1]." ";
//$db->debug = true;
}
if i try something like "select name,surname from users", the query partially works . By partially i mean , while there are 2 users in the database, the loop only prints the last user.
the original query i wanted to execute was this
$get_teachers=$db->Execute("select surname,name from users,assigned_to,lessons
where users.UID=assigned_to.UID and lessons.LID=assigned_to.LID and
lessons.term='".$_GET['term']."'");
but because it didnt seem to do anything i tried with a view ( when you execute this in the phpmyadmin it works fine(by replacing the GET part with a number from 1 to 7 )
the tables in case you wonder are: users,assigned_to and lessons. ( assigned_to is a table connecting each user to a lesson he teaches by containing UID=userid and LID=lessonid ). What i wanted to do here is get the name+surname of the users who teach a lesson. Imagine a list tha displays each lesson+who teaches it based on the term that lesson is available.
Looking at http://adodb.sourceforge.net/ I can see an example on the first page on how to use the library:
$rs = $DB->Execute("select * from table where key=123");
while ($array = $rs->FetchRow()) {
print_r($array);
}
So, you should use:
while ($row = $get_teachers->fetchrow()) {
instead of:
for ($j = 0; $j < $get_teachers->fetchrow(); ++$j) {
The idea with FetchRow() is that it returns the next row in the sequence. It does not return the number of the last row, so you shouldn't use it as a condition in a for loop. You should call it every time you need the next row in the sequence, and, when there are no more rows, it will return false.
Also, take a look at the documentation for FetchRow().
for($j=0;$j<$get_teachers->fetchrow();++$j){
... a few lines later ...
$row = $get_teachers->fetchrow();
See how you call fetchrow() twice before actually printing anything? You remove two rows from the result set for every 1 you actually use.
while ($row = $get_teachers->fetchrow()) {
instead and don't call fetchrow() again within the loop.
Because you're fetching twice first in the loop
for($j=0;$j<$get_teachers->fetchrow();++$j){
... some code ...
// And here you fetch again
$row = $get_teachers->fetchrow();
You should use it like this
while ($row = $get_teachers->fetchrow()) {

When listing information from a database using php and mysql how would you make the first row look different to the rest?

Basically I have articles in my database and I want to alter the way the first record displays. I want the lastest (Posted) article to be the focus and the older article just to list, (see F1.com). I need to know how to get the first of my values in the array and get it to display differently but I am not sure how to do this, I can do it so all rows display the same just not how to alter the first row. I also need to know how to tell the rest of the rows to display the same afterwards im guessing you use an if statement there and before that some kind of count for the rows.
Current code:
$result = mysql_query("SELECT * FROM dbArticle WHERE userID='".$_SESSION["**"]."' ORDER BY timestamp DESC");
while($row = mysql_fetch_array($result))
{
echo "<h2 class=\"heading1\">". $row['title'] ."</h2>";
echo "By: ".$row['username']." Type: ".$row['type']." Posted: ".$row['timestamp']."
$body = $row['body'];
echo "<br/><p>";
echo substr("$body",0,260);
echo "...<span class=\"tool\"><a class=\"blue\" href=\"index.php?pageContent=readArticle&id=".$row['id']."\">Read More</a></span></p><hr/>";
}
mysql_close($con);
Ok I have taken Luke Dennis's code and tried to test it, but I am getting this error: Warning: Invalid argument supplied for foreach() this is the line of the foreach statment. Something that has just come to mind is that I will only want 5 or so of the older articles to display. This is what I have thats creating the error:
<? $con = mysql_connect("localhost","****","***");
if (!$con)
{
die('Could not connect: ' . mysql_error());
}
mysql_select_db("******", $con);
$result = mysql_query("SELECT * FROM dbArticle ORDER BY timestamp DESC");
$first = true;
foreach($result as $row){
if($first)
{
echo"".$row['title']."";
echo"this is the headline";
$first = false;
}
else
{
echo"".$row['title']."";
}
}
?>
Do I need to add mysql_fetch_array somewhere to set the array up?
I would just iterate through the results and apply a css class to the first entry:
$first = true;
while ($row = mysql_fetch_assoc($result)) {
$cssClass = '';
if ($first) {
$cssClass = 'highlight';
}
echo '<p class="' . $cssClass . '">' . $row['text'] . '</p>';
$first = false;
}
It's a bit crude, but I often hard-code a variable to designate the first run through a loop. So something like:
$first = true;
foreach($list_of_items as $item)
{
if($first)
{
// Do some stuff
$first = false;
}
else
{
// Do some other stuff
}
}
A simple if statement when looping through your results will usually do the trick. You can use a boolean to indicate if you've output the first row of results or now. If you haven't then give it a particular style and then set the boolean to true. Then all subsequent rows get a different style.
All of the above are correct. Luke Dennis' post is of course fleshed-out a bit more.
As Brian Fisher said, add some CSS styling to the first link when you encounter it per Luke's post.
I took a look at the article list on the F1 website. Pretty well constructed site - "One would expect that." :-)
Anyway, the article listings are contained within a two row table (summary="Latest Headlines") in descending order (newest first).
Just place a class in the second column (<td class="first-news-article">). Then add the class name and appropriate styling values in the css file - probably your' modules.css. There's already quite a few class values associated with articles in that file, so you may be able to just use an existing value.
That should be about it - other than actually doing it!
By the way, judging by the quality of the underlying html, I'm assuming there's already an "article list emitter." Just find that emitter and place the appropriate conditional to test for the first record.
Darrell
I just noted your code addition. I assume that you were showing the F1 site as an example. Anyway, I think you're on your way.
I presume you have some code that loops through your resultset and prints them into the page? Could you paste this code in, and that might give us a starting point to help you.
I don't know PHP, so I'll pseudocode it in Perl. I wouldn't do it like this:
my $row_num = 0;
for my $row ($query->next) {
$row_num++;
if( $row_num == 1 ) {
...format the first row...
}
else {
...format everything else...
}
}
The if statement inside the loop unnecessarily clutters the loop logic. It's not a performance issue, it's a code readability and maintainability issue. That sort of thing just BEGS for a bug. Take advantage of the fact that it's the first thing in the array. It's two different things, do them in two different pieces of code.
my $first = $query->next;
...format $first...
for my $row ($query->next) {
...format the row...
}
Of course, you must make the first row stand out by using tags.
I'd use array_shift():
$result = mysql_fetch_assoc($resultFromSql); // <- edit
$first = array_shift($result);
echo '<h1>'.$first['title'].'</h1>';
foreach ($result as $row) {
echo '<h2>'.$row['title'].'</h2>';
}
The best way to do this is to put a fetch statement prior to the while loop.
Putting a test inside the while loop that is only true for one iteration can be a waste of time for a result of millions of rows.

Categories