48

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()?

2
  • Any reason you've created a function isNonEmptyArray instead of just using !empty(...)? Commented Oct 1, 2010 at 14:59
  • yes, it returns true only if the param is an array with at least one non-empty value Commented Oct 1, 2010 at 15:02

5 Answers 5

105

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.

Sign up to request clarification or add additional context in comments.

6 Comments

Yes I tried this before but it gives me this error - Warning: array_walk() [function.array-walk: Unable to call Array() - function does not exist in However this is working array_walk($fieldsArray,'user::test_print');. So what is wrong. I wanted to use $this
Can you show the exact code that doesn't work (that issues that warning)?
Oh I found the issue... please don't downvote guys... I did not initiate user object... was doing user::getUserFields()
Something to have in mind, the method being called must receive the elements by reference, otherwise the changes do not get sent through the callback to array_walk()
This worked also with the php native sorting function usort($someArray, array($this,'some_function_of_class'))
|
7

If you need to call a static method without instantiating the class you could do so:

// since PHP 5.3 array_walk($fieldsArray, 'self::test_print'); 

Or from outside:

// since PHP 5.5 array_walk($fieldsArray, User::class.'::test_print'); 

1 Comment

For static calls, array_walk( $forms, array( 'self', 'method_name' )) also works. I am not sure which version of PHP brought this, but I guess that array-method is older than the 'self::method_name' string-parsing-thing.
3

To call a class method as a callback function in another class method, you should do :

public function compareFucntion() { } public function useCompareFunction() { usort($arrayToSort, [$this, 'compareFucntion']) } 

Comments

1

This is the class which looks for a specific key in a multidimensional array and returns its value:

class Find_value_by_key { protected $look_by_key; protected $look_in_array = array(); public $result_value; public function get_array($look_in_array, $look_by_key) { $this->look_by_key = $look_by_key; $this->look_in_array = $look_in_array; $this->run_walk_through_array($this->look_in_array); } protected function walk_through_array($value, $key) { if (is_array($value)) { if ($key === $this->look_by_key) { $this->result_value = $value; } else { array_walk($value,[$this,'walk_through_array']); } } } protected function run_walk_through_array($look_in_array) { array_walk($look_in_array,[$this,'walk_through_array']); } } 

You need to pass the Array and the specific Key into get_array(). Then call for $result_value:

$this->load->library('find_value_by_key'); $this->find_value_by_key->get_array($my_array, 'my_key'); $key_Value = $this->find_value_by_key->result_value; 

Comments

0

Below are four examples of ways to do your callback functions.
If you're like me, one of these will be the most intuitive for you.
Look closely at the difference in how $callable is defined in each one. It's important to remember that array_walk() returns a boolean.

<?php namespace App\MiscTests; class User { protected $fieldsArray = []; protected $result = ""; public function setUserFields(array $fieldsArray) { $this->fieldsArray = $fieldsArray; } public function getResult() { return $this->result; } private function test_printOne($item, $key) { echo $key.$item; $this->result = $key.$item; } private function test_printTwo(){ $callThis = function ($item, $key){ echo $key.$item; $this->result = $key.$item; }; return $callThis; } public function callbackMethodOne() { $callable = array($this, 'test_printOne'); return array_walk($this->fieldsArray, $callable, null); } public function callbackMethodTwo() { $callable = $this->test_printTwo(); return array_walk($this->fieldsArray, $callable, null); } public function callbackMethodThree() { $callable = function ($item, $key){ echo $key.$item; $this->result = $key.$item; }; return array_walk($this->fieldsArray, $callable, null); } public function callbackMethodAnonymous() { return array_walk($this->fieldsArray, function ($item, $key){ echo $key.$item; $this->result = $key.$item; }, null); } } ?> 

Here's the unit tests I used:

<?php namespace Tests\Unit; use PHPUnit\Framework\TestCase; class MiscUserTest extends TestCase { /** * This will test the User class * * @return void */ public function test_print_with_callback_method_one() { $userObject = new \App\MiscTests\User; $userObject->setUserFields(['Foo'=>'Bar1']); $this->assertEquals(1, $userObject->callbackMethodOne()); $result = $userObject->getResult(); $this->assertEquals(0, strcmp('FooBar1', $result)); } public function test_print_with_callback_method_two() { $userObject = new \App\MiscTests\User; $userObject->setUserFields(['Foo'=>'Bar2']); $this->assertEquals(1, $userObject->callbackMethodTwo()); $result = $userObject->getResult(); $this->assertEquals(0, strcmp('FooBar2', $result)); } public function test_print_with_callback_method_three() { $userObject = new \App\MiscTests\User; $userObject->setUserFields(['Foo'=>'Bar3']); $this->assertEquals(1, $userObject->callbackMethodThree()); $result = $userObject->getResult(); $this->assertEquals(0, strcmp('FooBar3', $result)); } public function test_print_with_callback_method_anonymous() { $userObject = new \App\MiscTests\User; $userObject->setUserFields(['Foo'=>'Bar4']); $this->assertEquals(1, $userObject->callbackMethodAnonymous()); $result = $userObject->getResult(); $this->assertEquals(0, strcmp('FooBar4', $result)); } } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.