-6

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. Would appreciate some help! Sorry for the long post and thank you in advance.

Owly
  • 575
  • 2
  • 6
  • 16
  • 11
    Let's lay off the insults, people. I've cleaned up these comments because they weren't going anywhere productive. Focus on the technical issues at hand. – Brad Larson Feb 25 '15 at 17:13

1 Answers1

1

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

Community
  • 1
  • 1
Bono
  • 4,757
  • 6
  • 48
  • 77
  • It wasn't me. I don't know who is downvoting the answers... I upvoted. Thank you for your time. I will try! – Owly Feb 25 '15 at 16:02
  • I get this error when I include the controller in the view: Fatal error: Cannot redeclare class model in /Applications/XAMPP/xamppfiles/htdocs/printstore2/model.php on line 3 – Owly Feb 25 '15 at 16:06
  • 1
    Have a look here: http://www.sitepoint.com/the-mvc-pattern-and-php-1/ I think it'd do you some good to read up there. It tells you how to set up the basics of an MVC (without using any template engines). Also unsure what your current code is (is controller a class?). – Bono Feb 25 '15 at 16:09
  • 1
    This might also help you out more: http://stackoverflow.com/questions/4675932/passing-a-variable-from-one-php-include-file-to-another-global-vs-not – Bono Feb 25 '15 at 16:11
  • Thank you! I will check that out :) Yes. I have a document called controller.php and it is a class as well. `class Controller { ... }` with all the functions in it. – Owly Feb 25 '15 at 16:11
  • 8
    **downvoted because**: recommendation to use global variables, implying that "template" and "view" is the same thing, recommendation to use Smarty. Basically, what you are telling OP to use is actively harmful. – tereško Feb 25 '15 at 16:14
  • 1
    @tereško actually, I did not recommend to use globals. I said he could do it with globals (that is was possible to do it like that). I suggested to use a templating engine. If you have any links to Smarty being "harmful" I'd be glad to read about it! :) Also not implying that view and template is the same btw. You're right I should have specified to not use globals though. Will edit it. – Bono Feb 25 '15 at 16:16