How to display a class from another class in PHP - php

How to display a class from another class in PHP ?
class Layout {
public $var;
public function __construct() {
$this->var = 'test';
}
public function __toString() {
return $this->var;
}
}
class Template {
private $var_layout;
public function __construct() {
$obj = new Layout;
$this->var_layout = $obj;
}
public function __toString() {
return $this->var_layout;
}
}
$template = new Template();
echo($template);
Error message: Method Template::__toString() must return a string value
Please help, thank you very much..

return $this->var_layout; in the Template class does not return a string, it returns an object. Make it return a string by calling the __toString() method of that object explicitly.

Related

Creating a new class object and setting variables directly - PHP

I am trying to understand how to efficiently create a new class object and set the variables directly.
I have a class:
class element_model
{
public $sType;
public $properties;
}
I have a controller in which the following function is defined:
public function create_element($sType, $properties)
{
$oElement_model = new element_model($sType, $properties);
return new element_model($sType, $properties);
}
But this does not returns a new element_model with properties set, it just returns an empty object.
It does not, however, throw an error.
What is the reason the function above does not work?
You have to pass to the constructor of the class, in PHP you should have a method in the class __construct :
class element_model
{
public $sType;
public $properties;
public function __construct($type, $property)
{
$this->sType = $type;
$this->properties = $property;
}
}
Then you can access them (note the variables are public)
$elem = new element_model($sType, $properties);
$elem->sType;
Although in some cases it is better to encapsulate vars (declare them private):
class element_model
{
private $sType;
private $properties;
public function __construct($type, $property)
{
$this->sType = $type;
$this->properties = $property;
}
public function getType()
{
return $this->sType;
}
public function getProperty()
{
return $this->properties;
}
}
Then you can access the variable through a getter
$elem = new element_model($sType, $properties);
$elem->getType(); //and
$elem->getProperty();
You must create a __construct function in your class that accepts the parameters and sets your variables. Like this:
class element_model{
.
.
.
public function __construct($type,$properties)
{
$this->sType = $type;
$this->properties = $properties;
}
}
The __construct function will be called when you create the object.
But if you want to be extra cool in programming, just define your properties as private and create getter and setter functions to access the variables of your object
private $sType;
public function getSType(){
return $this->sType;
}
public function setSType($value){
$this->sType = $value;
}

Calling a non-static method from a static method

I think it is very basic functionality, please help.
How can I call non-static method into static-method in php.
class Country {
public function getCountries() {
return 'countries';
}
public static function countriesDropdown() {
$this->getCountries();
}
}
Preferred way..
It is better to make the getCountries() method static instead.
<?php
class Country {
public static function getCountries() {
return 'countries';
}
public static function countriesDropdown() {
return self::getCountries();
}
}
$c = new Country();
echo $c::countriesDropdown(); //"prints" countries
Adding a self keyword displays the PHP Strict Standards Notice To avoid that you can create an object instance of the very same class and call the method associated with it.
Calling a non-static method from a static method
<?php
class Country {
public function getCountries() {
return 'countries';
}
public static function countriesDropdown() {
$c = new Country();
return $c->getCountries();
}
}
$c = new Country();
echo $c::countriesDropdown(); //"prints" countries
You even use Class Name
public static function countriesDropdown() {
echo Country::getCountries();
}
You cannot straight forward do that for that you need create a instance of the class & have to call the non-static method,
class Country {
public function getCountries() {
return 'countries';
}
public static function countriesDropdown() {
$country = new Country();
return $country->getCountries();
}
}
DEMO.

PHP Method Chaining: Calling one method before allowing other methods to be chained

Consider the following class
class myClass {
private $model;
public function update($input) {
return $this->model->update($input);
}
public function find($id) {
$this->model = ORMfind($id);
}
}
How do I prevent
$myClass = new myClass;
$myClass->update($input);
The problem isn't HOW to use the above code but how to make update() a method only callable after find().
EDIT: I changed what my method does so it was more clearly understood that I need to do one method (find()) before another (update())
You could add a flag to your code like so:
class myClass {
private $model;
private $canUpdate = 0;
public function update($input) {
if ($canUpdate === 0) return; // or throw an exception here
return $this->model->update($input);
}
public function find($id) {
$this->model = ORMfind($id);
$canUpdate = 1;
}
}
Setting the flag $canUpdate will caution the update() method to react accordingly. If update() is called, you can throw an exception or exit out of the method if the flag is still 0.
To prevent from returning null value by get :
public function get() {
if (isset($this->value)) return $this->value;
else echo "please give me a value ";
}
You can also create a construct:
function __construct($val){
$this->value=$val;
}
and then give a value to your $value without using set() method:
$myClass=new myClass(10);
Outputting text, returning void, I think all of this is wrong. When you do not expect something to happen, you should throw an exception:
class MyClass {
private $canUpdate = false;
public function find($id) {
// some code...
$this->canUpdate = true;
}
public function canUpdate() {
return $this->canUpdate;
}
private function testCanUpdate() {
if (!$this->canUpdate()) {
throw new Exception('You cannot update');
}
}
public function update($inpjut) {
$this->testCanUpdate();
// ... some code
}
}
Now you can do:
$obj = new MyClass();
try {
$obj->update($input);
} catch (Exception $e) {
$obj->find($id);
$obj->update($input);
}
The proper way to make sure ->update() can only be called when the model has been initialized is to turn it into a dependency:
class myClass
{
private $model;
public function __construct($id)
{
$this->model = ORMfind($id);
}
public function update($input) {
return $this->model->update($input);
}
}
$x = new myClass('123');
Alternatively, if you have multiple find operations, you could introduce them as static constructor methods:
class myClass
{
private $model;
private function __construct($model)
{
$this->model = $model;
}
public function update($input) {
return $this->model->update($input);
}
public static function find($id)
{
return new self(ORMfind($id));
}
}
$x = myClass::find('123');
Update
Tackling your immediate problem can be done by a simple check:
public function update($input) {
return $this->model ? $this->model->update($input) : null;
}

PHP Object Oriented Issue On My Code

Hi please have a look on bellow code.
<?php
class A
{
public $name;
public function getName()
{
return $this->name;
}
}
class B extends A
{
public function setName()
{
$this->name = 'Prasad';
}
}
$obj = new B();
echo $obj->getName();
?>
Here It's display nothing when I echo the name. Related to the $name in class A. Is this issue is with getName or setName? How can I set the $name variable in class A from extended class B. And how can I get that from a class B object. Appreciate any hint or explanation on what I have missed.
You didn't set the name (using $obj->setName()) before.
Technically, it's echoing the $name variable (which is undefined at that point). Unfortunately, it hasn't been set yet. Try using $obj->setName() to set the name.
You are most of the way there with your code, in fact you would have a working example if you added a line telling the code to call the setName() function:
$obj = new B();
$obj->setName();
echo $obj->getName();
More typically you would use a set function with a parameter, then pass the value you want to set. You would also set the $name property to protected, which means the value must be accessed via the set & get methods (more on visibility in the manual):
<?php
class A
{
protected $name;
public function getName()
{
return $this->name;
}
}
class B extends A
{
public function setName($name)
{
$this->name = $name;
}
}
$obj = new B();
$obj->setName('Prasad');
echo $obj->getName();
?>
Yes, as SomeKittens suggested you need to call setName() first.
class A
{
public $name;
public function getName()
{
return $this->name;
}
}
class B extends A
{
public function setName()
{
$this->name = 'Prasad';
}
}
$obj = new B();
$obj->setName();
echo $obj->getName();
However, it might be better to perform the setting of the name in the constructor of B, as:
class A
{
public $name;
public function getName()
{
return $this->name;
}
}
class B extends A
{
public function B()
{
$this->name = 'Prasad';
}
}
$obj = new B();
echo $obj->getName();
This printed Prasad for me using http://writecodeonline.com/php/ to test the code.
Even better, pass the name 'Prasad' when creating the new B object, as:
class A
{
public $name;
public function getName()
{
return $this->name;
}
}
class B extends A
{
public function B( $value = 'Prasad' )
{
$this->name = $value;
}
}
$obj = new B();
echo $obj->getName(), "<br>";
$obj = new B( 'John' );
echo $obj->getName();
It's because you aren't setting the name attribute first. Call B->setName() and then you can get the name by calling B->getName().

PHP Observer Pattern, Issue

Bellow is a PHP script.
I tried to implement the Observer pattern (without MVC structure)... only basic.
The error which is encountered has been specified in a comment.
First I tried to add User objects to the UsersLibrary repository. There was a error such as User::update() does not exists or something.
Why is that error encountered? What fix should be applied and how?
interface IObserver {
public function update(IObservable $sender);
}
interface IObservable {
public function addObserver(IObserver $obj);
public function notify();
}
class UsersLibrary implements IObservable {
private $container;
private $contor;
//private $z;
public function __construct() {//IObserver $a) {
$this->container = array();
$this->contor = 0;
echo "<div>[constructing UsersLibrary...]</div>";
$this->addObserver(new Logger());
//$this->z = $a;
}
public function add($obj) {
echo "<div>[adding a new user...]</div>";
$this->container[$this->contor] = $obj;
$this->contor++;
$this->notify();
}
public function get($index) {
return $this->container[$index];
}
public function addObserver(IObserver $obj) {
$this->container[] = $obj;
}
public function notify() {
echo "<div>[notification in progress...]</div>";
foreach($this->container as $temp) {
//echo $temp;
#################################################################
$temp->update(); //--------ERROR
//Fatal Error: Call to a member function update() on a non-object.
#################################################################
}
//$this->container[0]->update();
//$this->z->update($this);
}
}
class User {
private $id;
private $name;
public function __construct($id, $name) {
$this->id = $id;
$this->name = $name;
}
public function getId() {
return $this->id;
}
public function getName() {
return $this->name;
}
}
class Logger implements IObserver {
public function __construct() {
echo "<div>[constructing Logger...]</div>";
}
public function update(IObservable $sender) {
echo "<div>A new user has been added.</div>";
}
}
$a = new UsersLibrary(); //new Logger());
//$a->add(new User(1, "DemoUser1"));
//$a->add(new User(2, "DemoUser2"));
$a->add("Demo");
echo $a->get(0);
//echo $a->get(0)->getName();
Your User class is not implementing interface IObserver and therefore is not forced to have the method update().
You have to instantiate a new User() in order to add it to the UsersLibrary:
$library = new UsersLibrary();
$user = new User(1, "Demo");
$library->add($user);
Also, you are mixing Users and Loggers into your UsersLibrary container. Maybe think about separating the containers for them?
You are passing a string instead of an object in your $a->add() call. You should either pass in an object, or alter the code in UserLibrary::add() to wrap it's argument in an appropriate object (or do an object lookup of it sees a string, for instance find a user with that name).
$user = new User(1, "Demo");
$a = new UsersLibrary();
$a->add($user);

Categories