class Parent
{
public function __construct($method) {
call_user_func(array($this, $method), 1);
}
}
class Child extends Parent
{
public function __construct($method) {
parent::__construct($method);
}
protected function call_me_on_construct($par) {
echo $par;
}
}
Creating instance of $child = new Child("call_me_on_construct");
I want call_me_on_construct method to be called. The problem is Parent's constructor know nothing about $this. What is better way to do it?
Thank you.
It knows about $this. The only error in your code is that you use reserved keyword parent
class Ancestor
{
public function __construct($method) {
call_user_func(array($this, $method), 1);
}
}
class Child extends Ancestor
{
public function __construct($method) {
parent::__construct($method);
}
protected function call_me_on_construct($par) {
echo $par;
}
}
$c = new child("call_me_on_construct");
Related
cook looks like this:
abstract class Foo
{
pulbic function __construct()
{
if (method_exists($this, 'beforeConstruct')) {
$this->beforeConstruct();
}
if (method_exists($this, 'afterConstruct')) {
$this->afterConstruct();
}
}
}
class Bar extends Foo
{
public function beforeConstruct()
{
echo 'Before Construct.<br>';
}
public function __construct()
{
echo 'Clas Bar has been created.<br>'
}
public function beforeConstruct()
{
echo 'After Construct.<br>';
}
}
$bar = new Bar();
but not working, somebody can help me? how to return results like this:
Before Construct.
Class Bar has been created.
After Construct.
First call the constructor of the parent from the child class constructor , which in turn calls the method beforeConstruct() of the child class and after that it prints the Clas Bar has been created. after that it fires the destructor of your child class.
<?php
abstract class Foo
{
public function __construct()
{
if (method_exists($this, 'beforeConstruct')) {
$this->beforeConstruct();
}
if (method_exists($this, 'afterConstruct')) {
$this->afterConstruct();
}
}
}
class Bar extends Foo
{
public function __construct()
{
parent::__construct();
echo 'Clas Bar has been created.<br>';
}
public function beforeConstruct()
{
echo 'Before Construct.<br>';
}
public function __destruct()
{
echo 'After Construct.<br>';
}
}
$bar = new Bar();
OUTPUT:
Before Construct.
Clas Bar has been created.
After Construct.
I have this Base class:
class Base
{
public $extA;
public $extB;
function __construct()
{
}
public function Init()
{
$this->extA = new ExtA();
$this->extB = new ExtB( $this );
}
public function Test()
{
return 'Base Test Here!';
}
}
class ExtA extending the Base Class
class ExtA extends Base
{
public function Test()
{
return 'ExtA Test Here!';
}
}
class ExtB extending the Base Class too
class ExtB extends Base
{
private $base;
public function __construct( $base )
{
$this->base = $base;
}
public function Test()
{
return 'ExtB calling ExtA->Test()::' . $this->base->extA->Test();
}
}
$base = new Base();
$base->Init();
var_dump( $base->Test() );
var_dump( $base->extA->Test() );
var_dump( $base->extB->Test() );
I try to call the ExtA class Test() function from the ExtB,
both of ExtA and ExtB is exnteding the Base class.
My question is : is this ok, or have a better, faster solution for this?
The extends is necessary too?
Or simply enough like this
class ExtA
{
...
}
class ExtB
{
...
}
Thanks!
This is weird way of OOP.
The Base class should not know anything about its children so we shall go more correct way. Let's implement Decorator pattern:
interface IExt
{
public function test();
}
abstract class ExtDecorator implements IExt
{
protected $instance;
public function __construct(IExt $ext)
{
$this->instance = $ext;
}
}
class ExtA extends ExtDecorator
{
public function test()
{
return 'ExtA::test here and calling... ' . $this->instance->test();
}
}
class ExtB extends ExtDecorator
{
public function test()
{
return 'ExtB::test is here and calling... ' . $this->instance->test();
}
}
class Base implements IExt
{
public function test()
{
return 'Base::test here!';
}
}
class Printer
{
public static function doMagic(IExt $ext)
{
echo $ext->test()."\n";
}
}
Printer::doMagic($base = new Base);
// Base::test here!
Printer::doMagic($extA = new ExtA($base));
// ExtA::test here and calling... Base::test here!
Printer::doMagic(new ExtB($extA));
// ExtB::test is here and calling... ExtA::test here and calling... Base::test here!
You can play further any way you want
I would like to write a generic method that refers to a generic class (but the same method) in php.
class A {
public static function Dox(){
}
}
class B {
public static function Dox(){
}
}
class C{
public static function Include($class){
$result = $class::Dox(); //instead of 2 methods => A::Dox and B::Dox
}
}
I get an error.
any suggestions?
include is a keyword. Rename your method to foo(), bar() or anything that is not a keyword.
e.g.
<?php
class A {
public static function Dox() { return 'A::Dox'; }
}
class B {
public static function Dox() { return 'B::Dox'; }
}
class C {
public static function foo($class) {
$result = $class::Dox();
echo 'result: ', $result, "\n";
}
}
foreach( array('A','B') as $c ) {
C::foo($c);
}
prints
result: A::Dox
result: B::Dox
Does call_user_func work?
class A {
public static function Dox() {
}
}
class B {
public static function Dox() {
}
}
class C {
public static function Include($class) {
$result = call_user_func(array($class, "Dox"));
}
}
Include keyword "spesific keyword".
Try it:
public static function IncludeXXX(){...}
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.
I want to have a static method in a parent class that creates instances of whatever subclass i call this method on.
An example to make this more clear:
class parent {
public static method make_objects($conditions){
for (...){
// here i want to create an instance
// of whatever subclass i am calling make_objects on
// based on certain $conditions
}
}
}
class sub extends parent{
...
}
$objects = sub::make_objects($some_conditions);
As of php 5.3 you can use the static keyword for this
<?php
class A {
public static function newInstance() {
$rv = new static();
return $rv;
}
}
class B extends A { }
class C extends B { }
$o = A::newInstance(); var_dump($o);
$o = B::newInstance(); var_dump($o);
$o = C::newInstance(); var_dump($o);
prints
object(A)#1 (0) {
}
object(B)#2 (0) {
}
object(C)#1 (0) {
}
edit: another (similar) example
<?php
class A {
public static function newInstance() {
$rv = new static();
return $rv;
}
public function __construct() { echo " A::__construct\n"; }
}
class B extends A {
public function __construct() { echo " B::__construct\n"; }
}
class C extends B {
public function __construct() { echo " C::__construct\n"; }
}
$types = array('A', 'B', 'C');
foreach( $types as $t ) {
echo 't=', $t, "\n";
$o = $t::newInstance();
echo ' type of o=', get_class($o), "\n";
}
prints
t=A
A::__construct
type of o=A
t=B
B::__construct
type of o=B
t=C
C::__construct
type of o=C
I think you want something like this:
class parent {
public static function make_object($conditionns) {
if($conditions == "case1") {
return new sub();
}
}
}
class sub extends parent {
}
Now you can create an instance like this:
$instance = parent::make_object("case1");
or
$instance = sub::make_object("case1");
But why would you want all the sub classes to extend the parent? Shouldn't you much rather have a parent for your models (sub classes) and then a factory class, that creates the instances for this models depending on the conditions given?
Umm, wouldn't that be:
class sub extends parent {
public static function make_objects($conditions) {
//sub specific stuff here
//....
}
}
make the parent class an abstract class and make the parent method also an abstract
abstract static class parent {
abstract function make_method() {
// your process
}
}
class child extends parent {
public function __construct() {
parent::make_method();
}
}