PHP5 olası bir 'invoke' tarzı geri mi?

5 Cevap php

PHP functions such as 'array_map' take a callback, which can be a simple function or a class or object method:
$array2 = array_map('myFunc', $array);
or
$array2 = array_map(array($object, 'myMethod'), $array);

Ama (prototype.js içinde 'çağırma' gibi) mevcut nesnenin yineleme içinde bağlı olduğu bir yöntem geçmek için bir sözdizimi var? Ben söyleyebiliriz ki

$ Dizi2 = array_map ($ dizi 'myMethod');

etkisiyle

foreach ($ dizi as $ obj) $ dizi2 [] = $ obj-> myMethod ();

Açıkçası ben bu formu kullanabilirsiniz, ya da ben arama yapmak için bir sargı işlev yazabilirsiniz, ve hatta bu inline yapmak. 'MyMethod' zaten bir yöntem olduğundan Ama bunlardan birini yapmak zorunda evlerin yuvarlak olacak gibi görünüyor.

5 Cevap

Şu anda yok. 5.3 çıktığı php olduğunda, aşağıdaki sözdizimini kullanabilirsiniz:

$array2 = array_map(function($obj) { return $obj->myMethod(); }, $array);

Temel olarak, no. Bu daha kolay hale getirmek için özel bir sözdizimi vardır.

PHP şeyler yapmak için birden fazla yolu her zaman var gibi görerek, PHP 5.3 bunu yapmanın bir meraklısı şekilde düşünüyorum, ama ben mutlaka better olmaz söyleyebilirim sizin {[daha (1)]}, örneğin:

$x = array_reduce(
    $array_of_objects, 
    function($val, $obj) { $val = array_merge($val, $obj->myMethod()); return $val; },
    array() 
);

Sadece foreach ile gitmek :)

<?php

// $obj->$method(); works, where $method is a string containing the name of the
// real method
function array_map_obj($method, $array) {
    $out = array();

    foreach ($array as $key => $obj)
        $out[$key] = $obj->$method();

    return $out;    
}

// seems to work ...

class Foo {
    private $y = 0;
    public function __construct($x) {
        $this->y = $x;
    }
    public function bar() {
        return $this->y*2;
    }
}

$objs = array();
for ($i=0; $i<20; $i++)
    $objs[] = new Foo($i);

$res = array_map_obj('bar', $objs);

var_dump($res);

?>

işte!

Bu saçma bir cevap biraz, ama sen ArrayObject alt sınıf ve bunun yerine normal bir dizi olduğu kullanabilirsiniz:

<?php

class ArrayTest extends ArrayObject {
    public function invokeMethod() {
        $result = array();
        $args = func_get_args();
        $method = array_shift($args);
        foreach ($this as $obj) {
            $result[] = call_user_func_array(array($obj, $method), $args);
        }
        return $result;
    }
}

//example class to use
class a { 
    private $a;
    public function __construct($a) { 
        $this->a = $a; 
    }

    public function multiply($n) {
        return $this->a * $n;
    }
 }

//use ArrayTest instance instead of array
$array = new ArrayTest();
$array[] = new a(1);
$array[] = new a(2);
$array[] = new a(3);

print_r($array->invokeMethod('multiply', 2));

Çıkışlar bu:

Array
(
    [0] => 2
    [1] => 4
    [2] => 6
)

PHP 5.3 için beklerken ... iyi ... array_map için geçici bir işlev oluşturmak için create_function() kullanmak istiyorsunuz

$func = create_function('$o', '$o->myMethod();');
array_map($func, $objects);