PHP class extend question

guest2013-1

guest
Joined
Aug 22, 2003
Messages
19,800
Reaction score
13
In the below example, I have a extended a class with the same function showName, when it's public or protected, it will return the extended class' showName instead of the parent class'

I was wondering, how would I be able to run the parent class function and then continue with it in the extended class? (my thoughts in red, can't really test this, at work now and this question is burning)

Code:
<?php 
class test { 

    public function __construct() { 
    } 

    public function showName($name) { 
        echo 'my name in test is '.$name; 
    } 
} 

class extendTest extends test { 

    public function __construct() { 
        parent::__construct(); 
    } 

    public function showName($name) { 
[color=red]$name = parent::showName($name);[/color]
        echo 'this function is run in extendTest and '.$name; 
    } 
} 

$test = new extendTest(); 
$test->name("Joe"); 
?>

Will my idea work? Where the parent class' function is called first, processes and returns whatever and then the extended class continues processing it, but when calling the extended class, it will run it's own function instead of it's parents?
 
Also a quick one, do I have to call the class a different name to the one I created primarily?

I'm attempting to write an add-on to current script I have that would be awesome if I could just add a new extended class version (different include in the page) and it will automatically take over all of the instantiation in the code without having to go edit it. Sort of a plug and play type deal.
 
I was reading somewhere that the Child object function will override the Parent object in the event the names are the same. So, PHP might compile the child in such a way to override the parent and lead to an error
 
Will have to try it tonight at home then and see.

I'm basically looking to want to put a new class file in the directory, reference it, and then it automatically taking over everywhere without having to change any instances.

So when I do $test = new Test(); it is actually taking extendTest automatically
 
Will have to try it tonight at home then and see.

I'm basically looking to want to put a new class file in the directory, reference it, and then it automatically taking over everywhere without having to change any instances.

So when I do $test = new Test(); it is actually taking extendTest automatically

http://php.net/manual/en/keyword.parent.php

The example usage they give pretty much exactly answers your question.
 
http://php.net/manual/en/keyword.parent.php

The example usage they give pretty much exactly answers your question.

Okay so I have to change my existing class names and then use the ones currently in there and referenced (ala $b = new B;)

This does mean I have to overwrite a file each time to add new functionality though... which isn't what I want (plan to sell addons to my script, and would like them to build on each other instead of overwriting each time)
 
If I understand what you want???

week 1:
Code:
class A {
  function dog() {
     echo "dog";
}
A a = new A();
a.dog(); //prints "dog"

week 2:
Code:
class B extends A {
 function dog() {
    parent:dog();
    echo "dog2";
}
A a = new A();
a.dog(); //prints "dog" "dog2"

class_alias() perhaps?

Code:
class_alias('A', 'A-orig')
class_alias('B', 'A');

either way that seems wierd.


you wouldnt do it like this IMO. you would rather have some registry Factory.

Code:
factory.registerClass('myAwesomeClass', 'A');
myAwesomeClass = factory.create('myAwsomeClass');
myAwesomeClass.dog() //prints "dog";

factory.registerClass('myAwesomeClass', 'B'); //replaces existing reference to class A
myAwesomeClass = factory.create('myAwsomeClass');
myAwesomeClass.dog() ; //prints "dog" "dog2"
 
Last edited:
If I understand what you want???

week 1:
Code:
class A {
  function dog() {
     echo "dog";
}
A a = new A();
a.dog(); //prints "dog"

week 2:
Code:
class B extends A {
 function dog() {
    parent:dog();
    echo "dog2";
}
A a = new A();
a.dog(); //prints "dog" "dog2"

class_alias() perhaps?

Code:
class_alias('A', 'A-orig')
class_alias('B', 'A');

either way that seems wierd.


you wouldnt do it like this IMO. you would rather have some registry Factory.

Code:
factory.registerClass('myAwesomeClass', 'A');
myAwesomeClass = factory.create('myAwsomeClass');
myAwesomeClass.dog() //prints "dog";

factory.registerClass('myAwesomeClass', 'B'); //replaces existing reference to class A
myAwesomeClass = factory.create('myAwsomeClass');
myAwesomeClass.dog() ; //prints "dog" "dog2"

You understand perfectly, will give this a shot when im home :)
 
class_alias seem to work kind of. you cant use it to "rename" Class A to A-orig and then alias class B to A. It will throw an exception saying something about not being able to redeclare the class name.

Also, even if it worked I'd have an issue with addons

If I extend Class A with Class B and call the function as in OP, it works.

But now I want to extend Class A with B & C, but don't necessarily want Class C dependent on class B, but if both exists, the output of the function that's overridden in Class A, is changed
 
If you extend Class B from Class A and also Class C from Class A, then Class C will not be dependent on Class B!
Also, if you want to use the parent function without changing anything, then don't redeclare the function in the extended class.

eg.
Code:
<?php 
class classA { 
	public function showName($name) { 
		echo 'my name in classA is '.$name; 
		return 'classA';
	} 
} 

class classB extends classA { 
	public function showName($name) { 
		$cn = parent::showName($name);
		echo 'this function is run in classB and '.$cn; 
		return 'classB';
	} 
} 

class classC extends classA { 
	public function showName($name) { 
		$cn = parent::showName($name);
		echo 'this function is run in classC and '.$cn;
		return 'classC';
	} 
} 

$test = new classA(); 
$test->name("Joe"); 

$test2 = new classB(); 
$test2->name("Soap"); 

$test3 = new classC(); 
$test3->name("Bill"); 
?>
 
If you extend Class B from Class A and also Class C from Class A, then Class C will not be dependent on Class B!
Also, if you want to use the parent function without changing anything, then don't redeclare the function in the extended class.

eg.

Yes, I know that, but Class C needs to be able to manipulate the output from Class B (if it's there) automatically.

For example, I have a text engine class. I want to extend it by just adding classes to it without changing the underlying calls.

Like, lets say you have a framework that you develop on, Zend maybe (crap example, but the only framework that comes to mind)

Within your code you use a class: $b = new B(); and call a function, like $b->changeString("test");

Zend then releases an addon you buy, copy it to the addon folder. And instead of having to go and change your code, it works automatically by adding additional functionality into changeString.

Another addon releases, you buy it, copy the file into the addon folder, and it extends the changeString function automatically (takes the output of the parent into the child till there's no more children)

When removing the first addon, the 2nd addon will still work.

Now I've played around with something like this:

PHP:
$addon = array('addon1','addon2'); //etc will maintain somewhere, file that includes the addons perhaps

public function changeString($input) {
...snip 

$callingclass = get_calling_class(); //this is a function outside the class calling debug_backtrace() to find out who the calling class is, not just the current class name or the parent class
		for ($i=0;$i<count($addon);$i++){
if ($addon[$i] != $callingclass) {
			if($addon[$i] != get_class($this)){
				$tmpclass = $addon[$i];
				$tmp = new $tmpclass(); //calls the other class extending the main class as well
				$tmpstr = $tmp->changeString($input);
				$input = $tmpstr; //gets its output and makes it the new input
			}
}
		}

..snip
return $input
}

Still a work in progress but so far it appears to work. Just need to make it generic enough to be re-used by anything I really want
 
Last edited:
The above will pass $input to any addon class defined in the array that is not the calling class or itself, manipulate $input, returns it to the class running it and does its own thing, and pushes it back.

So you could have 50 classes extending the main class, when you run changeString, it will load all the addons and change the string for every class in your addon list

if there's a much better way to do this I'm open ears
 
I know not PHP, but look at how Servlet Filters work. this is exactly what you want, the pattern is identical.

basically

Code:
class Filter {
  function doFilter(SomeArgs, FilterChain filterChain) {
    //do something
    filterChain.doFilter(SomeArgs);
  }
}

class FilterChain {
   private List<Filter> filters;
   
   function doFilter(SomeArgs) {
    //do something
    nextFilter().doFilter(SomeArgs, this);
  }

   function Filter nextFilter() {
    ..//
   }
}
 
Last edited:
look at "Chain of Responsiblity" and "Interceptor" patterns
 
Thing is, I want to avoid changing every single line of code that instantiates my classes just to get something working as we're about to launch


fuuuuuuuuuck
 
I think the little experiment I highlighted in a different post will work for this situation. I only really need to chain a bunch of changes on 1 function in 1 class as it's the main output of the entire web application. Just need to figure out how to properly implement it so that it can take addons automatically and figure out when I'd like to run what, ie, do I want the original class function to run first before processing the rest or do I want to process everything first and then let the original class function do it's thing
 
Top
Sign up to the MyBroadband newsletter
X