Removing an element from an array

The problem

While re-building and refactoring my Functions adapter class I run into the need to remove an element from an array and have been using, at first, this code.
The method below comes from a class responsible for the decoration, in test environment, of the Functions class and this method in particular will remove a function that was added to the class for mocking purposes.

public static function removeFunction($f){
   $addedFunctionsKeys = array_keys(self::$addedFunctions);
   if (method_exists(self::$targetClassName, $f)) {
      runkit_method_remove(self::$targetClassName, $f);
      unset(self::$addedFunctions[$f]);
   }
}

What seems like a trivial task is not and the following test, in the matching testing class, kept failing

 public function testRemoveFunction(){
    FunctionsDecorator::addFunction('foo');
    $countBefore = count(get_class_methods(FunctionsDecorator::$targetClassName));
    $addedFunctionsCountBefore = count(FunctionsDecorator::$addedFunctions);
    FunctionsDecorator::removeFunction('foo');
    $countAfter = count(get_class_methods(FunctionsDecorator::$targetClassName));
    $addedFunctionsCountAfter = count(FunctionsDecorator::$addedFunctions);
    $this->assertTrue($countAfter == ($countBefore -1));
    $this->assertTrue($addedFunctionsCountAfter == ($addedFunctionsCountBefore -1));
 }

The gotcha or “read the manual”

As many times before the answer did lay in PHP manual, more precisely where it says:

If a globalized variable is unset() inside of a function, only the local variable is destroyed. The variable in the calling environment will retain the same value as before unset() was called.

If a static variable is unset() inside of a function, unset() destroys the variable only in the context of the rest of a function. Following calls will restore the previous value of a variable.  

So much examples and working explanations I found on the web did report using unset as working because the functions were unsetting values in arrays and using them in those same functions. Since I’m unsetting in removeFunction and using the presumably modified array in another function, the testRemoveFunction test one, it did not work.

array_diff

The function, baked right into PHP,

Returns an array containing all the entries from array1 that are not present in any of the other arrays.

And so I modified the function using it

public static function removeFunction($f){
   $addedFunctionsKeys = array_keys(self::$addedFunctions);
   if (method_exists(self::$targetClassName, $f)) {
      runkit_method_remove(self::$targetClassName, $f);
      self::$addedFunctions = array_diff(self::$addedFunctions, array($f));
   }
}

2 thoughts on “Removing an element from an array

  1. Pingback: mexicana bottes

I appreciate your input