Forum

Thread tagged as: Problem

Variable not working as expected?

Hi,

When I hardcode the value in each, it works great.

However, I need the value to be a variable, when I do that the filter doesn't work?

$sectors = perch_categories([
    'set' => 'sectors-en',
    'template' => 'list.html',
    'each' => function($item) {
          $item['related_sectors'] = perch_collection('Solutions EN',[
                'category' => $item['catPath'],
                'template' => 'callback.html',.
                'count' => 1,
                'filter' => 0, 
                'match' => 'contains',
                'value' => 'category-name', // WORKS WHEN VALUE IS HARDCODED
                ],true
          );
          return $item;
          },
]);

I've created a test variable and echoed it to the page, it looks the same as the value when I hardcode it.

$test_var = 'category-name';
echo $test_var; // OUTPUTS category-name TO THE PAGE

$sectors = perch_categories([
    'set' => 'sectors-en',
    'template' => 'list.html',
    'each' => function($item) {
          $item['related_sectors'] = perch_collection('Solutions EN',[
                'category' => $item['catPath'],
                'template' => 'callback.html',.
                'count' => 1,
                'filter' => 0, 
                'match' => 'contains',
                'value' => $test_var, // DOESN'T WORK? LINE 61
                ],true
          );
          return $item;
          },
]);

When I try to use a variable for the value it doesn't work and debug shows this message:

Array
(
    [type] => 8
    [message] => Undefined variable: test_var
    [file] => /Users/stephen/Repositories/project-name/cms/perch/templates/layouts/sectors-en/sectors--categories.php
    [line] => 61
)

It says test_var is undefined, even though I can echo it to the page.

I've successfully used the variable with other filters, but this is the first time I've tried it with each.

Is there a special way to use a variable with each?


Summary

Perch Runway: 3.1.1, PHP: 7.1.12, MySQL: mysqlnd 5.0.12-dev - 20150407 - $Id: b396954eeb2d1d9ed7902b8bae237b287f21ad9e $, with PDO
Server OS: Darwin, cgi-fcgi
Installed apps: content (3.1.1), assets (3.1.1), categories (3.1.1)
App runtimes: <?php $apps_list = [ ];
PERCH_LOGINPATH: /perch
PERCH_PATH: /Users/stephen/Repositories/project/cms/perch
PERCH_CORE: /Users/stephen/Repositories/project/cms/perch/core
PERCH_RESFILEPATH: /Users/stephen/Repositories/project/cms/perch/resources
Image manipulation: GD
PHP limits: Max upload 32M, Max POST 32M, Memory: 128M, Total max file upload: 32M
F1: 3b606135b33e6a102526838f4152a807
Resource folder writeable: Yes
SCRIPT_NAME: /perch/core/settings/diagnostics/index.php
REQUEST_URI: /perch/core/settings/diagnostics/
DOCUMENT_ROOT: /Users/stephen/Repositories/project/cms
HTTP_HOST: project.local
Stephen Meehan

Stephen Meehan 4 points

  • 3 years ago
Duncan Revell

Duncan Revell 78 points
Registered Developer

Hi Stephen,

the each callback makes use of an anonymous function - which by default is its own silo (much like a normal function).

To use your $test_var, you essentially make use of a closure, as follows:

'each' => function($item) use ($test_var) {

Do some Googling on closures/anonymous functions (they are essentially the same thing) to understand what else you can do, especially if you want to change the value of $test_var inside your function.

Hi Dunc,

Thanks for replying, and for the suggestion to Google closures, I didn't even know what to search for!

It works now :)

The real variable is generated by looking at the url, so the value will change.

I've found out about using an & to change the variable inside the function, so that's useful.

$test_var = 'category-name';
echo $test_var; // OUTPUTS category-name TO THE PAGE

$sectors = perch_categories([
    'set' => 'sectors-en',
    'template' => 'list.html',
        'each' => function($item) use (&$test_var) { 
          $item['related_sectors'] = perch_collection('Solutions EN',[
                'category' => $item['catPath'],
                'template' => 'callback.html',.
                'count' => 1,
                'filter' => 0, 
                'match' => 'contains',
                'value' => $test_var,
                ],true
          );
          return $item;
          },
]);

Some good articles here about closures :