I am trying to get the php class Base to load only once for a custom MVC framework. So that i can close the database connection in the destructor and be able to use it in inheritance but I can't seem to figure it out. I looked at a singleton design here but i cant figure out how to load the database. Is there a way to get this working or perhaps a better way to do this. Or am i going about this in a totally stupid way and should change it?
Base class
class Base {
protected $db;
//constructor
public function Base(){
echo some unique id to test it worked
$db = connection to database
}
//load modules as needed
public function load($m){
$this->$m = new $m;
}
}
module class
class module extends Base {
//some random function
public function listing(){
$this->db->query();
}
}
the index.php which initializes the Base class
$main = new Base;
$main->load( 'module' );
$main->module->listing();
Related
I am developing a eCommerce store for school project.
i have several classes like this that uses same database connection.
so i have to separate those.
1. how to use a single database connection file for all of my classes.I have sevaral classes same as this
2. I draw some use case and class diagram. if any one has experience in UML - (ecommerce ) can you verify those?
class abc {
public $id;
public $name;
public $email;
public $db;
function __construct()
{$this->db=new mysqli('localhost','root','','cart');}
public function newsletter_subcribe()
{$sql="insert into table (id,name,email) value('$this->id','$this->name','$this->email')";
$this->db->query($sql);}
this class is do some query to your database for CRUD, the best thing you can do is make one more controller to access to this class, also make sure every function to do that is in private, not public.
so basicly the controller will post data to class to do CRUD.
more like Model in CI.
CONTROLLER -->> YOUR CLASSS -->> DATABASE
CLASS A
{
private function dbconnection()
{
}
private function a($param)
{
dbconnection();
//CRUD HERE
}
}
CLASS B
main function()
{
//load class A here, and you can access all method
$result = a($param);
}
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?
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
I'm playing around with Slim PHP framework and stumbled upon a situation I cannot work out.
First, I'll explain the basic setup:
Using slim-skeleton, I have a dependencies.php file, where the DIC is set up. It's the default slim-skeleton's setup with two more things:
$container['db'] = function ($c) {
return new PDO('mysql:host=localhost;dbname=****', '********', '********');
};
$container['model.user'] = function ($c) {
$db = $c['db'];
return new Dash\Models\User($db);
};
So, as you can see, I have two new things registered in the DIC - A PDO object and a User object.
But passing a database object for each and every other model is a bit of a pain... I would like to be able to inject the PDO object to a parent class, called Model.
So the Model should look like this:
class Model
{
protected $db;
public function __construct($db)
{
$this->db = $db;
}
}
And the User model:
class User extends Model
{
public function getById($id)
{
$this->db->... // I have access to the database object (PDO) from the parent class.
}
}
The thing is that I cannot have a parent object, because the slim's container returns a new instance of User and does not instantiate the parent Model class.
Any ideas on how to achieve inheritance, using Slim's container in a clean and usable way?
Thanks in advance.
That's not how inheritance works. User is an instance of Model. So when you do new User($c['db']), it'll work fine.
Currently I am trying to understand how OOP applies to PHP and I am having trouble with calling my class when I am getting into inheritance.
I am using the following PHP code:
require_once("init.php");
$table = new Table();
$table->draw();
$customer1 = new Customer();
Since the table class is just a plain class (not inherited) it will load correctly.
The init.php has the following PHP code:
function __autoload($class_name) {
require_once('classes/'.$class_name . '.class.php');
}
Because the Customer class is inhereting the User class, the code for the Customer class is inside the User class, however the __autoload function is trying to call for the customer.class.php now.
My Customer class would look something like this:
class User
{
private $_username;
public function __construct($name)
{
$this->_username = $name;
}
public function getUsername()
{
return $this->_username;
}
}
class Customer extends User
{
public function __construct()
{
//some code here
}
}
Cany anyone explain me please how I should call an inherited class with PHP?
You should only have one class per file. Your autoload will handle everything for you as long as every class is in its own file, named the same way...
Put all your Customer class code inside Customer.class.php
Each class should be written in its own file, exactly because of this autoload. There's no reason why class Customer must be within the same file as class User, just put it in its own file and your autoloader will handle it correctly.
Otherwise, you'll have to adopt some other naming scheme and write a more intelligent autoloader which can find classes in files with different names. (Don't do that, not really.)
Intro
I'm developing an MVC framework, and I've run into a problem. It seems what I was trying to accomplish is known as the Singleton Design method -- initializing classes only once. Remember that I'm trying to put as less code in the controller "acontroller" as possible.
With that said, a final question remains: how can I add objects to an object that has already been instantialized?
It may help to have or at least see actual source instead of just example source, so I have pushed my source to my github. You can find that here: https://github.com/derekmaciel/uMVC
Code explanation
What's happening "under the hood" is first,
The Controller class loads a controller located in /application/controller, in this case "acontroller".
After, the acontroller class loads a model (called "amodel") using the Load class, using $this->load->model("amodel"), which was instantialized in the Controller __construct.
The final outcome of $this->load->model("amodel") is: $controller->amodel =& new Amodel(), where $controller is the Controller instance (not acontroller, because the controller loading the model will vary).
Step 4: Allow acontroller access to models that were loaded (amodel).
Code result
A copy of the current output of these scripts can be found here: http://pastebin.com/EJxuXaki
The first thing you'll notice is that I'm given a warning for using a deprecated assignment. I'm going to focus on the error for now.
The second thing you'll notice is that I first print_r()'d the Controller instance. Inside there is an amodel object, which is want to add to acontroller.
After that, I print_r()'d the $this (acontroller) object. It has everything it got from __construct(), but not amodel.
If I can get acontroller to "see" amodel, then my problem will be solved.
Also:
Is there anyway for me to remove "parent::init()" from the controller acontroller? I only did that so acontroller could have access to both the Load and Model class, but I'm trying to put as less code as possible in acontroller, so having the acontroller have access to Load and Model automatically would help a lot.
I hope I was clear. Thanks for any help
I personally do not think that singleton methods belong within an MVC Framework, the reason for this is because the main objects that are loaded are Models,Libraries and controllers, everything else such as the Router is usually hard coded.
The structure that i would do is create the following classes:
ModelLoader
LibraryLoader
and have them included during system boot, then within your main controller do the following:
class Controller
{
public $library;
public $model;
public function __construct()
{
$this->library = new LibraryLoader();
$this->model = new ModelLoader();
}
}
this would expose the 2 loaders to the child controller, your model/library should hold a private array storing the loaded objects, a little something like this:
class LibraryLoader extends ObjectLoader
{
protected $_path = "/app/library/";
protected $_ext = '.php';
}
class ModelLoader extends ObjectLoader
{
protected $_path = "/app/models/";
protected $_ext = '.php';
}
the object loader would look like so:
class ObjectLoader
{
protected $_path = "/app/";
protected $_ext = '.php';
public function __get($item)
{
/*
* Load item here, the paths above would be overwritten
* store the object in an array, make sure you check if its already loaded
*/
}
}
this is pretty basic, but within your child controllers such as index / home etc you can do the following:
class indexController extends Controller
{
public function index()
{
$this->model->users->getUser(22);
$this->library->security->validateInput("get","key");
//As the objectLoader manages whats loaded, any further calls to the above would
//use the same objects initiated as above.
}
}
This should get you started, its more streamline them using the singleton approach.
I guess you need to include Model.php in your controller.php to be able to use model class.
include 'Model.php';
include 'Load.php';
Since PHP 5.3 you can use the static keyword to instantiate a class
abstract class singleton
{
/**
* Holds an insance of self
* #var $instance
*/
protected static $instance = NULL;
/**
* Prevent direct object creation
*/
final private function __construct() { }
/**
* Prevent object cloning
*/
final private function __clone() { }
final public static function getInstance()
{
if(null !== static::$instance){
return static::$instance;
}
static::$instance = new static();
return static::$instance;
}
}
class myclass extends singleton
{
}
$myclass = myclass::getInstance();