skip to Main Content

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.
enter image description here

2

Answers


  1. 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:

    IlluminateSupportCollection {#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

    Login or Signup to reply.
  2. 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

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search