0

Why in the below simplified Plugins system example, passing by reference ($data) is not working ($content is not modified)?

class Plugins
{
    public static function runhook()
    {
       $args = func_get_args();
       $hook = array_shift($args);
       foreach ($args as &$a); // be able to pass $args by reference
       call_user_func_array(array('Plugin', $hook), $args);
    }

}

class Plugin
{
    public static function modifData(&$data)
    {
       $data = 'Modified! :'.$data;
    }
}

class Application
{
    public $content;

    public function __construct()
    {
       $this->content = 'Content from application...';
    }

    public function test()
    {
       echo $this->content; // return 'Content from application...'
       Plugins::runHoook('modifData', $this->content);
       echo $this->content; // return 'Content from application...' instead of 'Modified! :Content from application...'

    }
}

$app = new Application();
$app->test();

As you can see $this->content should be modified by the modifData() called in background by runHook() function of the Plugin class. But for a strange reason nothing expected happens and the variable stay stuck in his original state... Maybe I'm wrong?

Thanks in advance for any help...

PeeHaa
  • 71,436
  • 58
  • 190
  • 262
Albertine
  • 25
  • 3

1 Answers1

0

Not possible with a variable amount of paramters (see also https://stackoverflow.com/a/7035513/684353).

You could achieve it with this (repeat this for the amount of parameters you're expecting, which shouldn't be too many):

<?php

class Plugins
{
    public static function runHook($hook, &$param1)
    {
       $args = func_get_args();
    //   call_user_func_array(array('Plugin', $hook), [$param1]); // doesn't work, probably can fix this but didn't seem necessary 
       Plugin::$hook($param1);
    }

}

class Plugin
{
    public static function modifData(&$data)
    {
       $data = 'Modified! :'.$data;
    }
}

class Application
{
    public $content;

    public function __construct()
    {
       $this->content = 'Content from application...';
    }

    public function test()
    {
       echo $this->content; // return 'Content from application...'
       Plugins::runHook('modifData', $this->content);
       echo $this->content; // return 'Content from application...' instead of 'Modified! :Content from application...'

    }
}

$app = new Application();
$app->test();

Or wait for PHP 5.6 and hope the ... token will allow this.

Community
  • 1
  • 1
Martijn Hols
  • 1,470
  • 1
  • 10
  • 21
  • Oh okay, so I could search for a very long time if it's just not possible! Thank you for the explanation, i'll try something based on your example :) – Albertine Aug 31 '14 at 17:15