Call function through self (recursion) doesnt works via SPL auto loader - php

When I call any function without recursion (class is loaded by SPL) - all fine, but if that function is calling itself (recursion) - nothing works.
If I use function without autoloader - all works great. I think that happens because object of class doesn't exist, like with magic methods: you have to use __callStatic, not a __call with abstract using class, I was trying to make this function static oO but nothing works again.
Any ideas how does it possible to use recursion through autoloader?
For example this function from php.net doesn't work in autoloader mode:
function r_implode($glue, $pieces)
{
foreach ($pieces as $r_pieces)
{
if (is_array( $r_pieces ))
{
$r_pieces = r_implode($glue, $r_pieces);
}
else
{
$retVal[] = $r_pieces;
}
}
return implode($glue, $retVal);
}
class load
{
public static function init()
{
return spl_autoload_register(array(__CLASS__, "hook"));
}
public static function quit()
{
return spl_autoload_unregister(array(__CLASS__, "hook"));
}
public static function hook($class)
{
// echo "CLASS IS:$class<br>";
$lnk=PATH . str_replace("_", "/", $class) . ".php";
ob_start();
require $lnk;
ob_end_clean();
return $class;
}
}
So when I add function into a class tools, and call tools::r_implode($a,$b); function doesn't work, but when I insert this function in the same php and call r_implode($a,$b) works.

From your posted info this is not clear. You didn't describe the actual error. But I surmise your problem is actually this:
class tools {
function r_implode($glue, $pieces)
{
$r_pieces = r_implode($glue, $r_pieces);
}
}
You have packed that function into a class, and the autoloader may even find it. But you didn't adapt the recursive call. If you don't use tools::r_implode for the recursion, then PHP won't find that function. Static methods need to be named explicitly (with class:: prefix). Keeping the plain function name there won't work.

Related

Assign functions from another file to a Class

I am trying to add functions to class from a separate file, I wonder if this could be possible!
$mClass = new MyClass();
$mClass->new_Functions[0](10); // Is there a way to have it in this form?
class myClass
{
private $Pvar = 5;
$new_Fcuntions;
function __construct()
{
include('additional.functions.php');
$arr = get_defined_functions();
$this->new_Functions = $arr['user'];
// trying to call the function with parameter 10
call_user_func(array($this, $this->new_Functions[0]), 10);
}
}
[additional.functions.php] file
function operate($y)
{
return $this->Pvar * $y;
}
----- Edited ------- as it wasn't clear!
"additional.functions.php" is a module and there will be multiple modules to be added to the application, and every module could have more than single function and modules could call one another!
additional.functions.php [module file]
function operate($y)
{
return $this->Pvar * $y;
}
function do-more($foo)
{
return $this->operate(20) + $foo;
}
another.functions.php [another module]
function do-another($foo)
{
return $this->do-more(30) - $foo;
}
function add($foo, $bar)
{
return $foo + $bar;
}
appreciate every participation, its been a while since I am trying to maneuver around with it!
Is this possible or should I give up!
It looks to me like you are looking for Traits, which are a new feature as of PHP 5.4.0. Using traits, you can have snippets of code "mixed in" to other classes, a concept known as "horizontal reuse".
If you are not looking for traits, it's possible that you could do what you wanted with Runkit, however I would suggest staying as far away from it as possible, if you are not genuinely interested in PHP internals as well.
In any event, whatever you are trying to do is very interesting
I got it to work with dependency injection. The pvar has to be public or create a __get method to return the private variable. I also used the function name because it seems cleaner to me to use it via name rather than it's position in the list but if you want to keep that then just put $key where you see $value from the line: $this->function_list[$value] = ...
function operate($y, $that)
{
return $that->Pvar * $y;
}
class Example {
public $function_list = array();
private $Pvar = 5;
public function __construct()
{
$list = get_defined_functions();
$that = $this;
foreach ($list['user'] as $key => $value) {
$this->function_list[$value] = function() use ($value, $that) {
print call_user_func_array($value, array_merge(func_get_args(), array($that )));
};
}
}
public function __get($key)
{
if (isSet($this->$key)) {
return $this->$key;
} else {
throw new \Exception('Key "'.$key.'" does not exist');
}
}
}
$Ex = new Example();
$Ex->function_list['operate'](10);
If you want to extend MyClass from your modules (and not to initialize it, like in your example code), than you could do it in a way like this:
<?php
namespace modules\MyModuleA;
class MyClassExtension
{
private $MyObject;
public function __construct(\MyClass $MyObject)
{
$this->MyObject = $MyObject;
}
public function doSomething($anyParameter)
{
return $this->MyObject->doSomethingElse($anyParameter * 5, 42, 'foo');
}
}
And MyClass:
<?php
class MyClass extends \Extensible
{
// some code
}
abstract class Extensible
{
private $extensions = [];
public function extend($extension)
{
$this->extensions[] = $extension;
}
public function __call($methodName, $parameters)
{
foreach ($this->extensions as $Extension) {
if (in_array($methodName, get_class_methods($Extension))
return call_user_func_array([$Extension, $methodName], $parameters);
}
throw new \Exception('Call to undefined method ' . $methodName . '...');
}
public function hasExtension($extensionName)
{
return in_array($this->extensions, $extensionName);
}
}
And put it all together:
<?php
$moduleNames = ['MyModuleA', 'MyModuleB'];
$MyObject = new \MyClass;
foreach ($moduleNames as $moduleName) {
$className = '\\modules\\' . $moduleName . '\\MyClassExtension';
$module = new $className($MyObject);
$MyObject->extend($module);
}
// Now you can call a method, that has been added by MyModuleA:
$MyObject->doSomething(10);
You should add an interface for the extension classes of course...
The problem is: What happens if any code in your application calls a method of $MyObject, that is not there, because the module has not been loaded. You would always have to check if ($MyObject->hasExtension('ModuleA')) { ... }, but, of course, the application shouldn't be aware of any module. So I would not design an application in such a way.
I would suggest to use traits (mix-ins). See PHP reference
If you can have another class in that file instead of file with functions
- the best solution will be Traits
http://php.net/manual/en/language.oop5.traits.php
or using inheritance
If you move that code to class you can avoid a lot of unnecessary code. I mean:
include('additional.functions.php');
$arr = get_defined_functions();
$this->new_Functions = $arr['user'];
// trying to call the function with parameter 10
call_user_func(array($this, $this->new_Functions[0]), 10);
It'll be e.g.:
class myClass extends MyBaseClassWithMyAwesomeFunctions
{
private $Pvar = 5;
}
Maybe this approach helps you:
In the files with the additional functions, don't define named functions, but return a closure, that expects (at least) the object (instance of MyClass) as parameter:
<?php
// additional.functions.php
return function ($myObject) {
$Object->multiplyPvar($myObject->getTheNumber());
$Object->doSomethingElse(42, 'foo');
};
The client, that builds MyClass collects those functions from the files into the array:
<?php
$files = [
'/path/to/my/additional.functions1.php',
'/path/to/my/additional.functions2.php'
];
$initFunctions = [];
foreach ($files as $path)
$initFunctions[] = include $path;
$MyObject = new \MyClass($initFunctions);
The constructor then calls those functions:
<?php
class MyClass
{
public function __construct(array $additionalInitFunctions)
{
foreach ($additionalInitFunctions as $additionalInitFunction)
$additionalInitializerFunction($this); // you can also add parameters of course
}
}
This way the class keeps very well testable as well as the function files. Maybe this could help you in any way. You should never ever think about modifying the internal (private) state of an object directly from any code from outside of the class. This is not testable! Think about writing tests before you implement your code (called "test driven development"). You will see, it is not possible to test a class, if you allow any code outside of that class to modify the internal (private) state of the class instance. And you don't want to have this. If you change some internal implementation detail in your class without breaking the unit test of that class, you will anyways probably break some code in any of your additional.functions.php files and no test will tell you: "Hey: you've broken something right now".

How can I call a custom function that is part of a class in PHP (wordpress do_action style)?

Wordpress uses hooks and actions for extensibility. A plugin might look something like this:
class myLightbox
{
function __construct()
{
add_action('wp_footer',array($this,'my_footer'));
}
function my_footer()
{
echo '<script src="http://external-site.com/lightbox.js" ></script>';
}
}
If I run that code outside of Wordpress, I'd like the add_action to work - even if it just calls the function immediately.
I read these:
call_user_func(array($this, $method), $par) from parent's constructor?**
Enqueue a function (like wordpress add_action)
The second one is fairly close to what I'd like to do, but I don't think it was designed to work with functions that are part of a class.
I tried using call_user_function but I'm not sure how to give it the array($this,'my_footer') stuff:
function add_action($whenToCall,$contextAndFunction=array())
{
call_user_func($contextAndFunction);
}
I also tried this, but as you can tell my OOP isn't great so I'm struggling:
function add_action($whenToCall,$contextAndFunction=array())
{
$function = array_pop($contextAndFunction);
$context = array_pop($contextAndFunction);
$context->$function();
}
Failed test using minitech's suggestion:
class myLightbox
{
function __construct()
{
add_action('wp_footer',array($this,'my_footer'));
}
function my_footer()
{
echo '<script src="http://external-site.com/lightbox.js" ></script>';
}
}
function add_action($whenToCall,$contextAndFunction=array())
{
$contextAndFunction();
}
$myLightbox = new myLightbox();
Produces:
Fatal error: Function name must be a string
If you're using PHP 5.4, it's already a callable:
$contextAndFunction();
Here's a demo.
Otherwise, call_user_func will work as-is.
call_user_func($contextAndFunction);
And there's a demo.

Make a script pluginable

I am working on a script, and I need to make it pluginable. Now the syntax I have come with and which should work for me, is to make it use classes. For example, in order to create a new plugin that would be run when a certain point (hook) is reached, you would declare a new class. What I am not sure is how would the hook be specified in that syntax, so I am looking for suggestions.
Syntax example:
<?php
class ScriptPlugin
{
function runPlugin() {} // would be run when the time has to come to execute this plugin
}
?>
Also, if that syntax is not going to work, it would be great if you guys could give me a good syntax example.
There is the Observer Pattern which comes to mind. Plugins will register themselves and will get notifications when the hook is invoked.
Another thing that comes to mind are callbacks in PHP. And there was a similar question already with an answer that came to mind. It shows hooks based on callbacks.
The Observer Pattern runs a bit short because with hooks you often want to provide things like arguments and a return value. The linked answer which uses callbacks does not have this either, so I wrote a little Hooks example class that provides named hooks/events to registered callbacks, and a way to register your own classes, e.g. a plugin.
The idea is pretty basic:
A hook has a name and zero or more callbacks attached.
All hooks are managed in a Hooks class.
The main code invokes hooks by calling a function on the Hooks object.
Plugins (and other classes) can register their own callbacks, which is done with the help of the Registerable interface.
Some example code with one plugin and two hooks:
<?php
Namespace Addon;
class Hooks
{
private $hooks = array();
private $arguments;
private $name;
private $return;
public function __call($name, array $arguments)
{
$name = (string) $name;
$this->name = $name;
$this->arguments = $arguments;
$this->return = NULL;
foreach($this->getHooks($name) as $hook)
{
$this->return = call_user_func($hook, $this);
}
return $this->return;
}
public function getHooks($name)
{
return isset($this->hooks[$name]) ? $this->hooks[$name] : array();
}
public function getArguments()
{
return $this->arguments;
}
public function getName()
{
return $this->name;
}
public function getReturn()
{
return $this->return;
}
public function setReturn($return)
{
$this->return = $return;
}
public function attach($name, $callback)
{
$this->hooks[(string) $name][] = $callback;
}
public function register(Registerable $plugin)
{
$plugin->register($this);
}
}
interface Registerable
{
public function register(Hooks $hooks);
}
class MyPlugin implements Registerable
{
public function register(Hooks $hooks)
{
$hooks->attach('postPublished', array($this, 'postPublished'));
$hooks->attach('postDisplayFilter', array($this, 'filterToUpper'));
}
public function postPublished()
{
echo "MyPlugin: postPublished.\n";
}
public function filterToUpper(Hooks $context)
{
list($post) = $context->getArguments();
return strtoupper($post);
}
}
$hooks = new Hooks();
$plugin = new MyPlugin();
$hooks->register($plugin);
$hooks->postPublished();
echo $hooks->postDisplayFilter("Some post text\n");
I've done it this way to prevent that each Plugin must have a concrete base class only because it wants to make use of hooks. Additionally everything can register hooks, the only thing needed is a callback. For example an anonymous function:
$hooks->attach('hookName', function() {echo "Hook was called\n";});
You can however create yourself a plugin base class, that for example implements the register function and will automatically register functions that have a certain docblock tag or the name of a function
class MyNewPlugin extends PluginSuper
{
/**
* #hook postPublished
*/
public function justAnotherFunction() {}
public hookPostPublished() {}
}
The superclass can make use of Reflection to add the hooks on runtime. However reflection can slow things down and might make things harder to debug.
Let's say a plugin is like :
class NewsPlugin extends Plugin
{
function onCreate($title)
{
# Do some stuff
}
}
Then when you create a news you can just call onCreate on all plugins registered.
I would make a base abstract class with functions for all the hooks that could possibly be called.
abstract class Plugin {
abstract function yourHook();
}
All plugin classes should inherit this base class, and will override those base functions with their own.
class SomePlugin extends Plugin {
function yourHook() {
echo 'yourHook() Called!';
}
}
Now when your program runs, you need to find all of those plugin files to include, and somehow put them into an array, such as $plugins. See this article: https://stackoverflow.com/a/599694/362536
foreach (glob("classes/*.php") as $filename)
{
include $filename;
}
(From Karsten)
Define a function accessible from everything, such as registerPlugin():
function registerPlugin($classname) {
$plugins[] = new $classname();
}
Make the top line of each plugin file like this (prior to the class):
registerPlugin('SomePlugin');
If you do this, you'll have an array in $plugins with instances of each plugin. At the appropriate time, you can do something like this:
foreach ($plugins as $plugin) {
$plugin->yourHook();
}
As an alternative, it may be more appropriate to use interfaces in your case, instead. You should decide which method is best for your application.

php namespaces & autoload

I've read some posts about namespaces and autoload in php 5.3+, but still haven't succeeded in creating one working :x maybe some of you have an idea of what's going wrong about my code ?
Thank you previously.
Autoloader.php class
<?php
namespace my;
class AutoLoader {
private $aExt;
private $sPath;
protected static $instance;
public static function getInstance() {
if(!self::$instance instanceof self ) {
self::$instance = new self();
}
return self::$instance;
}
function __construct($sPath = __DIR__, $exts = 'php') {
// define path and extensions to include
$this->setPath($sPath);
$this->setExtensions($exts);
}
public function getPath() {
return $this->sPath;
}
public function setPath($path){
$this->sPath = $path;
}
public function removePath() {
unset ($this->sPath);
}
public function addExtension($ext) {
// prepends period to extension if none found
$this->aExt[$ext] = (substr($ext, 0, 1) !== '.') ? '.'.$ext : $ext;
}
public function removeExtension($ext) {
unset ($this->aExt[$ext]);
}
public function getExtensions() {
return $this->aExt;
}
public function setExtensions($extensions) {
// convert
if (is_string($extensions)) {
$extensions = array($extensions);
}
// add
foreach($extensions as $ext) {
$this->addExtension($ext);
}
}
public function register() {
set_include_path($this->sPath);
// comma-delimited list of valid source-file extensions
spl_autoload_extensions(implode(',',$this->aExt));
// default behavior without callback
spl_autoload_register(array($this, 'autoload'));
}
public function autoload($sClassName) {
include_once($sClassName.'.php');
return;
}
}
$autoloader = new AutoLoader();
$autoloader->register();
?>
MyClass.php the class i am trying to load dinamically
<?php
namespace my\tools;
class MyClass {
function __construct() {}
function __destruct() {}
function test() {
echo 'ok';
}
}
?>
index.php the caller
<?php
include_once('../Libraries/php/my/AutoLoader.php');
new my\tools\MyClass();
?>
and finally the class structures on my disk
Libraries
|_php
|_my
| |_Autoloader.php
|
|_MyClass.php
That's a tad bit over-engineered, my friend.
You might want to take a look at simply using PSR-0 (PRS-0 is now depreciated, PSR-4 is the new one), an autoloader specification from a large number of PHP projects, like phpBB, Joomla, CakePHP, Zend Framework and lots more. It's built with namespaces in mind, but works well with or without them.
The advantage of PSR-0 (or PSR-4) is that it leads to a clean, simple, obvious directory structure that an increasing number of projects are supporting. This means using one autoloader instead of a single autoloader for every single set of code.
spl_autoload_register() expects a valid callback. You give ... something ^^ But not a callback. A callback is
// a closure
$cb = function ($classname) { /* load class */ }
// object method
$cb = array($object, 'methodName');
// static class method
$cb = array('className', 'methodName');
// function
$cb = 'functionName';
See manual: spl_autoload_register() for further information and examples.
After searching a little on PHP.net website, the solution were really simple :/
In fact php autoload function MUST be on root namespace /, mine was on first level of my package (my/), when i moved the class to root namespace everything worked fine.

Redefine Class Methods or Class

Is there any way to redefine a class or some of its methods without using typical inheritance? For example:
class third_party_library {
function buggy_function() {
return 'bad result';
}
function other_functions(){
return 'blah';
}
}
What can I do to replace buggy_function()? Obviously this is what I would like to do
class third_party_library redefines third_party_library{
function buggy_function() {
return 'good result';
}
function other_functions(){
return 'blah';
}
}
This is my exact dilemma: I updated a third party library that breaks my code. I don't want to modify the library directly, as future updates could break the code again. I'm looking for a seamless way to replace the class method.
I've found this library that says it can do it, but I'm wary as it's 4 years old.
EDIT:
I should have clarified that I cannot rename the class from third_party_library to magical_third_party_library or anything else because of framework limitations.
For my purposes, would it be possible to just add a function to the class? I think you can do this in C# with something called a "partial class."
It's called monkey patching. But, PHP doesn't have native support for it.
Though, as others have also pointed out, the runkit library is available for adding support to the language and is the successor to classkit. And, though it seemed to have been abandoned by its creator (having stated that it wasn't compatible with PHP 5.2 and later), the project does now appear to have a new home and maintainer.
I still can't say I'm a fan of its approach. Making modifications by evaluating strings of code has always seemed to me to be potentially hazardous and difficult to debug.
Still, runkit_method_redefine appears to be what you're looking for, and an example of its use can be found in /tests/runkit_method_redefine.phpt in the repository:
runkit_method_redefine('third_party_library', 'buggy_function', '',
'return \'good result\''
);
runkit seems like a good solution but its not enabled by default and parts of it are still experimental. So I hacked together a small class which replaces function definitions in a class file. Example usage:
class Patch {
private $_code;
public function __construct($include_file = null) {
if ( $include_file ) {
$this->includeCode($include_file);
}
}
public function setCode($code) {
$this->_code = $code;
}
public function includeCode($path) {
$fp = fopen($path,'r');
$contents = fread($fp, filesize($path));
$contents = str_replace('<?php','',$contents);
$contents = str_replace('?>','',$contents);
fclose($fp);
$this->setCode($contents);
}
function redefineFunction($new_function) {
preg_match('/function (.+)\(/', $new_function, $aryMatches);
$func_name = trim($aryMatches[1]);
if ( preg_match('/((private|protected|public) function '.$func_name.'[\w\W\n]+?)(private|protected|public)/s', $this->_code, $aryMatches) ) {
$search_code = $aryMatches[1];
$new_code = str_replace($search_code, $new_function."\n\n", $this->_code);
$this->setCode($new_code);
return true;
} else {
return false;
}
}
function getCode() {
return $this->_code;
}
}
Then include the class to be modified and redefine its methods:
$objPatch = new Patch('path_to_class_file.php');
$objPatch->redefineFunction("
protected function foo(\$arg1, \$arg2)
{
return \$arg1+\$arg2;
}");
Then eval the new code:
eval($objPatch->getCode());
A little crude but it works!
For people that are still looking for this answer.
You should use extends in combination with namespaces.
like this:
namespace MyCustomName;
class third_party_library extends \third_party_library {
function buggy_function() {
return 'good result';
}
function other_functions(){
return 'blah';
}
}
Then to use it do like this:
use MyCustomName\third_party_library;
$test = new third_party_library();
$test->buggy_function();
//or static.
third_party_library::other_functions();
For the sake of completeness - monkey patching is available in PHP through runkit. For details, see runkit_method_redefine().
How about wrapping it in another class like
class Wrapper {
private $third_party_library;
function __construct() { $this->third_party_library = new Third_party_library(); }
function __call($method, $args) {
return call_user_func_array(array($this->third_party_library, $method), $args);
}
}
Yes, it's called extend:
<?php
class sd_third_party_library extends third_party_library
{
function buggy_function() {
return 'good result';
}
function other_functions(){
return 'blah';
}
}
I prefixed with "sd". ;-)
Keep in mind that when you extend a class to override methods, the method's signature has to match the original. So for example if the original said buggy_function($foo, $bar), it has to match the parameters in the class extending it.
PHP is pretty verbose about it.
Zend Studio and PDT (eclipse based ide) have some built in refractoring tools. But there are no built in methods to do this.
Also you wouldn't want to have bad code in your system at all. Since it could be called upon by mistake.
I've modified the code from the answer by #JPhilly and made it possible to rename a the patched class to avoid errors.
Also, I've changed the regex that identifies the about-to-be-replaced function to fit cases where the replaced function doesn't have any class access modifiers in front of its name
Hope it helps.
class Patch {
private $_code;
public function __construct($include_file = null) {
if ( $include_file ) {
$this->includeCode($include_file);
}
}
public function setCode($code) {
$this->_code = $code;
}
public function includeCode($path) {
$fp = fopen($path,'r');
$contents = fread($fp, filesize($path));
$contents = str_replace('<?php','',$contents);
$contents = str_replace('?>','',$contents);
fclose($fp);
$this->setCode($contents);
}
function redefineFunction($new_function) {
preg_match('/function ([^\(]*)\(/', $new_function, $aryMatches);
$func_name = trim($aryMatches[1]);
// capture the function with its body and replace it with the new function
if ( preg_match('/((private|protected|public)?\s?function ' . $func_name .'[\w\W\n]+?)(private|protected|public|function|class)/s', $this->_code, $aryMatches) ) {
$search_code = $aryMatches[1];
$new_code = str_replace($search_code, $new_function."\n\n", $this->_code);
$this->setCode($new_code);
return true;
} else {
return false;
}
}
function renameClass($old_name, $new_name) {
$new_code = str_replace("class $old_name ", "class $new_name ", $this->_code);
$this->setCode($new_code);
}
function getCode() {
return $this->_code;
}
}
This is how I've used it to patch a Wordpress plugin:
$objPatch = new Patch(ABSPATH . 'wp-content/plugins/a-plugin/code.php');
$objPatch->renameClass("Patched_AClass", "Patched_Patched_AClass"); // just to avoid class redefinition
$objPatch->redefineFunction("
function default_initialize() {
echo 'my patched function';
}");
eval($objPatch->getCode());
$result = new Patched_AClass();
If the library is explicitly creating the bad class and not using a locater or dependency system you are out of luck. There is no way to override a method on another class unless you subclass.
The solution might be to create a patch file that fixes the library, so you can upgrade the library and re-apply the patch to fix that specific method.
You might be able to do this with runkit. http://php.net/runkit
You can make a copy of the library class, with everything the same except the class name. Then override that renamed class.
It's not perfect, but it does improve the visibility of the extending class's changes. If you fetch the library with something like Composer, you'll have to commit the copy to source control and update it when you update the library.
In my case it was an old version of https://github.com/bshaffer/oauth2-server-php. I modified the library's autoloader to fetch my class file instead. My class file took on the original name and extended a copied version of one of the files.
Since you always have access to the base code in PHP, redefine the main class functions you want to override as follows, this should leave your interfaces intact:
class third_party_library {
public static $buggy_function;
public static $ranOnce=false;
public function __construct(){
if(!self::$ranOnce){
self::$buggy_function = function(){ return 'bad result'; };
self::$ranOnce=true;
}
.
.
.
}
function buggy_function() {
return self::$buggy_function();
}
}
You may for some reason use a private variable but then you will only be able to access the function by extending the class or logic inside the class. Similarly it's possible you'd want to have different objects of the same class have different functions. If so, do't use static, but usually you want it to be static so you don't duplicate the memory use for each object made. The 'ranOnce' code just makes sure you only need to initialize it once for the class, not for every $myObject = new third_party_library()
Now, later on in your code or another class - whenever the logic hits a point where you need to override the function - simply do as follows:
$backup['buggy_function'] = third_party_library::$buggy_function;
third_party_library::$buggy_function = function(){
//do stuff
return $great_calculation;
}
.
.
. //do other stuff that needs the override
. //when finished, restore the original function
.
third_party_library::$buggy_function=$backup['buggy_function'];
As a side note, if you do all your class functions this way and use a string-based key/value store like public static $functions['function_name'] = function(...){...}; this can be useful for reflection. Not as much in PHP as other languages though because you can already grab the class and function names, but you can save some processing and future users of your class can use overrides in PHP. It is however, one extra level of indirection, so I would avoid using it on primitive classes wherever possible.
There's alway extending the class with a new, proper, method and calling that class instead of the buggy one.
class my_better_class Extends some_buggy_class {
function non_buggy_function() {
return 'good result';
}
}
(Sorry for the crappy formatting)

Categories