Viewed   77 times

If I use array_walk inside a class function to call another function of the same class

class user
{
   public function getUserFields($userIdsArray,$fieldsArray)
   {

     if((isNonEmptyArray($userIdsArray)) && (isNonEmptyArray($fieldsArray)))
     {
         array_walk($fieldsArray, 'test_print');
     }
   }


  private function test_print($item, $key)
  {
         //replace the $item if it matches something
  }

}

It gives me the following error -

Warning: array_walk() [function.array-walk]: Unable to call test_print() - function does not exist in ...

So, how do I specify $this->test_print() while using array_walk()?

 Answers

2

If you want to specify a class method as a callback, you need to specify the object it belongs to:

array_walk($fieldsArray, array($this, 'test_print'));

From the manual:

A method of an instantiated object is passed as an array containing an object at index 0 and the method name at index 1.

Sunday, August 21, 2022
3

not pretty but heres how I would do it with a nested foreach;

$aStartingArray = array();
$aStartingArray[] = array('source'=>'ABC', 'target' => 'DEF', 'total_volume' => 10); 
$aStartingArray[] = array('source'=>'ABC', 'target' => 'GHI', 'total_volume' => 5); 
$aStartingArray[] = array('source'=>'ABC', 'target' => 'DEF', 'total_volume' => 5); 


$aSortedArray = array();

foreach ($aStartingArray as $aArray) {

    $bSet = false;

    foreach ($aSortedArray as $iPos => $aTempSortedArray) {

        if(
            $aTempSortedArray['source'] == $aArray['source'] && 
            $aTempSortedArray['target'] == $aArray['target']){

            $aSortedArray[$iPos]['total_volume'] += $aArray['total_volume'];

            $bSet = true;
        }

    }

    if(!$bSet) {

        $aSortedArray[] = array(
            'source' => $aArray['source'], 
            'target' => $aArray['target'], 
            'total_volume' => $aArray['total_volume']
            );
    }
}


var_dump($aSortedArray);
Thursday, September 29, 2022
 
3

You would return $missing_variable in a few places. See below. (This isn't the only way to do it, mind you)

http://codepad.org/tf08Vgdx

<?
class class_2{
    public function __construct($callback){
        echo "Hello World - ";
        $missing = $callback();
        $this->missing = $missing;
    }
}
class class_1{
    public function function_1(){
        function callback_function(){
            echo "A Callback. ";
            $missing_variable = "Where Did I Go?";
            return $missing_variable;
        }
        $class2 = new class_2('callback_function');
        return $class2->missing;
    }
    public function __construct(){
        $this->missing = $this->function_1();
    }
}

$class = new class_1();

echo $class->missing;
Wednesday, September 28, 2022
 
1

Check the callable manual to see all the different ways to pass a function as a callback. I copied that manual here and added some examples of each approach based on your scenario.

Callable


  • A PHP function is passed by its name as a string. Any built-in or user-defined function can be used, except language constructs such as: array(), echo, empty(), eval(), exit(), isset(), list(), print or unset().
  // Not applicable in your scenario
  $this->processSomething('some_global_php_function');

  • A method of an instantiated object is passed as an array containing an object at index 0 and the method name at index 1.
  // Only from inside the same class
  $this->processSomething([$this, 'myCallback']);
  $this->processSomething([$this, 'myStaticCallback']);
  // From either inside or outside the same class
  $myObject->processSomething([new MyClass(), 'myCallback']);
  $myObject->processSomething([new MyClass(), 'myStaticCallback']);

  • Static class methods can also be passed without instantiating an object of that class by passing the class name instead of an object at index 0.
  // Only from inside the same class
  $this->processSomething([__CLASS__, 'myStaticCallback']);
  // From either inside or outside the same class
  $myObject->processSomething(['NamespaceMyClass', 'myStaticCallback']);
  $myObject->processSomething(['NamespaceMyClass::myStaticCallback']); // PHP 5.2.3+
  $myObject->processSomething([MyClass::class, 'myStaticCallback']); // PHP 5.5.0+

  • Apart from common user-defined function, anonymous functions can also be passed to a callback parameter.
  // Not applicable in your scenario unless you modify the structure
  $this->processSomething(function() {
      // process something directly here...
  });

Friday, September 23, 2022
 
bt101
 
4

No, you cannot, because the class definition has not yet completed running so the class name doesn't exist yet in the current namespace.

You can use the function object directly:

class C:    
    @staticmethod
    def default_concrete_strategy():
        print("default")

    @staticmethod
    def other_concrete_strategy():
        print("other")

    def __init__(self, strategy=default_concrete_strategy.__func__):
        self.strategy = strategy

C doesn't exist yet when the methods are being defined, so you refer to default_concrete_strategy by the local name. .__func__ unwraps the staticmethod descriptor to access the underlying original function (a staticmethod descriptor is not itself callable).

Another approach would be to use a sentinel default; None would work fine here since all normal values for strategy are static functions:

class C:    
    @staticmethod
    def default_concrete_strategy():
        print("default")

    @staticmethod
    def other_concrete_strategy():
        print("other")

    def __init__(self, strategy=None):
        if strategy is None:
            strategy = self.default_concrete_strategy
        self.strategy = strategy

Since this retrieves default_concrete_strategy from self the descriptor protocol is invoked and the (unbound) function is returned by the staticmethod descriptor itself, well after the class definition has completed.

Monday, October 24, 2022
 
git-flo
 
Only authorized users can answer the search term. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :