WordPress.org

Make WordPress Core

Opened 18 months ago

Last modified 18 months ago

#43455 new defect (bug)

apply_filters not passing by ref

Reported by: lordspace Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version: 4.8
Component: Plugins Keywords: reporter-feedback
Focuses: Cc:

Description

Hey folks,

I've tried passing some extra params to a filter by reference and it doesn't seem to work via apply_filters. Do you know why?

<?php
$arr = [
        'name' => 'slavi',
    ];

    $arr2 = [
        'total' => 0,
    ];

    $obj = new stdClass();
    $obj->total = 0;

    $arr = apply_filters('test', $arr, $arr2, $obj);

    add_filter('test', 'orb_pp_by_ref', 20, 3);

    function orb_pp_by_ref($arr, & $arr2, & $obj)
    {
        $arr2['total'] += 10;
        $obj->total += 10;
        return $arr;
    }

    echo "<pre>";

    echo '$arr:';
    var_dump($arr);

    echo '$arr2:';
    var_dump($arr2);

    echo '$obj:';
    var_dump($obj);

    echo "Direct call<br/>";

    orb_pp_by_ref($arr, $arr2, $obj);
    echo '$arr:';
    var_dump($arr);

    echo '$arr2:';
    var_dump($arr2);

    echo '$obj:';
    var_dump($obj);

    echo "</pre>";

Result:

$arr:array(1) {
  ["name"]=>
  string(5) "slavi"
}
$arr2:array(1) {
  ["total"]=>
  int(0)
}
$obj:object(stdClass)#408 (1) {
  ["total"]=>
  int(0)
}
Direct call
$arr:array(1) {
  ["name"]=>
  string(5) "slavi"
}
$arr2:array(1) {
  ["total"]=>
  int(10)
}
$obj:object(stdClass)#408 (1) {
  ["total"]=>
  int(10)
}

version.php

<?php
/**
 * The WordPress version string
 *
 * @global string $wp_version
 */
$wp_version = '4.8.5';

/**
 * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.
 *
 * @global int $wp_db_version
 */
$wp_db_version = 38590;

/**
 * Holds the TinyMCE version
 *
 * @global string $tinymce_version
 */
$tinymce_version = '4603-20170530';

/**
 * Holds the required PHP version
 *
 * @global string $required_php_version
 */
$required_php_version = '5.2.4';

/**
 * Holds the required MySQL version
 *
 * @global string $required_mysql_version
 */
$required_mysql_version = '5.0';

Change History (5)

#1 @lordspace
18 months ago

Correction: It seems I was calling apply_filters before adding a callback.
I've fixed that. It seems only the object gets passed by reference.

<?php

$arr = [
    'name' => 'slavi',
];

$arr2 = [
    'total' => 0,
];

$obj = new stdClass();
$obj->total = 0;

add_filter('test', 'orb_pp_by_ref', 20, 3);

$arr = apply_filters('test', $arr, $arr2, $obj);

function orb_pp_by_ref($arr, & $arr2, & $obj)
{
    $arr2['total'] += 10;
    $obj->total += 10;
    return $arr;
}

echo "<pre>";

echo '$arr:';
var_dump($arr);

echo '$arr2:';
var_dump($arr2);

echo '$obj:';
var_dump($obj);

echo "Direct call<br/>";

orb_pp_by_ref($arr, $arr2, $obj);
echo '$arr:';
var_dump($arr);

echo '$arr2:';
var_dump($arr2);

echo '$obj:';
var_dump($obj);

echo "</pre>";
$arr:array(1) {
  ["name"]=>
  string(5) "slavi"
}
$arr2:array(1) {
  ["total"]=>
  int(0)
}
$obj:object(stdClass)#408 (1) {
  ["total"]=>
  int(10)
}
Direct call
$arr:array(1) {
  ["name"]=>
  string(5) "slavi"
}
$arr2:array(1) {
  ["total"]=>
  int(10)
}
$obj:object(stdClass)#408 (1) {
  ["total"]=>
  int(20)
}

#2 @SergeyBiryukov
18 months ago

  • Component changed from General to Plugins

#3 @ocean90
18 months ago

  • Keywords reporter-feedback added

It should work if you use apply_filters_ref_array():

$arr = apply_filters_ref_array( 'test', [ $arr, &$arr2, $obj ] );

#4 @lordspace
18 months ago

@ocean90 are you getting any notices in the log files when you pass the ampersand sign in the argument list?
The ampersand should only be used in the function declaration.

#5 @ocean90
18 months ago

No, make sure to pass an array as the second argument to apply_filters_ref_array(). Simplified example: https://3v4l.org/TKgIf

Note: See TracTickets for help on using tickets.