I know this question seems hacky and weird, but is there a way to remove a function at runtime in PHP?
I have a recursive function declared in a \"if\" block and wan
There may be another solution for replacing functions by changing usage of them like this ;
function function1(){
echo "1";
}
function function2(){
echo "2";
}
if(FUNCTION_CHOOSER_CONDITION) $the_function = "function2";
else $the_function="function1";
$the_function(); // displays 2 if condition is TRUE;
Maybe this not for you in this situation as you wanted to destroy the function but i though this is right place to talk about replacement of functions.
No. But removing a function definition is silly.
Either you're defining the function differently in an else
block and need the definition to change based on program state, effectively making your project closer and closer to impossible to debug, or code that calls that function will crash and burn if it didn't happen to get defined at runtime.
You should put this function in a class:
class foo {
public function bar() {
if( /* some condition */ ) {
$this->baz();
} else {
$this->bazzer();
}
}
private function baz() {
/* if the if condition was met */
}
private function bazzer() {
/* if the if condition failed */
}
}
or, if you only want the condition tested once,
class foo {
private $bar_function = NULL;
public function __construct() {
if( /* some condition */ ) {
$this->bar_function = baz;
} else {
$this->bar_function = bazzer;
}
}
public function bar() {
$this->$bar_function();
}
...
I don't know what you are trying to do or why you want to remove a function definition but hopefully this can help you do it in a cleaner way.
Simple answer: no.
However, you can try placing the function inside a namespace, a class or even within another function - but I think that's not what you're looking for.
One other option you have is to use debug_backtrace()
inside the said function to check what file / line / etc... is calling it - it's hackish I know, but so is runkit_function_remove()
.
Edit - Too bad you don't run PHP 5.3+, otherwise you could just do:
if (get_magic_quotes_gpc())
{
$_GET = json_decode(stripslashes(json_encode($_GET, JSON_HEX_APOS)), true);
$_POST = json_decode(stripslashes(json_encode($_POST, JSON_HEX_APOS)), true);
$_COOKIE = json_decode(stripslashes(json_encode($_COOKIE, JSON_HEX_APOS)), true);
$_REQUEST = json_decode(stripslashes(json_encode($_REQUEST, JSON_HEX_APOS)), true);
}
For older versions of PHP you still have this option:
if (get_magic_quotes_gpc()) {
$process = array(&$_GET, &$_POST, &$_COOKIE, &$_REQUEST);
while (list($key, $val) = each($process)) {
foreach ($val as $k => $v) {
unset($process[$key][$k]);
if (is_array($v)) {
$process[$key][stripslashes($k)] = $v;
$process[] = &$process[$key][stripslashes($k)];
} else {
$process[$key][stripslashes($k)] = stripslashes($v);
}
}
}
unset($process);
}
No functions there, and the code is not that long. =)
I too see very little reason to let a function "live" or "not live" depending on a condition, but to answer the question, it's sort of possible using anonymous functions. @Gordon already outlined how it's done. Starting with PHP 5.3.0, you can also use anonymous functions as follows. (There is no functional difference to the create_function()
approach.)
if (function_exists('get_magic_quotes_gpc') && @get_magic_quotes_gpc())
{
$stripslashes_deep = function($value)
{
return is_array($value) ? array_map('stripslashes_deep', $value) : stripslashes($value);
}
$_POST = array_map($stripslashes_deep, $_POST);
$_GET = array_map($stripslashes_deep, $_GET);
$_COOKIE = array_map($stripslashes_deep, $_COOKIE);
$_REQUEST = array_map($stripslashes_deep, $_REQUEST);
unset ($stripslashes_deep);
}
Initial function definition looks like:
// includes/std_functions.php
if (! function_exists('the_function')) {
function the_function() {
global $thefunction;
return call_user_func_array($thefunction, func_get_args());
}
$GLOBALS['thefunction'] = function() {
echo 'foo';
};
}
if you have a test condition that allows you to rewrite code:
// somewhere in your code
if (<replacethefunctioncondition>) {
$GLOBALS['thefunction'] = function() {
echo 'bar';
};
}
if you are overloading in another include that will be loaded before or after the original file:
// includes/custom_functions.php
if (! function_exists('the_function')) {
function the_function() {
global $thefunction;
return call_user_func_array($thefunction, func_get_args());
}
}
$GLOBALS['thefunction'] = function() {
echo 'bar';
};
It's impossible without runkit_function_remove. Runkit is the extension intended to do things like this.
Are you sure that the function lives after the if-block is completed? I would have thought that if it were defined within the if-block, that it would become inaccessible afterward.