Search code examples
phpmysqllistmodel-view-controllercount

How do I organize this list into MVC?


I want to make a list of best selling prints in my store. I have a table (print_for_sale) which has fk_sale_id and fk_print_id where I can see how many prints have been bought.

I came up with this code to print out an organized list, from most bought to least (not sure it is entirely correct):

<?php
    $sql = "SELECT fk_print_id as printId, COUNT(print_for_sale_id) as saleCount
                    FROM print_for_sale
                    GROUP BY fk_print_id
                    ORDER BY saleCount DESC";

    $result = mysql_query($sql);

    while ($row = mysql_fetch_assoc($result)) {
           echo $row['printId'];  echo $row['saleCount']; }
?>

I'm trying to make a transition of this to my model, controller and view (MVC), but I'm having a lot of trouble. I'm new to this and I've tried in so many different ways, none of which seem to work. I'm lost. Right now I have it like this (and it prints out nothing) or the only thing it prints out is "Notice undefined variable arr" when I make an echo in my view.

model.php

function getBestSelling() {

    $sql = "SELECT fk_print_id as printId, COUNT(print_for_sale_id) as saleCount
            FROM print_for_sale
            GROUP BY fk_print_id
            ORDER BY saleCount DESC";
    $result = $this->conn->query($sql);
    return $this->buildArr($result);
}

controller.php

function bestselling() {
    $arr = $this->model->getBestSelling();
    print_r($arr);
    include 'view.php';
}

view.php

<?php echo $arr['printId'] ?>

I want to print out the result of the query, but nothing is working. I'm sorry if this isn't an appropriate question, but I could really use some help understanding this.

I'm not using any framework.

In my model I do have a class model { }, a function __construct() and a function __destruct(). I also have a function to build the arrays.

function buildArr($result) {
    $arr = array();
    while ($row = $result->fetch_assoc()) {
        array_push($arr, $row);
    }
    return $arr;
}

In my controller, I include 'model.php'; and have a class Controller {} and function __construct() { $this->model = new model();}.

I also have a index.php where I start the session and define("BASE_URL", 'http://' . $_SERVER['SERVER_NAME'] . '/printstore/index.php/');

The app is working. I can already register users, login and make purchases. I just can't seem to get this part of the code right.


Solution

  • The included file is not behaving as you expect it to. To pull this off you will have to create a global out of the variable (but don't do it!). You can print_r() the array in the controller, because you're fetching it from the model. But after that you include the view. When you place that array in an included file, without defining it in the file itself, you're not going to get a result because only the including file has access to any defined variables. Not the other way around.

    So if you want this to work you're going to either have to make the variable $arr global (not recommended), or include the controller in view.php. (Note that this is not MVC!) If you want this to be MVC you'll have to use classes for the controllers and use those objects in the view. To find a better explanation for this please refer to the links down below.

    I am personally fond of using of a templating engines (also not MVC related). I'm quite fond of Smarty, but I've heard good stories about mustache too.

    These templating engines provide you with a way to pass variables to your templates, without including the controller file. For example in Smarty:
    PHP:

    $variable = 'Hello World!';
    $smarty->assign('variable', $variable);
    $smarty->display('helloworld.tpl');
    

    Smarty, helloworld.tpl:

    {$variable}
    

    Output: Hello World!

    I'd also recommend you to read these, they might help you out more than I've been able to explain.

    1. Setting up MVC in PHP: http://www.sitepoint.com/the-mvc-pattern-and-php-1/
    2. Including files in PHP: Passing a variable from one php include file to another: global vs. not

    Edit
    Teresko is right that you should not be using globals. I just specified them here, because it's possible to use them (definitely not recommended). Read this question for a couple of why's: Stop using `global` in PHP