Reputation: 10284
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 calltest_print()
- function does not exist in ...
So, how do I specify $this->test_print()
while using array_walk()
?
Upvotes: 48
Views: 35470
Reputation: 1914
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));
}
}
Upvotes: 0
Reputation: 41
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;
Upvotes: 1
Reputation: 94113
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.
Upvotes: 105
Reputation: 533
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'])
}
Upvotes: 3
Reputation: 13673
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');
Upvotes: 7