I'am begginer in OOP PHP. I have code like this
class Index
{
public $activepage = true;
public $url;
public $page;
function __construct()
{
if ($this->activepage) {
$this->url = "Yes";
$this->page = "Home";
} else {
$this->url = "No";
$this->page = "Index";
}
}
public function show()
{
return $this->page;
}
public function showTest()
{
return "test";
}
}
class Home extends Index
{
function __construct()
{
echo $this->show();
}
}
$page = new Home;
My questions is :
Why I have blank page when I invoke Home class?
But when I change constructor in Home class like this echo $this->showTest();, it works. and displaying "test" on screen.
and what actually diferrent between my show method and showTest method in Index class?
When you add a __construct() in the Home class it overrides the construct from the parent class Index.
You can invoke the parent construct manually with:
function __construct()
{
parent::__construct();
echo $this->show();
}
You can call Parent class method like;
parent::show()
Related
i have two class, one(controller class) extend from another, then in the controller class, I define a variable "load" (in the construct), but when i extend from another class i can't invoke this variable from the constructor, any ideas? (Apologies for my bad english).
Class Controller:
<?php
class Controller {
protected $load;
public function __construct() {
$this->load = new Loader();
if($_GET && isset($_GET['action']))
{
$action = $_GET['action'];
if(method_exists($this, $action))
$this->$action();
else
die('Method not found.');
} else {
if(method_exists($this, 'index'))
$this->index();
else
die('Index method not found.');
}
}
}
Class home ( Where does it extend):
<?php
class Home extends Controller
{
function __construct() {
parent::__construct();
$this->load->model("HomeModel");// this line doesn't work
}
public function index() {
$articles = new HomeModel();
$articles = $articles->getData();
$nombres = ['jona', 'juan', 'jose'];
$view = new Views('home/home', compact("nombres", "articles"));
}
}
Loader Class:
<?php
class Loader
{
function __construct() {
}
public function model($model) {
require('./models/'.$model.'.php');
}
}
The error "'HomeModel' not found" would lead me to believe that you are not requiring the file that contains the 'HomeModel' class in the 'Home' class file.
<?php
class controller
{
public function view()
{
echo "this is controller->view";
}
}
class home extends controller
{
public function index()
{
echo "this is home->index";
}
function page()
{
echo "this is home-> page";
}
}
$obj= new home;
$method="index";// set to view or page
if(method_exists($obj,$method))
{
$obj->{$method}();
}
?>
my problem :
If we set $method to view, the view() from base controller class will be called.
i want to check if $method exist on home class only
(don't want to check if the function is defined in base class )
any idea how this can be implimented?
Define base class function as private.
Change
public function view()
{
echo "this is controller->view";
}
to
private function view()
{
echo "this is controller->view";
}
It will be work...
EDIT
function parent_method_exists($object,$method)
{
foreach(class_parents($object) as $parent)
{
if(method_exists($parent,$method))
{
return true;
}
}
return false;
}
if(!(method_exists($obj,$method) && parent_method_exists($obj,$method)))
{
$obj->{$method}();
}
This will working perfectly in your case...
Also refer this link
Based off of #vignesh's answer, I needed to use is_callable() to make it work.
abstract class controller {
private function view() {
echo "this is controller->view";
}
}
class home extends controller {
public function index() {
echo "this is home->index";
}
public function page() {
echo "this is home->page";
}
}
$home_controller = new home;
is_callable([ $home_controller, 'view']); // false
I have this code and i´m trying to use a object
<?php
class Controller {
public $_view;
public function __construct() {
$this->_view = new View();
return $this->_view;
}
}
class View {
public $_params = array ();
public function set_params($index_name,$valores) {
$this->_params[$index_name] = $valores;
}
public function get_param($index_name){
return $this->_params[$index_name];
}
}
?>
i would like to do this:
class Index extends Controller {
public function index() {
$model = Model::get_estancia();
$usuarios = $model->query("SELECT * FROM usuarios");
$this->_view->set_params(); // cant be used.
$this->load_view("index/index");
}
}
i would like to use the set_parms function.
but i can't see the View Function, then i can not use.
Can someone explain and advise me a good and safe way?
Correction from Phil: If a __construct() method isn't found, PHP will revert to legacy constructor syntax and check for a method with the same name as the object. In your case the method index() is being treated as the constructor, and is preventing the parent's constructor from loading the view object into the $_view property.
You can force a class to inherit a parent's constructor by defining __construct() in the child and calling the parent's constructor:
public function __construct() {
parent::_construct();
}
Here is the fixed code:
<?php
class Controller {
public $_view;
public function __construct() {
$this->_view = new View();
return $this->_view;
}
}
.
class View {
public $_params = array ();
public function set_params($index_name,$valores) {
$this->_params[$index_name] = $valores;
}
public function get_param($index_name){
return $this->_params[$index_name];
}
}
.
class Index extends Controller {
public function __construct() {
parent::__construct();
}
public function index() {
$model = Model::get_estancia();
$usuarios = $model->query("SELECT * FROM usuarios");
$this->_view->set_params(); // cant be used.
$this->load_view("index/index");
}
}
I am trying to create a new model object from my mvc controller but the page doesn't generate. Is there any reason why I can't do this? Surely I should be able to create an object inside an existing one?
Sorry to be so simplistic, and I know I sound like an idiot, but I'm not sure how to explain what I am doing wrong.
class controller_landing extends controller_base
{
public function __construct($get,$post)
{
parent::__construct($get,$post);
$this->model = new model_landing; <-----problem line here
}
}
abstract class controller_base
{
//store headers
protected $get;
protected $post;
//store layers
protected $view;
protected $model;
protected function __construct($get,$post)
{
//store the header arrays
$this->get = $get;
$this->post = $post;
//preset the view layer as an array
$this->view = array();
}
public function __destruct()
{
//extract variables from the view layer
extract($this->view);
//render the view to the user
require_once('view/'.$this->get['controller'].'_view.php');
}
}
class model_landing extends class_mysqli
{
public function __construct
{
echo "landing model";
}
}
class class_mysqli
{
public function __construct
{
echo "mysqli";
}
}
I don´t know, but I think you are missing brackets.
There
public function __construct
{
echo "landing model";
}
should be
public function __construct()
{
echo "landing model";
}
In the index file i have _autoload and load the libs and then i explode the url to get the wanted contoller and the model if exists. In the view i can see the model __construct() so the model is loaded but if i try to use $this->model->test(); i get
Call to a member function test() on a non-object
http://site.com/about
$this->request = about;
$controller = new $this->request;
$controller->loadModel($this->request);
Everething work ok
*Here is the Main controller *
class Conroller {
function __construct() {
// echo 'Main controller<br />';
$this->view = new View();
}
public function loadModel($name) {
$path = 'models/'.$name.'_model.php';
if (file_exists($path)) {
require 'models/'.$name.'_model.php';
$modelName = $name . '_model';
// **here i make the object**
$this->model = new $modelName();
}
}
}
Here is the About model
class about_model{
function __construct() {
echo 'test';
}
public function test() {
$test = 'test one';
}
}
Here is the About Conroller
class About extends Conroller {
function __construct(){
parent::__construct();
$this->model->test();
$this->view->render('/about');
}
}
You will need to call loadModel in your About controller before you refer to the model:
class About extends Conroller {
function __construct(){
parent::__construct();
$this->loadModel('about');
$this->about->test();
}
}