62

I am trying to create a class to handle arrays but I can't seem to get array_map() to work in it.

$array = [1,2,3,4,5,6,7,8,9,10];
class test {
    public $values;

    public function adding($data) {
        $this->values = array_map($this->dash(), $data);
    }

    public function dash($item) {
        return '-' . $item . '-';
    }

}

var_dump($array);

$test = new test();
$test->adding($array);

// Expected: -1-,-2-,-3-,-4-... 
var_dump($test->values);

This outputs

array(10) { [0]=> int(1) [1]=> int(2) [2]=> int(3) [3]=> int(4) [4]=> int(5) [5]=> int(6) [6]=> int(7) [7]=> int(8) [8]=> int(9) [9]=> int(10) }

Warning: Missing argument 1 for test::dash(), called in [...]\arraytesting.php on line 11 and defined in [...]\arraytesting.php on line 15

Warning: array_map() expects parameter 1 to be a valid callback, function '--' not found or invalid function name in [...]\arraytesting.php on line 11 NULL

What am I doing wrong or does this function just not work inside classes?

Martijn
  • 15,791
  • 4
  • 36
  • 68
Justin
  • 1,249
  • 1
  • 15
  • 37

9 Answers9

169

You are specifying dash as the callback in the wrong way.

This does not work:

$this->classarray = array_map($this->dash(), $data);

This does:

$this->classarray = array_map([$this, 'dash'], $data);

Read about the different forms a callback may take here.

Alexandre Huat
  • 806
  • 10
  • 16
Jon
  • 428,835
  • 81
  • 738
  • 806
  • Thank you for the quick replay. I got it working and thanks for you help. I was just wondering do you happen to have more article about callback and how to specify if correctly? – Justin Mar 24 '11 at 16:49
  • @Justin: Take a look here: http://stackoverflow.com/questions/48947/how-do-i-implement-a-callback-in-php – Jon Mar 24 '11 at 19:01
  • 2
    even statically works like array_map( @[ self, 'dash' ] ) – bortunac Jun 25 '16 at 22:53
  • How can you pass a parameter with the dash function? – Nielsapp May 10 '18 at 11:33
  • 1
    @Nielsapp you cannot directly, you must pass in a callable that will effectively bind the arguments that you want, e.g. `array_map(function($item) { return $this->dash($item, 'additional argument'); }, $data)` – Jon May 14 '18 at 09:49
16

When using a class method as a callback for functions like array_map() and usort(), you have to send the callback as two-value array. The 2nd value is always the name of the method as a string. The 1st value is the context (class name or object)

// Static outside of class context
array_map( array( 'ClassName', 'methodName' ), $array );

// Static inside class context
array_map( array( __CLASS__, 'methodName' ), $array );

// Non-static outside of object context
array_map( array( $object, 'methodName' ), $array );

// Non-static inside of object context
array_map( array( $this, 'methodName' ), $array );
Peter Bailey
  • 105,256
  • 31
  • 182
  • 206
3

array_map($this->dash(), $data) calls $this->dash() with 0 arguments and uses the return value as the callback function to apply to each member of the array. You want array_map(array($this,'dash'), $data) instead.

Anomie
  • 92,546
  • 13
  • 126
  • 145
2

It must read

$this->classarray = array_map(array($this, 'dash'), $data);

The array-thing is the PHP callback for a object instance method. Callbacks to regular functions are defined as simple strings containing the function name ('functionName'), while static method calls are defined as array('ClassName, 'methodName') or as a string like that: 'ClassName::methodName' (this works as of PHP 5.2.3).

Stefan Gehrig
  • 82,642
  • 24
  • 155
  • 189
  • Thank you for you answer. I was very helpful do you have happen to know of any more articles about this subject? Thanks again, – Justin Mar 24 '11 at 17:21
1

array_map takes a callback as its first parameter.

And a callback to a static method is written like this :

array('classname', 'methodname')


Which means that, in your specific case, you'd use :

array_map(array('stripSlashesRecursive', ''), $value);


For more informations about callbacks, see this section of the PHP manual : Pseudo-types and variables used in this documentation - callback.

Pascal MARTIN
  • 395,085
  • 80
  • 655
  • 663
1

In case the class belongs to a different namespace, you need to use the complete namespaced class name. Below is an example using a CakePHP Utility class:

This will not work:

array_map(array('Inflector', 'humanize'), $some_array));

This will work:

array_map(array('Cake\Utility\Inflector', 'humanize'), $some_array));
Aris
  • 4,643
  • 1
  • 41
  • 38
0
array_map( array('Sanitize', 'stripSlashesRecursive'), $value) ...
aefxx
  • 24,835
  • 6
  • 45
  • 55
0

//Regular functions: array_map('MyFunction', $array);

//static functions in a class: array_map(array('MyClass', 'MyFunction'), $array);

//functions from an object: array_map(array($this, 'MyFunction'), $array);

//functions from an parent class array_map(array($this, 'parent::MyFunction'), $array);

otto9due
  • 9
  • 2
  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Ethan Jun 10 '22 at 01:16
-1

For multidimensional arrays (any arrays):

    $data = array_map('decode'), $data);

    function decode($data)
    {
        if (is_array($data)) {
            foreach ($data as &$value) {
                if (is_array($value)) {
                    $value = decode($value);
                } else {
                    $value = html_entity_decode($value);
                }
            }
        } else {
            $data = html_entity_decode($data);
        }
        return $data;
    }

For multidimensional arrays (any arrays) in Class:

$data = array_map(array($this,'decode'), $data);

private function decode($data)
{
    if (is_array($data)) {
        foreach ($data as &$value) {
            if (is_array($value)) {
                $value = $this->decode($value);
            } else {
                $value = html_entity_decode($value);
            }
        }
    } else {
        $data = html_entity_decode($data);
    }
    return $data;
}
Format
  • 1