<?php
class Model{
public $string;
public function __construct(){
echo "Constructor is called";
$string = "MVC + PHP = Awesome!";
}
}
class View{
private $model;
private $controller;
public function __construct($controller, $model){
$this->controller = $controller;
$this->model = $model;
}
public function output(){
echo "<p> The string is " . $this->model->string . "</p>";
}
}
class Controller{
public $model;
public function __construct($model){
$this->model = $model;
}
}
$model = new Model();
$controller = new Controller($model);
$view = new View($controller, $model);
$view->output();
?>
I am trying to learn MVC framework in PHP. But I am facing this problem.
The constructor of the model is called but I dont get any output of $this->model->string in "view->output".
Thanks
$string is just a variable in a scope of a function, $this->string is a property.
class Model{
public $string;
public function __construct(){
echo "Constructor is called";
$this->string = "MVC + PHP = Awesome!"; // note change here
}
}
Related
the code is self-explanatory, but the problem is, that I can't override the static variable through method calls, so the static variable of the class gives a value, but the value that I get through the objects is different.
Class dbEntity {
protected static $connection;
private static $name = "dbEntity";
public static function getName() {
return self::$name;
}
public static function setConnection($connection) {
self::$connection = $connection;
}
public static function getConnection() {
return self::$connection;
}
}
Class Patient extends dbEntity {
public static $connection = "patientConnection";
public static $name = "Patient";
}
$p = new Patient();
$p->setConnection("myConnection");
echo $p->getConnection() . "\n"; //myConnection
echo Patient::$connection . "\n"; //patientConnection
echo $p->getConnection() . "\n"; //myConnection
Ulrich is correct, if you change the following lines from self:: to static:: the code works as you're expecting it to.
public static function getName() {
return static::$name;
}
public static function setConnection($connection) {
static::$connection = $connection;
}
public static function getConnection() {
return static::$connection;
}
...
echo $p->getConnection() . "<br>"; //myConnection
echo Patient::$connection . "<br>"; //myConnection
echo $p->getConnection() . "<br>"; //myConnection
You need late static binding, see the official documentation:
https://www.php.net/manual/en/language.oop5.late-static-bindings.php
I am noob in PHP because I am mostly do .NET/Java. In code base I am working, I have,
class SomeOtherBaseClass{
public $prop2;
public function __construct(string $prop3)
{
$this->prop2 = $prop3;
}
public function __toString()
{
return $this->prop2 . ' '. $this->prop2;
}
}
class SomeClass
{
public function __toString()
{
return $this->prop1 . ' '. $this->prop1;
}
public $prop1;
public function someMethod() : SomeOtherBaseClass
{
return $this->createClass();
}
public function __construct()
{
$this->prop1 = 'foo';
}
private function createClass(
): SomeOtherBaseClass {
return new class(
$this->prop1
) extends SomeOtherBaseClass {
};
}
}
$class = new SomeClass();
echo $class;
echo $class->someMethod();
Why I am getting error that prop1 not found. Clearly createClass function is part of SomeClass which have prop1. Why I cannot access prop1 inside createClass?
It's because $prop1 has no value or meaning.
You can add a __construct() function to resolve your issue:
public function __construct()
{
$this->prop1 = 'foo';
}
now when you call this class (e.g. $foo = new SomeClass();):
$prop1 has a value of foo which can be used in your functions:
public function echoProp()
{
echo $this->prop1; # will output foo
}
Note: This is just an explanation answer - not a copy/paste solution - but the principles are all here for you to use in your code.
Let me know if this wasn't what you were looking for :)
Edit:
if prop1 exists in SomeOtherClass, when you construct you can do
public function __construct()
{
$this->class = new SomeClass();
$this->prop1 = $this->class->prop1;
}
Im testing this thing where i'm trying to load a class and use it like this:
$this->model->model_name->model_method();
This is what I've got:
<?php
error_reporting(E_ALL);
class Loader {
public function model($model)
{
require_once("models/" . $model . ".php");
return $this->model->$model = new $model;
}
}
class A {
public $load;
public $model;
public $text;
public function __construct()
{
$this->load = new Loader();
$this->load->model('Test');
$this->text = $this->model->Test->test_model();
}
public function get_text()
{
return $this->text;
}
}
$text = new A();
echo $text->get_text();
?>
Im getting a bunch of errors here:
Warning: Creating default object from empty value in
C:\xampp\htdocs\fw\A.class.php on line 9
Notice: Trying to get property of non-object in
C:\xampp\htdocs\fw\A.class.php on line 24
Fatal error: Call to a member function test_model() on a non-object in
C:\xampp\htdocs\fw\A.class.php on line 24
What am I doing wrong? Thanks for any tip!
P.S. not much in the loaded file:
<?php
class Test {
public function test_model()
{
return 'testmodel';
}
}
?>
In the A class' constructor you are not assigning the "loaded" model to anything and later you are trying to use the $model property which has nothing assigned to it.
Try this:
class A {
public $load;
public $model;
public $text;
public function __construct()
{
$this->load = new Loader();
$this->model = $this->load->model('Test');
$this->text = $this->model->test_model();
}
(...)
Problem may be that you have not defined Loader.model as object but treating it like it is.
class Loader {
public $model = new stdClass();
public function model($model)
{
require_once("models/" . $model . ".php");
return $this->model->$model = new $model();
}
}
When you have your class like this you can use
$this->model->model_name->model_method();
Try the following code(UPDATED) if you want to avoid $this->model = $this->load->model('Test') in the constructor.
You can simply load the models by calling $this->loadModel(MODEL) function
<?php
error_reporting(E_ALL);
class Loader {
private $models = null;
public function model($model)
{
require_once("models/" . $model . ".php");
if(is_null($this->models)){
$this->models = new stdClass();
}
$this->models->$model = new $model();
return $this->models;
}
}
class A{
public $load;
public $model;
public $text;
public function __construct()
{
$this->load = new Loader();
$this->loadModel('Test');
$this->loadModel('Test2');
$this->text = $this->model->Test2->test_model();
}
public function get_text()
{
return $this->text;
}
private function loadModel($class){
$this->model = $this->load->model($class);
}
}
$text = new A();
echo $text->get_text();
?>
I am building a wordpress plugin in some MVC style and i have setup almost every thing but when using call_user_func to call the request action class, I am not able to use the $this with the requested class.
Here is my code so far...
class Action{
protected $class;
protected $method;
protected $args = array();
protected $template='settings/index';
public function __construct() {
$this->getRequest();
}
public function getRequest(){
if(isset($_GET['c'])){
$route = $_GET['c'];
$parts = explode('/',$route);
if(isset($parts[0]))
$this->class = $parts[0];
if(isset($parts[1]))
$this->method = $parts[1];
if(isset($parts[2]))
$this->args[] = $parts[2];
if(isset($parts[3]))
$this->args[] = $parts[3];
}
}
public function render(){
extract($this->data);
ob_start();
require(LINKWAG_VIEW .DS. $this->template . P);
$this->output = ob_get_contents();
ob_end_clean();
return $this;
}
public function output(){
echo $this->output;
}
}
class Grv extends Action{
public function __construct() {
parent::__construct();
add_action('admin_menu', array($this,'setup'));
}
public function setup(){
add_menu_page( 'LinkWag', 'LinkWag', 'manage_options', 'linkwag',array($this,'execute'), plugins_url( 'myplugin/images/icon.png' ), 6 );
}
public function execute(){
if($this->class){
$this->controller = call_user_func_array(array($this->class,$this->method), $this->args);
}
}
}
The requested class goes here
class Settings extends Grv{
public function __construct() {
//parent::__construct();
}
public function view($id=false){
$this->template = 'settings/view'; // using $this here craetes a fatal error
$this->render();
}
}
suppose i requested
admin.php?page=grv&c=settings/view/2
please tell me what i am doing wrong..
use $this->render() instead of $this->class->render();
another is: add ucfirst because your class name is in first letter capital and you are passing small case in arguments.
$this->controller = call_user_func_array(array(ucfirst($this->class), $this->method), $this->args)
<?php
class FirstClass{
public static $second;
public static $result = 'not this =/';
public function __construct(){
$this->result = 'ok';
$this->second = new SecondClass();
}
public function show(){
echo $this->second->value;
}
}
class SecondClass extends FirstClass{
public $value;
public function __construct(){
$this->value = parent::$result; //Make it get "ok" here
}
}
$temp = new FirstClass();
$temp->show(); //It will show: "not this =/"
?>
How can I make it to print "ok"?
I mean, the SecondClass should know what FirstClass set as result, see?
Replace $this->result = 'ok'; with self::$result = 'ok'; in FirstClass constructor.
Btw, the code is terrible. You're mixing static and instance variables, and extend classes but don't use benefits extension provides.
you need to reference the static as self::$result in the first class.
Below should do what you want...
<?php
class FirstClass{
public static $second;
public static $result = 'not this =/';
public function __construct(){
self::$result = 'ok';
$this->second = new SecondClass();
}
public function show(){
echo $this->second->value;
}
}
class SecondClass extends FirstClass{
public $value;
public function __construct(){
$this->value = parent::$result; //Make it get "ok" here
}
}
$temp = new FirstClass();
$temp->show(); //It will show: "not this =/"
?>