Error calling a interface method in php - php

Hey guys i have this sample code and i want to call the method like this code:
<?php
interface Item{
function getRes();
}
class Weapon implements Item{
public function getRes(){
echo "Res";
}
}
abstract class Player implements Item{
public function defend(){
$this->Item->Weapon->getRes();
}
}
?>
I know this doesn't work but how is the best way to do this call.

If you are inheriting the Item class in player (which I don't think a player is a type of item ;) ), you would need to implement the getRes function.
Moving away from that, you will most likely want to rely on dependency injection (DI) in order for your player to get a weapon.
interface Item {
function getResponse();
}
interface AttackItem extends Item {
}
interface DefenseItem extends Item {
}
class Sword implements AttackItem {
public function getResponse(){
return "Swing of the sword!";
}
}
class Shield implements DefenseItem {
public function getResponse(){
return "Defend with the shield!";
}
}
class Player {
public function __construct(AttackItem $attackItem, DefenseItem $defenseItem) {
$this->attackItem = $attackItem;
$this->defenseItem = $defenseItem;
}
public function attack(){
return $this->attackItem->getResponse();
}
public function defend(){
return $this->defenseItem->getResponse();
}
}
$player = new Player(new Sword(), new Shield());
echo $player->attack() . "\n";
echo $player->defend() . "\n";

Related

Extends a PHP class and it's children

In one of my projects, I use an external library providing two classes : DrawingImage and DrawingCharset, both of them extending BaseDrawing.
I want to extends BaseDrawing to add some properties and alter an existsing method. But I also want theses modifications in "copy" of existing children (DrawingImage and DrawingCharset).
There is a simple way to do it ? Extending don't seems to be a solution : I must duplicate code between each subclass. And I'm not sure i can call a parent method through Trait.
Traits can access properties and methods of superclasses just like the subclasses that import them, so you can definitely add new functionality across children of BaseDrawing with traits.
<?php
class BaseDrawing
{
public $baseProp;
public function __construct($baseProp)
{
$this->baseProp = $baseProp;
}
public function doSomething()
{
echo 'BaseDrawing: '.$this->baseProp.PHP_EOL;
}
}
class DrawingImage extends BaseDrawing
{
public $drawingProp;
public function __construct($baseProp, $drawingProp)
{
parent::__construct($baseProp);
$this->drawingProp = $drawingProp;
}
public function doSomething()
{
echo 'DrawingImage: '.$this->baseProp.' - '.$this->drawingProp.PHP_EOL;
}
}
class DrawingCharset extends BaseDrawing
{
public $charsetProp;
public function __construct($baseProp, $charsetProp)
{
parent::__construct($baseProp);
$this->charsetProp = $charsetProp;
}
public function doSomething()
{
echo 'DrawingCharset: '.$this->baseProp.' - '.$this->charsetProp.PHP_EOL;
}
}
/**
* Trait BaseDrawingEnhancements
* Adds new functionality to BaseDrawing classes
*/
trait BaseDrawingEnhancements
{
public $traitProp;
public function setTraitProp($traitProp)
{
$this->traitProp = $traitProp;
}
public function doNewThing()
{
echo 'BaseDrawingEnhancements: '.$this->baseProp.' - '.$this->traitProp.PHP_EOL;
}
}
class MyDrawingImageImpl extends DrawingImage
{
// Add the trait to our subclass
use BaseDrawingEnhancements;
}
class MyDrawingCharsetImpl extends DrawingCharset
{
// Add the trait to our subclass
use BaseDrawingEnhancements;
}
$myDrawingImageImpl = new MyDrawingImageImpl('Foo', 'Bar');
$myDrawingImageImpl->setTraitProp('Wombats');
$myDrawingCharsetImpl = new MyDrawingCharsetImpl('Bob', 'Alice');
$myDrawingCharsetImpl->setTraitProp('Koalas');
$myDrawingImageImpl->doSomething();
$myDrawingCharsetImpl->doSomething();
$myDrawingImageImpl->doNewThing();
$myDrawingCharsetImpl->doNewThing();

How to access functions and data of one class in other class in php

I am new to PHP OOPs and I have a problem where I want to access the member data and functions of one class in another class. I google it but not getting any perfect solution.
Here is my example code:
class school{
public function teacher()
{
$teacher_name='Ali Raza';
}
public static function students()
{
echo"STUDENT DATA: Jhon Deo";
}
}
class library{
public function teacher_name()
{
// Now here i want to acces the name of teacher form above class function teacher.
}
public function student_name()
{
// Now here i want to access the member function(students) from school class.
}
}
I am new here. Thanks in advance.
Try this for accessing function of class school into class library function:
class school {
public function teacher()
{
$teacher_name='Ali Raza';
}
public function students()
{
echo"STUDENT DATA: Jhon Deo";
}
}
class library {
public function teacher_name()
{
// Now here i want to acces the name of teacher form above class function teacher.
}
public static function student_name()
{
echo School::students();
}
}
You need to instantiate the class that has the data you want to access. Or, you can define the data static and access it without instantiating.
Take a look at this:
class library{
private $getTeacherInstance;
public function teacher_name()
{
if(!$getTeacherInstance) // if instance is not created
$this->getTeacherInstance = new school(); // then get a new instance
return $this->getTeacherInstance->teacher(); // call the method exists inside `school class`
}
}
Make your teacher() function to return some data like "Teacher's name"
Try this one. This is a php class that inherits the from school class to library class.
The main function will access the data needed through the library class that takes the data from school class.
Hope this helps
<?php
class school{
public $teacher_name;
public $students_name;
public function getTeacherName(){
return $this->teacher_name;
}
public function setTeacherName(){
$this->teacher_name = "Ali Raza";
}
public function getStudentName(){
return $this->students_name;
}
public function setStudentName(){
$this->students_name = "Ali Raza";
}
}
/**
*
*/
class library extends school
{
//this will get the value from class school
}
function showAll(){
$showAll = new library();
$showAll->setTeacherName();
echo "Teacher Name: " . $showAll->getTeacherName() . '<br>';
echo "Studnet Name: ". $showAll->getStudentName();
}
showAll();

PHP Decorator Debugging

Reading this article and worked through the Decorator example. The code is returning <strong></strong> instead of the expected <strong>Logout</strong>.
class HtmlLinks {
//some methods which is available to all html links
}
class LogoutLink extends HtmlLinks
{
protected $_html;
public function __construct() {
$this->_html = "Logout";
}
public function setHtml($html) {
$this->_html = $html;
}
public function render() {
echo $this->_html;
}
}
class LogoutLinkStrongDecorator extends HtmlLinks {
protected $_logout_link;
public function __construct( $logout_link ) {
$this->_logout_link = $logout_link;
$this->setHtml("<strong>" . $this->_html . "</strong>");
}
public function __call( $name, $args ) {
$this->_logout_link->$name($args[0]);
}
}
$logout_link = new LogoutLink();
$logout_link = new LogoutLinkStrongDecorator($logout_link);
$logout_link->render();
Tried to debug all afternoon but I haven't made any headway. Any insight would be appreciated.
Looks like you forgot to pull the _html from the inner object. You need to add it to each constructor method of each decorator. Basically add this $this->_html=$_linked_obj->_html.
Decorator pattern:
The Decorator and the Decorated Object implement the same interface.
The Decorator takes an object implementing the shared interface in its constructor.
You don't necessarily want your decorator to inherit from the class it decorates. You just care that it implements the method you need in the context you're using it (in this case, "render()"), which you can enforce by using Interfaces. The benefit of using inheritance is that all other methods are guaranteed to still be callable, and you'll also get back an instance of the class you passed in.
The code:
interface Renderable
{
public function render();
}
class HtmlLink implements Renderable
{
public function render()
{
return ''.$this->anchorText.'';
}
// other link methods...
}
class StrongRenderableDecorator implements Renderable
{
protected $renderable;
public function __construct(Renderable $renderable)
{
$this->renderable = $renderable;
}
public function render()
{
return '<strong>'.$this->renderable->render().'</strong>';
}
}
$logout_link = new StrongRenderableDecorator(new LogoutLink());
$logout_link->render();

Force someone to make his sub classes implement an interfaces' methods

I'm wondering how to force sub classes to implement a given interface method.
Let's say I have the following classes :
interface Serializable
{
public function __toString();
}
abstract class Tag // Any HTML or XML tag or whatever like <div>, <p>, <chucknorris>, etc
{
protected $attributes = array();
public function __get($memberName)
{
return $this->attributes[$member];
}
public function __set($memberName, $value)
{
$this->attributes[$memberName] = $value;
}
public function __construct() { }
public function __destruct() { }
}
I would like to force any sub class of "Tag" to implement the "Serializable" interface. For example, if i a "Paragraph" class, it would look this way :
class Paragraph extends Tag implements View
{
public function __toString()
{
print '<p';
foreach($this->attributes as $attribute => $value)
print ' '.$attribute.'="'.$value.'"';
print '>';
// Displaying children if any (not handled in this code sample).
print '</p>';
}
}
How can i force a developer to make his "Paragraph" class implement the methods from the interface "Serializable"?
Thanks for taking the time to read.
Just have the abstract class implement the interface:
interface RequiredInterface
{
public function getName();
}
abstract class BaseClass implements RequiredInterface
{
}
class MyClass extends BaseClass
{
}
Running this code will result in the error:
Fatal error: Class MyClass contains 1 abstract method and must
therefore be declared abstract or implement the remaining methods
(RequiredInterface::getName)
This requires the developer to code the methods of RequiredInterface.
PHP code example:
class Foo {
public function sneeze() { echo 'achoooo'; }
}
abstract class Bar extends Foo {
public abstract function hiccup();
}
class Baz extends Bar {
public function hiccup() { echo 'hiccup!'; }
}
$baz = new Baz();
$baz->sneeze();
$baz->hiccup();
It is possible for an abstract class to extend Serializable, as abstract classes do not need to be base classes
This adds a __constructor to your class Paragraph which checks to see if Serializable is implemented.
class Paragraph extends Tag implements View
{
public function __construct(){
if(!class_implements('Serializable')){
throw new error; // set your error here..
}
}
public function __toString()
{
print '<p';
foreach($this->attributes as $attribute => $value)
print ' '.$attribute.'="'.$value.'"';
print '>';
// Displaying children if any (not handled in this code sample).
print '</p>';
}
}

Get called a subclass method from a superclass

I have a big problem. How to get called subclass method from a superclass. Please execute below code.
class Model {
public function render(){
echo '<br />class: '.get_class($this).' -- function: '.__FUNCTION__;
}
}
class Product extends Model {
public function show(){
$this->render();
}
}
class User extends Model {
public function index(){
$this->render();
}
}
$p = new Product();
$u = new User();
echo $p->show();
echo $u->index();
result :
class: Product -- function: render
class: User -- function: render
How to get subclass method name instead of render?
Thanks.
You can get that information using debug_backtrace().
I am curious as to why you want this - it could indicate a flaw with your design if you need this for anything other than debugging.
The __FUNCTION__ thingie is replaced at compile-time by the name of the function it is in. So no matter how your object model is structured, you'll get the function where __FUNCTION__ is met by PHP's preprocessor.
The best you can do here, if you want to know the name of the method being called, is to add it as a parameter to the method render() :
class Model {
public function render($methodName){
echo '<br />class: '.get_class($this).' -- function: '. $methodName;
}
}
And add the name in the method calls :
class Product extends Model {
public function show(){
$this->render(__FUNCTION__);
}
}
class User extends Model {
public function index(){
$this->render(__FUNCTION__);
}
}
Could you go into detail as to why you need this?
I'm not sure what you are trying to do, but especially when you are developing a PHP framework you should restrict yourself to the basic rules of inheritance.
Maybe you could illustrate a little better what you're trying to achieve with this.
Couldn't you simply change it to the following?
class Model {
protected $_type='unspecified';
public function render(){
echo '<br />class: '.$this->_type.' -- function: '.__FUNCTION__;
}
}
class Product extends Model {
public function __construct(){
$this->_type = 'product';
}
public function show(){
$this->render();
}
}
class User extends Model {
public function __construct(){
$this->_type = 'user';
}
public function index(){
$this->render();
}
}
Or is there any reason why that doesn't work for you?
You could move the logic which works out what you are rendering into the superclass, e.g.:
class Model {
public function render($type){
echo '<br />class: '.get_class($this).' -- function: '.$type;
}
public function show() {
$this->render('show');
}
public function index() {
$this->render('index');
}
}
class Product extends Model {
public function show(){
//some stuff
parent::show();
}
}
class User extends Model {
public function index(){
parent::index();
}
}
I don't really recommend this to you, but what you could do is throw an exception and catch it right away.
Then you can use the stack trace of this exception to find out which function called your render method.
I know that it works, but both performancewise and codingwise this is not a good option.
UPDATE:
<?php
class bla {
function test1() {
$this->test2();
}
function test2() {
$method = "";
try {
throw new Exception("bla");
} catch(Exception $e) {
$trace = $e->getTrace();
$method = $trace[1]['function']);
}
echo $method; //will echo test1
}
}
$blub = new bla();
$blub->test1();
Hope you get what I'm trying to illustrate.

Categories