donnikitos
donnikitos

Reputation: 976

PHP - strange global behavior

I am trying to access a variable from a function defined in an required file:

**main.php**

function run() {
    require('cfg.php');
    require('function.php');
    print(fn());
}


**cfg.php**

$test = 'Var!';


**function.php**

function fn() {
    global $test;
    return $test;
}

I expected "Var!" as output. But $test seem to be NULL. I also tried this one for debugging:

**function.php

var_dump($test);
function fn() {
    global $test;
    return $test;
}

var_dump() return the right value... How can I fix this?

Upvotes: 0

Views: 63

Answers (2)

Amal Murali
Amal Murali

Reputation: 76666

Why doesn't it work?

function run() {
    require('cfg.php');
    require('function.php');
    print(fn());
}

Your code suffers from variable scope issues. The variables / functions inside cfg.php and function.php only exist inside the run() function and they aren't accessible globally.

Consider your fn() function:

function fn() {
    global $test;
    return $test;
}

You're trying to access $test variable. It isn't defined globally, so trying to access it will return NULL (as it should).

Consider the second case:

$test = 'Var!';

var_dump($test);

function fn() {
    global $test;
    return $test;
}

Here, the $test variable is defined. So global $test; variable will correctly import the variable into the function scope, and the return statement will return the variable. That'd explain why you're getting the output Var! for the second code block.

What should you use instead?

Using global variables is not considered good practice as it violates encapsulation etc. I'd recommend not using them.

Use constants for storing configurations. The scope of a constant is global. You can access constants anywhere in your script without regard to scope.

Separate your logic into multiple files. Use cfg.php for configurations, functions.php for functions etc. That way, you can keep your files independently and use one according to the requirements. This way, you can also avoid the headache of having to include from an included file (or even, include from an include from an included file) etc.


config.php

<?php

define('test', 'Var!')

functions.php:

<?php

function doSomething($foo) {
    // do something with $foo and return
}

function somethingElse($bar) {
    // do something with $bar and return
}

main.php:

<?php

require_once 'cfg.php';
require_once 'include.php';

// more code

Upvotes: 1

Jon
Jon

Reputation: 437336

You are including cfg.php in the context of your run function -- therefore, the variable definition creates a local variable.

You would get the expected behavior if you changed $test = 'Var!' to $GLOBALS['test'] = 'Var!', but while that will make the problem go away it's not a good way of doing things -- injecting variables from one script into another scope never is.

What you should probably be doing instead is using constants, e.g.:

// cfg.php
const TEST = 'Var!';

// main.php
require('cfg.php');

function run() {
    require('function.php');
    print(fn());
}

// function.php

function fn() {
    return TEST;
}

Upvotes: 0

Related Questions