0

I'd like some help understanding how to call the results of a function on separate pages within my simple web app. I'm quite new to php/pdo.

Most of the time I just want to create a simple SELECT function and display the data on another page.

I have a page containing all of my functions named class.crud.php, the contents are as follows (minified for display purposes);

class.crud.php

class crud {

    private $db;

    function __construct($DB_con) {
        $this->db = $DB_con;
    }

    public function testing() {
        $stmt = $this->db->prepare("SELECT * FROM users WHERE user_id=:userId");
        $stmt->bindparam(":userId", $_SESSION['user_session']);
        $stmt->execute();
        $results = $stmt->fetch(PDO::FETCH_ASSOC);
        //var_dump($results); this dumps the results successfully on the desired page
        if ($stmt->rowCount() > 0) {
            while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
                print($row['user_id']);
                print($row['user_name']);
                echo $row['user_id'];
                echo $row['user_name'];
            }
        } else {
            echo 'nothing here';
        }
        return true;
    }

}

How do I display the results of this testing() function on any other page? I have tried the following but it doesn't work (no data displayed at all, although if I uncomment the var_dump($results) I can see an array of data displayed);

user-details.php

<div>
  <p>User Details</p>
  <?php $crud->testing();?>
</div>

A few questions;

  • If I echo or print variables within my functions - how do I access this data on another page?
  • Should I return true or return anything at all?
  • Should I format the data within my functions - i.e tabularise it. Or leave this to the page where I want it displayed?

My database connection is fine and I have many functions that work. However they are very simple functions that I have been using for testing.

Any help is appreciated in understanding the logic. I have read so many tutorials :/

3
  • You should save the data to an array and return it within your function: While($row = $stmt->fetch...) $results[] = $row; } return $results; You can then iterate over this in your template file and choose how to display it. Functions should almost never print or echo anything directly, as you've found, because it makes the data inaccessible. Moreover, a template should always control how data is displayed on page. edit - I see you are already using the var $results for another purpose, so choose a different name for the actual results you will return from your function. Commented Mar 8, 2016 at 16:22
  • Glad that helped, please see my answer for a little more depth. Commented Mar 8, 2016 at 16:46
  • phpdelusions.net/pdo#fetchall Commented Mar 8, 2016 at 17:22

2 Answers 2

2

The reason behind this is that you can fetch results only once, unless you build your PDOStatement object with scrollable cursor.

When all rows have been returned (in your case I go with your result set is made of only one row, because you have user_id as key and unique field), the function fetch returns false. So in your while loop, fetch gives false.

Or you use the $result array, as proposed by carbide, or you need to call again the execute function before the second call to fetch, or you use scrollable cursors to go back and forth. You have an example of usage in the PHP doc for PDOStatement::fetch.

And if you want to get all results in an array, you can also use the function PDOStatement::fetchAll.

$results = $stmt->fetchAll(PDO::FETCH_ASSOC);

So it makes your whole function like this:

public function testing() {
    $stmt = $this->db->prepare("SELECT * FROM users WHERE user_id=:userId");
    $stmt->bindparam(":userId", $_SESSION['user_session']);
    $stmt->execute();
    return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
Sign up to request clarification or add additional context in comments.

1 Comment

I added an example for the OP, because it helps when a function is shown in the exact context.
2

The best way to accomplish this is to save the data to an array and return it within your function:

$returnResults = array();
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
    $returnResults[] = $row;
}
return $returnResults;

Within your template file, you can then call your function, and iterate over the results:

<?php 
$testing = $crud->testing();
foreach($testing as $row) {
    // Echo your data here, in whatever way it best fits your template goals
    echo $row['user_id'];
    echo $row['user_name'];
}
?>

Functions should almost never print or echo anything directly, as you've found, because it makes the data inaccessible. Moreover, a template should always control how data is displayed on page. This is called separation of concern:

In MVC structure, the model (your crud class) should communicate with your database to create, read, update, or delete data. It should have no concerns about how or when that data will be displayed.

Your view (in this case your template file), on the other hand, should not concern itself with talking to the database. It should ask your model for data, and only worry about displaying it accordingly.

If you want to get into MVC structure even more, technically it is your controller layer that should pass the data back and forth between the model and view. This would mean removing the $crud->testing() call from your template, and calling it in an intermediary file that first gets the data from the model, then renders the view passing it the data it needs to render. This is probably more complex than your code has to be at this point, but it's worth understanding if you want to get further into best MVC practices and separation of concerns.

1 Comment

@johnny_s there is a typo in the code above. But I am sure you can fix it yourself, if you would not only copy and paste it in your script but also try to comprehend what does it do.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.