Difference between revisions of "PHP OO problem"

From Organic Design wiki
m
(Change source-code blocks to standard format)
 
(5 intermediate revisions by one other user not shown)
Line 1: Line 1:
 
Take the following example class ''Foo'' which defines a static method called ''X'' that statically calls another of it's method's called ''Y'' using ''self::Y()'' as follows.
 
Take the following example class ''Foo'' which defines a static method called ''X'' that statically calls another of it's method's called ''Y'' using ''self::Y()'' as follows.
{{code|<php>
+
<source lang="php">
 
class Foo {
 
class Foo {
  
Line 12: Line 12:
  
 
}
 
}
</php>}}
+
</source>
  
  
 
Now lets say that ''Foo'' is part of a core library that we don't have commit access to and we want to make a modified version of the functionality via a sub-class of ''Foo'' called ''Bar'' which overrides the ''Y'' method as follows.
 
Now lets say that ''Foo'' is part of a core library that we don't have commit access to and we want to make a modified version of the functionality via a sub-class of ''Foo'' called ''Bar'' which overrides the ''Y'' method as follows.
{{code|<php>
+
<source lang="php">
 
class Bar extends Foo {
 
class Bar extends Foo {
  
Line 24: Line 24:
  
 
}
 
}
</php>}}
+
</source>
  
 +
== The problem ==
 +
The ''Y'' method is only ever called via the ''self::Y'' statement in the ''X'' method, so when we call ''Bar::X()'' it's actually ''Foo::Y'' that executes, because ''X'' only ever executes within the context of ''Foo'' since we haven't overridden the ''X'' method with a definition in the ''Bar'' class.
  
But the ''Y'' method is only ever called via the ''self::Y'' statement in the ''X'' method, so when we call ''Bar::X()'' it's actually ''Foo::Y'' that executes, because ''X'' only ever executes within the context of ''Foo'' since we haven't overridden the ''X'' method with a definition in the ''Bar'' class.
+
== The question ==
 +
Is there a way to define a ''Bar::X'' method that calls ''Foo:X'' while maintaining the context of ''Bar'' (i.e. the value of ''self'' is "Bar" during execution of ''Foo::X''?
  
'''So the question is:'''
+
== Notes ==
 
+
This is a known limitation of PHP and they've tried to resolve it with [http://www.php.net/manual/en/language.oop5.late-static-bindings.php Late Static Bindings], but unfortunately this doesn't work for me as the solution would require changing the call in ''Foo:X'' from ''self::Y()'' to ''static::Y()'', but we don't have access to the ''Foo'' class.
:is there a way to define a ''Bar::X'' method that calls ''Foo:X'' while maintaining the context of ''Bar'' (i.e. the value of ''self'' is "Bar" during execution of ''Foo::X''?
 

Latest revision as of 18:11, 22 May 2015

Take the following example class Foo which defines a static method called X that statically calls another of it's method's called Y using self::Y() as follows.

class Foo {

	public static function X() {
		self::Y();
	}

	public static function Y() {
		echo( "This is Foo::Y" );
	}

}


Now lets say that Foo is part of a core library that we don't have commit access to and we want to make a modified version of the functionality via a sub-class of Foo called Bar which overrides the Y method as follows.

class Bar extends Foo {

	public static function Y() {
		echo( "This is Bar::Y" );
	}

}

The problem

The Y method is only ever called via the self::Y statement in the X method, so when we call Bar::X() it's actually Foo::Y that executes, because X only ever executes within the context of Foo since we haven't overridden the X method with a definition in the Bar class.

The question

Is there a way to define a Bar::X method that calls Foo:X while maintaining the context of Bar (i.e. the value of self is "Bar" during execution of Foo::X?

Notes

This is a known limitation of PHP and they've tried to resolve it with Late Static Bindings, but unfortunately this doesn't work for me as the solution would require changing the call in Foo:X from self::Y() to static::Y(), but we don't have access to the Foo class.