0

I have a class that contains methods used globally, and am using them by extending the class:

App.php

final class App extends Core {

  // The app class handles routing and basically runs the show

}

Core.php

abstract class Core {

  public function __construct() { // Here we bring in other classes we use throughout the app
    $this->Db = new Db($this);
    $this->Mail = new Mail($this);
  }

  // Then we define multiple methods used throughout the app

  public function settings($type) {
    // You see this used by the model below
  }

}

index.php

$App = new App(); // This fires up the app and allows us to use everything in Core.php

Up until now, this is all great, because everything is handled throughout the site from within $App. However, within my MVC structure, the models need to pull data from the database, as well as retrieve other settings all contained in Core. We do not need the entire $App class to be used by the models, but we need Core to be.

MyModel.php

class MyModel extends Core { 

  public function welcome() {
    return 'Welcome to '.$this->settings('site_name');
  }

}

Once MyModel.php comes into play, the Core constructor is run a second time. How do I keep the Core constructor from being run twice?

MultiDev
  • 10,389
  • 24
  • 81
  • 148
  • This post might help: http://stackoverflow.com/questions/23160509/check-whether-instance-of-a-class-exists-if-not-create-an-instance – Fueled By Coffee Dec 22 '16 at 14:14
  • Your App class should not access the db.. only the models should do that.. – Mihai Matei Dec 22 '16 at 14:17
  • Also, take a look and read about Dependency Injection: http://stackoverflow.com/questions/130794/what-is-dependency-injection – Mihai Matei Dec 22 '16 at 14:18
  • As an App class, which can't has more the one instance, you could use Singleton pattern (it's just a tip, be careful with Singleton pattern, "great power comes great responsibility"). An App class shouldn't have access to the storage. There's a lot of patterns that can be used, a Register pattern, a Service Provider (which is a Register) or a Connection Manager could manage your services instances. Dependency Injection (as linked before) is the best way to share dependency without create without control. – Gabriel Heming Dec 22 '16 at 15:32

1 Answers1

1

you can use a static instance in the core class and reuse it.

abstract class Core {
  public static $instance; //create a static instance

  public function __construct() { // Here we bring in other classes we use throughout the app
    $this->Db = new Db($this);
    $this->Mail = new Mail($this);
    self::$instance = $this; // initialise the instance on load
  }

  // Then we define multiple methods used throughout the app

  public function settings($type) {
    // You see this used by the model below
  }

}

in the model class, use it like this

class MyModel extends Core { 

  public function welcome() {
    $_core = Core::instance; // get the present working instance
    return 'Welcome to '.$_core->settings('site_name');
  }

}

you can take a look at this singleton reference
additionally you can check this answer explain-ci-get-instance

Community
  • 1
  • 1
  • Your code has a few problems. First, it isn't a singleton because we can instantiate as many class as we want. Second, the use of a construct to create and storage his own instance is a bad pratice, because it's not its purpose. Third, you need test if it has a instance or if need be instantiated. And finally, CI has a really bad program design, as you linked a really bad coded class. – Gabriel Heming Dec 22 '16 at 15:26