Can't set PHP Interface function - Why? - php

I'm trying to set the "setFlyBhavior(FlyBehavior $newFlyBehavior)" dynamically. Can anyone explain why it will not work in the code below? I appreciate your help.
<?php
abstract class Duck {
public $flyBehavior;
public function performFly() {
return $this->flyBehavior->fly();
}
public function setFlyBhavior(FlyBehavior $newFlyBehavior) {
$this->flyBehavior = $newFlyBehavior;
}
}
interface FlyBehavior {
public function fly();
}
class GotWings implements FlyBehavior {
public function fly(){
return "<br />I'm flying with wings!!<br />";
}
}
class NotWings implements FlyBehavior {
public function fly(){
return "<br />I can't fly I have no wings!!<br />";
}
}
class FlyingDuck extends Duck {
public function __construct(){
$this->flyBehavior = new GotWings();
}
}
$ducky = new FlyingDuck();
// Code works when the setFlyBehavior function is commented out.
$ducky->setFlyBehavior(new NoWings);
echo "<br />I'm a Duck: " . $ducky->performFly();
?>
Note: The code works when not calling the "ducky->setFlyBehavior function. I also tried defining the setFlyBehavior function in the Duck class without using type casting, which also failed e.g.
public function setFlyBhavior($newFlyBehavior) {
$this->flyBehavior = $newFlyBehavior;
}

You are calling the wrong function and class names.
Replace the line:
$ducky->setFlyBehavior(new NoWings);
With:
$ducky->setFlyBhavior(new NotWings);

Related

Head first design pattern bug

I am studying Head First - design patterns and translating the exercises to PHP.
I dont get any errors but there is a bug that I cannot figure out.
Edit ( Code ):
abstract class Cat
{
public $meowBehaviour, $eatBehaviour;
function __construct(MeowBehaviour $meowBehaviour, EatBehaviour $eatBehaviour)
{
$this->meowBehaviour = $meowBehaviour;
$this->eatBehaviour = $eatBehaviour;
}
public abstract function sits();
public function performMeowBehaviour()
{
$this->meowBehaviour->meow();
}
public function performEatBehaviour()
{
$this->eatBehaviour->eat();
}
}
interface EatBehaviour {
public function eat();
}
class EatCatFood implements EatBehaviour {
public function eat()
{
echo "I eat cat food. <br />";
}
}
class EatGazzelle implements EatBehaviour {
public function eat()
{
echo "I hunt and eat gazzelle. <br />";
}
}
interface MeowBehaviour {
public function meow();
}
class Meow implements MeowBehaviour {
public function meow()
{
echo "meow <br />";
}
}
class Roar implements MeowBehaviour {
public function meow()
{
echo "ROAR! <br />";
}
}
class HouseCat extends Cat
{
function __construct()
{
parent::__construct(new Meow, new EatCatFood);
}
public function sits()
{
echo "if I fits I sits";
}
}
class CatSimulator {
public $cat;
public function __construct()
{
$this->cat = new HouseCat;
$this->cat->performMeowBehaviour();
$this->cat->performEatBehaviour();
}
}
$c = new CatSimulator;
the output from CatSimulator is
meow
meow
I eat cat food.
I cannot figure out why 'meow' is repeated.
In PHP function names are case-insensitive. So here:
class Meow implements MeowBehaviour {
public function meow()
{
echo "meow <br />";
}
}
... meow() is treated as a constructor (PHP 4.x style) - and gets called on $this->cat = new HouseCat; line, echoing the first 'meow'.
You can rename the class, of course, but there's another alternative: add explicit constructor in that class, as here:
class Meow implements MeowBehaviour {
public function __construct() {}
public function meow()
{
echo "meow <br />";
}
}
Now meow method will be called only once.
It's important that __construct() precedes meow(), otherwise E_STRICT error will be raised. You can read more about it here.

OOP PHP - accessing instances and methods

I'm trying to find a solution of my problem, but unsuccessfully. For example:
I have one main class:
class System {
public function loadClass($instance, $name)
{
$this->$instance = new $name;
}
}
And I want, that I simply can load another class into main class called System.
<?php
$system = new System;
$system->loadClass('db', 'database');
?>
It's working.. But I need to access all methods (and instances) of loaded class from any loaded class like this:
<?php
class System {
public function loadClass($instance, $name)
{
$this->$instance = new $name;
}
public function run()
{
echo $this->subA->methodA();
echo $this->subB->methodB();
}
}
class subClassA extends System {
function __construct()
{
echo $this->subB->methodB();
}
public function methodA()
{
return 'okA';
}
}
class subClassB extends System {
function __construct()
{
echo $this->subA->methodA();
}
public function methodB()
{
return 'okB';
}
}
$system = new System;
$system->loadClass('subA', 'subClassA');
$system->loadClass('subB', 'subClassB');
$system->run();
?>
How it is possible without using static methods and instances?

chaining methods what needs to be changed in class

I have the following class and I want to implement chaining methods. I am kinda teaching my ownself so I thought it would be neat to test chaining. However that didnt work. What would I need to do that
echo $animal->name.' says'.$animal->speak()->likes()."<br />";
here is my complete code
<?php
class Animal{
var $name;
function __construct(){
$this->name = $name;
}
}
class Dog extends Animal{
public function speak(){
return "Woof Woof";
}
public function likes(){
return "steaks";
}
}
class Cat extends Animal{
public function speak(){
return "Meow Meow";
}
public function likes(){
return "tuna";
}
}
$animals = array(new Dog('skippy'), new Cat('snowball'));
foreach($animals as $animal){
echo $animal->name.' says'.$animal->speak()->likes()."<br />";
}
?>
<?php
class Animal {
function speak() {
echo "Random Noise!\n";
return $this;
}
}
class Dog extends Animal {
function bark() {
echo "bark!\n";
return $this;
}
}
$a = new Dog();
$a->speak()->bark();
You need to return $this in order to chain your methods.
If you want to chain method, you need to return $this in the method for chaining.
try to write instead of
echo $animal->name.' says'.$animal->speak()->likes()."<br />";
that :
printf('%s says %s %s',#animal->name,$animal->speak()->likes());

php class function wrapper

this is my class:
class toyota extends car {
function drive() {
}
function break() {
}
}
class car {
function pre() {
}
}
Is there any way I can do so that when I run $car->drive(), $car->break() (or any other function in toyota), it would call $car->pre() first before calling the functions in toyota?
Yep. You could use protected and some __call magic:
class toyota extends car {
protected function drive() {
echo "drive\n";
}
protected function dobreak() {
echo "break\n";
}
}
class car {
public function __call($name, $args)
{
if (method_exists($this, $name)) {
$this->pre();
return call_user_func_array(array($this, $name), $args);
}
}
function pre() {
echo "pre\n";
}
}
$car = new toyota();
$car->drive();
$car->dobreak();
http://ideone.com/SGi1g
You could do the following, but I don't think that is what you want.
class toyota extends car {
function drive() {
$this->pre();
}
function break() {
$this->pre();
}
}
class car {
function pre() {
}
}
You may want to look into PHP specific magic methods. http://php.net/manual/en/language.oop5.magic.php
This will better done with the magic methods called __call()
public function __call($name, $arguments)
{
$this -> pre();
return $this -> $name($arguments);
}
What is this method? It overrides the default method call, so that preCall State can be invoked.
Your toyota class
class toyota extends car {
public function __call($name, $arguments)
{
$this -> pre();
return call_user_func_array(array($this, $name), $arguments);
}
function drive() {
}
function break() {
}
}
If you are using PHP5 (>=5.3.2), there is a solution that works with declaring all methods as private. This will enforce method call from single function call:
exec_method()
To run at: http://ideone.com/cvfCXm
The code snippet is here:
<?php
class car {
//method to get class method
public function get_method($method_name) {
$class = new ReflectionClass(get_class($this));
$method = $class->getMethod($method_name);
$method->setAccessible(true);
return $method;
}
public function exec_method($method_name, $arg_args=array()) {
//execute the pre() function before the specified method
$this->pre();
//execute the specified method
$this->get_method($method_name)->invokeArgs($this, $arg_args);
}
public function pre() {
echo 'pre';
echo '<br />';
}
}
class toyota extends car {
private function drive() {
echo 'drive';
echo '<br />';
}
private function brake() {
echo 'brake';
echo '<br />';
}
}
$toyota = new toyota();
$toyota->exec_method('drive');
$toyota->exec_method('brake');
?>
Reference:
Answer to Best practices to test protected methods with PHPUnit [closed]
Just add a constructor, like this...
class toyota extends car {
function __construct() {
$this->pre();
}
function drive() {
echo "drive!";
}
function dobreak() {
echo "break!";
}
}
class car {
function pre() {
echo "Hello!";
}
}
$car = new toyota();
$car->drive();
$car->dobreak();
Classes which have a constructor method call this method on each
newly-created object, so it is suitable for any initialization that
the object may need before it is used.
break is reserved, so you shouldn't use this as a function name.

PHP How to distinguish $this pointer in the inheritance chain?

Please look at the following code snipped
class A
{
function __get($name)
{
if ($name == 'service') {
return new Proxy($this);
}
}
function render()
{
echo 'Rendering A class : ' . $this->service->get('title');
}
protected function resourceFile()
{
return 'A.res';
}
}
class B extends A
{
protected function resourceFile()
{
return 'B.res';
}
function render()
{
parent::render();
echo 'Rendering B class : ' . $this->service->get('title');
}
}
class Proxy
{
private $mSite = null;
public function __construct($site)
{
$this->mSite = $site;
}
public function get($key)
{
// problem here
}
}
// in the main script
$obj = new B();
$obj->render();
Question is: in method 'get' of class 'Proxy', how I extract the corresponding resource file name (resourceFile returns the name) by using only $mSite (object pointer)?
What about:
public function get($key)
{
$file = $this->mSite->resourceFile();
}
But this requires A::resourceFile() to be public otherwise you cannot access the method from outside the object scope - that's what access modifiers have been designed for.
EDIT:
OK - now I think I do understand, what you want to achieve. The following example should demonstrate the desired behavior:
class A
{
private function _method()
{
return 'A';
}
public function render()
{
echo $this->_method();
}
}
class B extends A
{
private function _method()
{
return 'B';
}
public function render()
{
parent::render();
echo $this->_method();
}
}
$b = new B();
$b->render(); // outputs AB
But if you ask me - I think you should think about your design as the solution seems somewhat hacky and hard to understand for someone looking at the code.

Categories