i have multiple controller like registerController, loginController, boardController
and those controllers have same dependency of authentication.
in code
$registerController = new Register($authentication);
$loginController = new Login($authentication);
$shopController = new Shop();
$boardController = new Board($authentication);
so im trying to make parent class for those contorllers that named BaseController.
so child Controllers can inherite same authentication instance.
class BaseController {
public $authentication;
public function __construct($authentication) {
$this->authentication = $authentication;
}
}
one of my ChildController looks like this
class Shop extends BaseController{
public function __construct() {}
public function checkParentAuth(){
var_dump($this->authentication); // it shows NULL
}
}
i wish the code look like this
new BaseController($authentication);
$registerController = new Register();
$loginController = new Login();
$shopController = new Shop();
$boardController = new Board();
what should i do for this?
i thought it will surely works...
It looks like you're missing call the parent contructor, which will run all stuff necessary to activate and fill values the properties/variables
class Orders extends Site_Controller
{
public function __construct()
{
//first, call the parent constructor
parent::__construct();
...
//your code goes here.
}
}
Related
I am building an MVC component and I'm getting stuck with an issue with a parent and child model. I have a few methods in the parent Model and they're not working with the database_class object
the constructor works fine
but when I use that object in the methods its like the constructor doesn't exist?
Class Controlller
{
public function __construct()
{
$this->childModel = $this->model('childModel');
} // end construct
// methods go here
}
Here are the models:
class childModel extends parentModel {
private $dbo;
public function __construct()
{
$dbobj = new Database_class;
$this->dbo = $dbobj;
}
//methods
}
class parentModel {
private $dbom;
public function __construct()
{
$dbombj = new Database_class;
$this->dbom = $dbombj;
var_dump($this->dbom); //working perfectly as database object
}
public function methodName()
{
var_dump($this->dbom); //not showing up as database object
}
}
I don't think this code is doing what you think it's doing. In childModel, you are overwriting the __construct method of the parentModel, so the __construct in the parentModel never gets called. Therefore $this->dbom should be null. Furthermore if you wish to use $this->dbom from the childModel, you should probably change the scope from private $dbom to protected $dbom. See this page for more info on that: http://php.net/manual/en/language.oop5.visibility.php
I have a simple php code and I want to split it into model,view,helper. Model should access some methods from helper class and helper class should access some methods from model class.
I am not sure if the below pattern is correct. I guess it is not because in this example model,view,helper will be initialized multiple times. Which is the most simple way to accomplish something like I am trying to do with the below code?
lib/main.php
require_once('lib/model.php');
require_once('lib/helper.php');
require_once('lib/view.php');
$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : 'show';
switch($action){
case "show":
$class->showAction();
break;
case "another":
$class->anotherAction();
break;
}
class main extends abstract{
public function showAction(){
if($this->helper->getParam('browse')){
//something
}else{
$profiles= $this->model->getProfiles();
}
echo $this->view->toHtml($profiles);
}
}
lib/abstract.php
class abstract{
public function __construct(){
$this->model = new model();
$this->view = new view();
$this->helper = new helper();
}
}
lib/model.php
class model extends abstract{
public function getProfiles(){
if($this->helper->someMethod(){
//some code
}
//some code
return $profiles;
}
}
lib/helper.php
class helper extends abstract{
public function someHelperMethod(){
if($this->model->someAnotherMethod(){
//some code
}
//some code
return $profiles;
}
}
First problem is that you are nesting your classes like russian dolls. You shouldn't have your Abstract class both contain model/view/helper, and be the parent of model/view/helper.
I'd caution against using extension just to ensure a class is in-scope.
Generally you can think of it this way: use extension when your class has shared behaviors or properties as it's parent, but it either needs additional functionality, or modifications to existing functionality.
The "abstract" class you defined shares no attributes or methods between Model/View/Helper, so Model/View/Helper should not probably extend from it.
If however you want a "container" class that contains instances of each of these class types, just make it a standalone class, don't extend it, for example:
class Container{
public $model;
public $view;
public $helper;
public function __construct(){
$this->model = new model();
$this->view = new view();
$this->helper = new helper();
}
public function showAction(){
if($this->helper->getParam('browse')){
//something
}else{
$profiles= $this->model->getProfiles();
}
echo $this->view->toHtml($profiles);
}
Then instantiate it only once at the start someplace:
$action = isset($_REQUEST['action']) ? $_REQUEST['action'] : 'show';
$class = new Container();
Then, if you want to call something from Model inside Helper, this can be done a number of ways.
One option, pass a reference to this class and keep it inside Helper:
// Inside Container
public function __construct(){
$this->model = new model();
$this->view = new view();
$this->helper = new helper($model);
}
The Helper class would look like:
class Helper{
protected $model;
public function __construct($model){
$this->model = $model;
}
public function someHelperMethod(){
if($this->model->someAnotherMethod()){
//some code
}
//some code
return $profiles;
}
}
I've got to implement a database connection pattern. I created two classes:
ConnectionFactory
MySQLService
ConnectionFactory:
<?php
class ConnectionFactory {
protected static $connection;
public function getConnection() {
if (!self::$connection) {
self::$connection = new PDO('mysql:host=localhost;dbname=sapienter', "root", "admin");
}
return self::$connection;
}
}
?>
MySQLService:
<?php
class MySQLService {
protected $connectionFactory;
public function __construct(ConnectionFactory $factory) {
$this->connectionFactory = $factory;
}
public function listItemsForSharerSQL() {
$conn = $this->connectionFactory->getConnection();
$items = ...
return $items;
}
}
?>
I call these methods in my controller ItemController:
<?php
require_once ROOT_DIR . "/models/Item.php";
require_once ROOT_DIR . "/ConnectionFactory.php";
require_once ROOT_DIR . "/MySQLService.php";
class ItemController {
private $data;
public function listItemsForSharer() {
$connFactory = new ConnectionFactory();
$service = new MySQLService($connFactory);
$items = $service->listItemsForSharerSQL();
$this->data = ['items' => $items];
return 'itemslistforsharer-view';
}
}
?>
I don't like the fact that I've got to instantiate a new ConnectionFactory in my Controller. Is it a mistake? Should I change my code design?
It is mistake that you are using a Database in a Controller at all. If talking about a Controller from the MVC Architecture pattern, then its Models job to interact with the database. There should be only instances of the Models in the controllers, but not instances of the Database.
Basically in the modern MVC frameworks that Models are extending the base Model class, which has the instantiation of the database.
As I understand, MySQLService is something like a model since you are returning some items, it seems like you are doing DB operation and want to handle it from a controller. Instead of every model having its own constructor, you should use a base class. I would suggest something like:
class Model {
protected function getAdapter() {
$connection = new ConnectionFactory();
return $connection->getConnection();
}
}
class MySQLService extends Model {
public function listItemsForSharerSQL() {
$this->getAdapter();
$items = ...
return $items;
}
}
So now your controller will only need
$service = new MySQLService();
Ofcourse you base class can have the getAdapter() method as a constructor, without any params, so you won't need to pass anything to the MySQLService and won't need to call getAdapther() in each method of MySQLService. Depends on your needs.
I need to call a function someFunction() how do I refer to it when it is in the following class structures?
abstract class A
{
protected $session;
protected $model;
public function __construct()
{
$session = new classSession;
$model = new classModel;
}
}
class classModel
{
$this->session->someFunction();
}
I've tried using $this->session->someFunction() but it does not work!
Firstly, you need to put it within the context of a function - code cannot exist on its own within a class body. Secondly, for anything in classModel to access $session, classModel has to extend class A. You end up with something like this:
class classModel extends A
{
public function foo()
{
$this->session->someFunction();
}
}
So for $this->session->someFunction(); to execute, you'd do this:
$model = new classModel();
$model->foo();
I'm trying to build MVC pattern using OOP PHP. Please read the rest of the post to understand what I want exactly.
This is the homepage controller which extends the main controller
class Home extends Controller {
function __construct () {
parent::__construct();
}
public function index () {
$this->load->model("test");
$this->test->get_all();
$data = array (
'name' => "Amr",
'age' =>24
);
$this->load->view("home_view",$data);
}
}
The Main Controller looks like this and extends loader class:
class Controller extends Loader {
public $load;
function __construct(){
parent::__construct();
$this->load = new Loader();
}
}
The Loader class which has the problem looks like this
class Loader {
public $Error;
function __construct(){
$this->Error = new Error();
}
public function model($Modelname){
$this->$Modelname = $Modelname;
if (file_exists("models/".$Modelname.".php")){
require_once $Modelname . ".php";
$this->$Modelname = new $Modelname;
}else{
$this->Error->Not_found();
}
}
public function view($Viewname,$data=NULL){
if(is_array($data)){
extract($data);
}
if (file_exists("views/".$Viewname.".php")){
require_once $Viewname . ".php";
}else{
$this->Error->Not_found();
}
}
public function helper($helper) {
if (file_exists("helpers/".$helper.".php")){
require_once $helper . ".php";
$this->$helper = new $helper;
}else{
$this->Error->Not_found();
}
}
}
What I need to do is to be able FROM HOMEPAGE Controller to do something like this:
$this->load->model("someModel"); // model name is test
$this->someModel->someMethodInModel(); // the model method is get_all()
// and the same for helper
$this->load->helper("someHelper");
$this->someHelper->someMethodInHelper();
Can anyone help me?
EDIT: The error that I'm getting when doing this is:
Notice: Undefined property: Home::$test
Fatal error: Call to a member function get_all() on a non-object
NOTE: the model name is test and the model method is get_all()
public function model($Modelname){
$this->$Modelname = $Modelname;
if (file_exists("models/".$Modelname.".php")){
require_once $Modelname . ".php";
$this->$Modelname = new $Modelname;
What do you need help with? With your current code you can do
$this->load->model("someModel");
$this->someModel->someMethodInModel();
// and the same for helper
$this->load->helper("someHelper");
$this->someHelper->someMethodInHelper();
in your Home controller. I just tried it out myself. What errors do you get? What's not working properly?
If I were you, I would put a "load()" method into my controller which would call the "loader" class and store the new model/helper/view into a variable.
I think the problem you're having is, your loader creates an instance of a model as a member of the Loader class, and not your controller class.
if your base controller extends Loader then there is no reason use it like property
class Controller extends Loader {
public $load;
function __construct(){
parent::__construct();
$this->load = new Loader();
}
}
change it to
class Controller extends Loader {
}
another way is to use magic method hook http://php.net/manual/en/language.oop5.overloading.php#object.get
class Controller {
public $load;
function __construct(){
parent::__construct();
$this->load = new Loader();
}
function __get($modelName){
return $this->load->$modelName;
}
}