简体   繁体   中英

How can I emulate PHP's crazy global thing?

If I have a file a.php which I can't edit.

<?php
$a = 1;
function a() {
  global $a;
  echo $a;
}  
a();

then running php a.php prints 1 nicely. But if I have b.php :

<?php
function b() {
  include "a.php";
}
b();

Then running php b.php doesn't print anything.

What can I type before the include "a.php" to make it behave the same without editing a.php ?

(Obviously other than defining $a . In my real-world example it has to work for a complicated a.php ).

Try adding a global into your new function:

function b() {
  global $a;

  include "a.php";
}

At the moment I wonder if PHP is treating $a as local to your b() function.

Addendum: in response to your comment, it seems that you need to grab arbitrary variables that your include has created locally in your function, and remake them as global. This works for me on 5.3.20 on OSX 10.6.8:

function b() {
    include 'a.php';

    // Move variables into global space
    foreach (get_defined_vars() as $name => $value) {
        global $$name;
        // global wipes the value, so just reset it
        $$name = $value;
        echo "Declared $name as global\n";
    }
}

b();
// Your global vars should be available here

Obviously you can remove the echo once you're happy it works.

Defining a function inside a function? Yuck. But I guess you have a real-world situation that doesn't allow any other way. But for the record, this is REALLY BAD PRACTICE

Adding global $a to b() should work.

function b() {
  global $a;
  include "a.php";
}

I don't know what variables need to be defined. a.php is really complicated

Then the only way I can think of is not using a function in b.php, so you're in the global scope when including a.php. I can see no other way.

It sounds like a.php is some legacy or 3rd party script that you have to wrap in your own application. I had a similar problem once and the solution was not pretty. First, you will have to find out, what global variables exist ( grep global or similar helps).

This is the relevant part of my "Script Adapter" class:

private function _includeScript($file, $globals)
{
    foreach ($globals as $global) {
        global $$global;
    }

    ob_start();
    require $file;
    $this->_response->setBody(ob_get_clean());
}

As you see, I had to catch the output too. The class also emulates $_GET and catches header calls to assign everything to a Response object, but for your case only this method is important. It gets called with the file name and an array of global variable names as parameters:

_includeScript('a.php', array('a'));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM