chaining methods what needs to be changed in class - php

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());

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.

Can't set PHP Interface function - Why?

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);

How get method from another class method

I have two class es
class Pet {
public $pet = null;
public function setPet(){}
public function getPet(){}
}
and
class B {
public $cat = 'cat';
public $dog = 'bog';
public function cat()
{
$pet = new Pet();
$pet->pet = $this->cat;
}
public function dog()
{
$pet = new Pet();
$pet->pet= $this->dog;
}
}
Can I get this:
$pet = new Pet();
$pet->setPet()->dog();
$pet->getPet(); //dog
I don't believe you can. You could make class B extends Pet. That will allow you to call the functions from the class Pet. Read up on object inheritance, that might help! http://php.net/manual/en/language.oop5.inheritance.php
You can simply extend Class Pet on Class B to call functions from the Pet class. So Class B inherits the functions of Pet.
Class B extends Pet {
// class B functions here...
}
I laughed while I'm writing down my code here..
<?php
class Pet {
public $name;
public function setName($string) {
$this->name = $string;
}
public function getName() {
return $this->name;
}
}
class Dog extends Pet {
public function bark() {
echo "Arf arf!";
}
}
class Cat extends Pet {
public function meow() {
echo "Meoooww~ purrr~";
}
}
$dog = new Dog();
$dog->setName("Jacob");
$dog->bark(); //Arf arf!
echo "Good job, ".$dog->getName()."!"; //Good job, Jacob!
?>
sir you cant call $pet->setPet()->dog() with ->dog() since setPet() is a function and not an object.. just like they said, the right thing to do with your code is to extend it as a super class and declare a Dog Class as the child class..
My variant
class Pet {
public $pet = null;
public function setPet($pet = null)
{
if (is_null($pet)) {
return new B($this);
} else {
$this->pet = $pet;
return $this;
}
}
public function getPet()
{
return $this->pet;
}
}
class B {
protected $pet = null;
protected $cat = 'cat';
protected $dog = 'bog';
public function __construct(Pet $pet)
{
$this->pet = $pet;
}
public function cat()
{
$this->pet->setPet($this->cat);
return $this->pet;
}
public function dog()
{
$this->pet->setPet($this->dog);
return $this->pet;
}
}
$pet = new Pet();
$pet->setPet()->cat();
var_dump($pet->getPet());

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 Class - How can I make a Class know parent value

<?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 =/"
?>

Categories