-2

How to organize MVC architecture in PHP? I tried to do this, and it works, but in my code model connects to database each time it is loaded. Is that possible to use previous connection?

Here are my files (not making any queries in model, for example purposes):

index.php

include 'controller/home.php';

$home = new HomeController();
$home->index();

controller/home.php

class HomeController {
  public function index () {
    require('model/home.php');
    require('model/another.php');

    $home = new HomeModel();
    echo $home->foo();
    echo $home->bar();

    $another = new AnotherModel();
    echo $another->baz();
  }
}

model/home.php

class HomeModel extends mysqli {
  public function __construct() {
      parent::__construct('localhost', 'root', '', 'mydb');

      if (mysqli_connect_error()) {
          die('Connect Error (' . mysqli_connect_errno() . ') '
                  . mysqli_connect_error());
      }
  }

  public function foo () {
    return true;
  }

  public function bar () {
    return false;
  }
}

model/another.php

class AnotherModel extends mysqli {
  public function __construct() {
      parent::__construct('localhost', 'root', '', 'mydb');

      if (mysqli_connect_error()) {
          die('Connect Error (' . mysqli_connect_errno() . ') '
                  . mysqli_connect_error());
      }
  }

  public function baz () {
    return true;
  }
}
tjomamokrenko
  • 149
  • 2
  • 10
  • 2
    Use LARAVEL, CAKEPHP, ZEND, KOHANA, CODEIGNITER ..... or any other MVC Framework that is out there! Don't try to reinvent the wheel. Belive me it is not a good idea and will kill your Project pretty fast. – ITroubs Nov 18 '14 at 14:42
  • 3
    It is a bad idea if you are building commercial software. But building your own MVC is an excellent way to understand how the architecture works underneath and why certain things are built and organized in certain ways... – Dawid O Nov 18 '14 at 14:47
  • 3
    As counter argument to @ITroubs: Real "MVC" doesn't really need much in terms of a "framework". MVC is a code organisation technique of separating code with certain responsibility into three different categories and keeping those separate; the glue between those categories can be pretty minimal and not require any framework, depending on what exactly you're after. Some of the mentioned frameworks also aren't stellar examples of proper MVC categorisation. – deceze Nov 18 '14 at 14:55
  • I know what MVC ist. There is NO stellar example for a good MVC. There are some MVC's that make your life easier with built in hardening of your code. Learning MVC by doing it on your own might work. But it is easier to learn it with a php framework. – ITroubs Nov 18 '14 at 14:58
  • @ITroubs they have a lot of features I don`t need. I need just to separate PHP, SQL and HTML&CSS – tjomamokrenko Nov 18 '14 at 14:59
  • 1
    My advice is to learn about [Composer](https://getcomposer.org/) and routing [search for Klein, Toro, zaphpa]. Then follow a bottom-up article like [this one from Symfony creator](http://fabien.potencier.org/article/50/create-your-own-framework-on-top-of-the-symfony2-components-part-1), and come up with your own recipe. – moonwave99 Nov 18 '14 at 15:03
  • 2
    @tjomamokrenko If you don't need them and the project will be something simple as a onepage website then you havemy blessing. For anything more it MIGHT be wiser to use at least a lightweight framework that automatically brings a nice autoload, input validation, input cleaning and so on. Just features that make your site securer AND that are well tested. – ITroubs Nov 18 '14 at 15:05
  • 1
    Some users are recommending you to start using a framework because you will learn to code better in all aspects of programming. It will train your mind to write code cleaner, organized, free of bugs, efficient, etc. And you will learn from a solid base how MVC models should be implemented the right way. – Heroselohim Nov 18 '14 at 15:07
  • @tjomamokrenko maybe reading [this](http://stackoverflow.com/a/16596704/727208) and [this](http://stackoverflow.com/a/10685095/727208) would help a bit (and [this](http://stackoverflow.com/a/16356866/727208) for general list of materials). What you currently have is kinda .. emm .. "a minor disaster" would be the polite way to describe it. – tereško Nov 20 '14 at 08:44
  • @Heroselohim unfortunately, people who usually advocate for the use of frameworks, have no idea what a good code even is. And none of php's "mvc frameworks" have anything to do with MVC architectural pattern .. they are just Rails clones. – tereško Nov 20 '14 at 08:48

1 Answers1

-3

There are few ways of doing it.

You can use singleton design pattern to have one instance of the class making the connection to the database and then reuse it.

http://en.wikipedia.org/wiki/Singleton_pattern

Here is an example of a wrapper around PDO class to make it a singleton: http://tonylandis.com/php/php5-pdo-singleton-class/

You can also make a persistent connection in PDO (which is a better way of doing it).

Many web applications will benefit from making persistent connections to database servers. Persistent connections are not closed at the end of the script, but are cached and re-used when another script requests a connection using the same credentials. The persistent connection cache allows you to avoid the overhead of establishing a new connection every time a script needs to talk to a database, resulting in a faster web application.

<?php
    $dbh = new PDO('mysql:host=localhost;dbname=test', $user, $pass, array(
         PDO::ATTR_PERSISTENT => true
         ));
?>

http://php.net/manual/en/pdo.connections.php

You can make a persistent connection with MySQLi if you have 5.3+: http://php.net/manual/en/mysqli.persistconns.php

Good Luck!

Edit

Since the answer got quite a lot criticism let me elaborate. Yes, using singleton design pattern isn't the most elegant way of doing things. The best way you could deal with your models is to create an instance of a your MySQLi (or PDO) in the Controller and pass it to each model.

class HomeModel {

    private $_db;

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

    public function foo () {
        return true;
    }

    public function bar () {
        return false;
    }
 }

and in your controller.

public function index () {
    require('model/home.php');
    require('model/another.php');

    $db = new mysqli('localhost', 'root', '', 'mydb');

    $home = new HomeModel($db);
    echo $home->foo();
    echo $home->bar();

    $another = new AnotherModel($db);
    echo $another->baz();
}

This way the code is much easier to test and is not state dependant.

Dawid O
  • 5,100
  • 7
  • 23
  • 33
  • @tjomamokrenko you can make a baseclass for your models where the database connection and so on is handled. if you want you can use the singleton pattern there, or in another separated database class. – Raphael Müller Nov 18 '14 at 15:14
  • singleton is an **ANTIPATTERN**. – tereško Nov 19 '14 at 20:11