简体   繁体   中英

Laravel collection map use private function in same class instead closure

I use the map function to loop each object of collections. The closure method is too long and I tried to make it a private function. But I cannot successfully call the function.

Here is my sample code. (note: the function test may be very long in real case)

<?php

class cls
{
    private function test($a) {
        return ($a + 1);
    }

    public function run1() {
        return ($this->test(5));
    }

    public function run2() {
        $col = Collect([1,2,3]);
        return ($col->map($this->test()));
    }

    public function run3() {
        $col = Collect([1,2,3]);
        $mycls = $this;
        return ($col->map(function ($c) use ($mycls) {
            return($mycls->test($c));
        }));
    }
}

$c = new cls;
$c->run1(); # 6
$c->run2(); # Error: Too Few Argements
$c->run3(); # [2,3,4]

I use the function: run1 to test if the private function is callable and I failed at function: run2. Although function: run3 makes code shorten. It seems a little bit too superfluous. How can I make run2 works?

Update

My version of Laravel is 6.2

Update

I tried the @xenooooo answer. It works with the public function, but I get a different error code with the private method. 在此处输入图像描述

Simple answer: $this->test() required a parameter and you are simply not passing anything to it.

You can also modify your run2/run3 methods to do the following:

public function run2() {
   $col = collect([1,2,3])->map(function ($value) {
      return $this->test($value);
   });
        
   return $col; //returns a collection of items
   //return $col->toArray(); //(extra option) returns an array of collected items
}

Result:

Illuminate\Support\Collection {#872 ▼ 
  #items: array:3 [▼
    0 => 2
    1 => 3
    2 => 4
  ]
  #escapeWhenCastingToString: false
}

You may read more on collections here: https://laravel.com/docs/9.x/collections#introduction

The problem in run2 is that you are calling the method directly and you need to pass the an argument since test is expecting argument $a . To use the method as a callback function you need the pass it as an array which is the first value is $this and the second is the method name which is test :

public function test($a) {
    return ($a + 1);
}

public function run2()
{
    $collection = collect([1,2,3]);

    $newCollection = $collection->map([$this,'test']);

    return $newCollection;
}

UPDATE

It only work if the method that you will call is public and it will not work if you use a private or protected method. If you use a private or protected if will throw a BadMethodCallException

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM