BlaM
BlaM

Reputation: 28888

How to achieve "require_global"?

Current situation:

Much simplified that means:

New Version:

<?PHP
class blaController extends baseController {
    private $intVar;

    function dosomethingFunction() {
        $this->intVar = 123;
        $this->view('myView');
    }
}
?>

Old Version:

<?PHP
$globalVar = 123;
// view "controllername" is automatically shown
?>

I'm now trying to write a wrapper to be able to use my old controllers in my new MVC without having to rewrite everything. To do so, I have a "wrapper" controller:

class wrapController extends baseController {
    function dosomethingFunction() {
        require 'old_dosomething.function.php';
        $this->view('old_dosomething_view');
    }
}

(Once again: This is VERY, VERY simplified - just to get the idea over. Not actual code.)

The problem with that approach is, that the previously global variable $globalVar now only exists inside of the method "dosomethingFunction" and cannot be accessed by the view.

This wouldn't be the case if I could force the require to behave as "in global scope" so that $globalVar would once again be available in global scope.

So: Is there some way to achieve "require_global" or something similar?

(One solution for my problem would be to modify my old controllers to start with a bunch of "global" commands, but I'd prefer a solution where I don't have to change so much of that old code.)

(Note: Please don't tell me that GLOBALS are bad. It totally misses the point of this question. Just accept that it is a requirement to keep some old code working in a newer, cleaner environment.)

Upvotes: 4

Views: 11152

Answers (5)

BlaM
BlaM

Reputation: 28888

For anybody interested: My (so far) final version:

class wrapController extends baseController {
    function dosomethingFunction() {
        // ... do some initialisation stuff ...

        $__defined_vars = array_keys(get_defined_vars());

        require 'old_dosomething.function.php';

        $__newly_defined_vars = array_diff(
                                    array_keys(get_defined_vars()),
                                    $__defined_vars, 
                                    array('__defined_vars')
                                );
        foreach ($__newly_defined_vars as $var) {
            $GLOBALS[$var] = &$$var;
        }

        $this->view('old_dosomething_view');
    }
}

Ugly, but it works. Thanks for all your great help!

Upvotes: 1

uuɐɯǝʃǝs
uuɐɯǝʃǝs

Reputation:

Have you tried Zend_Registry from Zend Framework?

The registry is a container for storing objects and values in the application space. By storing the value in the registry, the same object is always available throughout your application. This mechanism is an alternative to using global storage.

http://framework.zend.com/manual/en/zend.registry.html

Upvotes: 0

vartec
vartec

Reputation: 134691

You can add local variables defined within dosomethingFunction() to global scope:

class wrapController extends baseController {
    function dosomethingFunction() {
        require 'old_dosomething.function.php';
        //begin added code  
        $vararr = get_defined_vars();
        foreach($vararr as $varName => $varValue) 
              $GLOBALS[$varName] = $varValue;            
        //end added code          
        $this->view('old_dosomething_view');
    }
}

Note, that for this to work as expected, you should call require before using any other thing in the function. get_defined_vars() returns only variables from the current scope, so no array_diff hacks are needed.

Upvotes: 6

Matt
Matt

Reputation: 2230

This is the easiest solution I can think of.

Use the get_defined_vars() function twice and get a diff of each call to determine what variables were introduced by the required file.

Example:

$__defined_vars       = get_defined_vars();
require('old_dosomething.function.php');
$__newly_defined_vars = array_diff_assoc($__defined_vars, get_defined_vars());
$GLOBALS = array_merge($GLOBALS, $__newly_defined_vars);
$this->view('old_dosomething_view');

Upvotes: 4

Peter Bailey
Peter Bailey

Reputation: 105916

Hmmm, this is an issue I've never before seen. I suppose you could do this

class wrapController extends baseController {
    function dosomethingFunction() {
        require 'old_dosomething.function.php';

        // Force "old" globals into global scope
        $GLOBALS['globalVar'] = $globalVar;

        $this->view('old_dosomething_view');
    }
}

But that's a pretty tedious, manual process as well, depending on how many globals we're talking about. I'll think about this, but I don't know of any "auto-magic" solution off the top of my head.

Upvotes: 1

Related Questions