Home > Enterprise >  Using reference with array_walk and arrow function
Using reference with array_walk and arrow function

Time:09-19

I am not sure how to increase my email_actions in this snippet:

$email_actions = 0;
array_walk(
    $steps,
    fn($step): int => !empty($step['settings']['type']) &&
                      $step['settings']['type'] === self::FLOWS_EMAIL_TYPE_ACTION
                          ? $email_actions  
                          : false
);
dd($email_actions);

I get 0 as result when it should be 2. Tried to pass the variable by reference like: fn($step, &$email_actions) but is obviously not the right approach.

CodePudding user response:

fn copies the variables that are automatically injected.

From documentation (check example 4) :

Arrow functions use by-value variable binding. This is roughly equivalent to performing a use($x) for every variable $x used inside the arrow function. A by-value binding means that it is not possible to modify any values from the outer scope. Anonymous functions can be used instead for by-ref bindings.

If you want to have a write access (a reference), you might need to use the old syntax :

$email_actions = 0;
array_walk(
    $steps,
    function($step) use (&$email_actions) : int
    {
        return !empty($step['settings']['type']) &&
               $step['settings']['type'] === self::FLOWS_EMAIL_TYPE_ACTION
                   ? $email_actions  
                   : false;
    }
);
dd($email_actions);

CodePudding user response:

You should be using array_reduce to get single value after iterating through all array

$email_actions = array_reduce(
    $steps,
    function ($carry, $step) {
        if ($step['settings']['type'] === self::FLOWS_EMAIL_TYPE_ACTION) {
            $carry  ;
        }
        
        return $carry;
    },
    0
);


If you really need to use arrow functions:

$email_actions = array_count(
    array_filter($steps, fn ($step) => $step['settings']['type'] === self::FLOWS_EMAIL_TYPE_ACTION)
);
  •  Tags:  
  • php
  • Related