Variable accessibility with require_once/ob_start() - php

Maybe I'm just tired or just am simply confused, but I'm having a strange issue dealing with some require_once() calls and ob_start().
Basic Structure:
Top of Main.php:
require_once 'config.php'; // includes variable $A = "bar", and Function "foo"
function getPage(){
ob_start();
include 'some_file.php';
$html = ob_get_clean();
echo $html;
die();
}
getPage();
some_file.php
require_once 'config.php'; // includes same config file
var_dump($A); // NULL
foo(); // runs, returns correct value
Config.php
$A = 'bar';
function foo(){
return "FOO";
}
So, what is wrong here? I'm including a file while buffering output. The required file config.php holds a variable and function. When including some_file.php during the buffer, the variable $A is apparently NOT set/accessible. The function foo CAN execute.

The documentation says:
When a file is included, the code it contains inherits the variable
scope of the line on which the include occurs. Any variables available
at that line in the calling file will be available within the called
file, from that point forward. However, all functions and classes
defined in the included file have the global scope.

Your provided code does not illustrate the problem that you're describing. When I run it as-is, it correctly shows that the variable is defined.
That being said, the thing to remember is that what looks like a global variable in an included file actually ends up in the scope of the function that's calling it. So if the first time require_once() is called is from a function, the $A variable is scoped to the function - and disappears when the function returns, just like any other variable defined inside the function.
If you absolutely must define a global variable inside an included file (are you sure? really?), make sure you only include that file from the global scope - not from within a function. If you need to access the variable from within a function, include the file outside the function, and then use the global keyword to access the variable from within the function.

Related

PHP - Accessing variables in an included script from an included script

I have a list of files that I require_once at the beginning of my main scripts.
In one of those files, I have a bunch of functions.
In another one of those files, I have a bunch of constants (which are variables at the moment, but they are essentially constants).
Main.php
require_once \Constants.php
require_once \Functions.php
From within main.php, I am able to call functions and call the constants from their respective scripts... I am also able to call functions and pass the constants from Constants.php as parameters to the functions.
However, I am not able to use functions that have the constants embedded within them.
In other words, I cannot use the functions from Functions.php that already have the variables from the Constants.php file within the functions, but I am able to use functions from Functions.php if they do not have any variables from other included files within the function.
Function FirstFunction(){ echo $Constant1; return 1 }
FirstFunction() uses $Constant1 from Constants.php and does not work.
Function SecondFunction($param){ echo $param; return 1 }
SecondFunction() can be passed $Constant1 from Constants.php as a parameter and it works fine.
Questions:
Is there a way for me be able to use my Main.php to call a function file and a constant file and have the function file use variables from the constant file without explicitly calling or passing them from within Main.php?
If I were to daisy chain them (Main.php calls Functions.php; Functions.php calls Constants.php) will this work? (I kind of tried this but not well enough to either trust or rule out this method just yet).
Note
Most of the information I am able to find is regarding using variables from included files, but not specifically about included files using variables from other included files.
This sounds like a simple scope issue, that has nothing to do with your include-cycle.
When you create your 'constants' as normal PHP-variables ($name='value';), in the root scope of the Constants.php, then they must be called inside any later functions, by referencing them first ... like this:
$name='value';
/** other stuff **/
function Foo(){
global $name;
//You have access to $name here
}
The true solution tho, is to actually define your constants as real constants, which makes them available in any scope ... like this:
define('NAME','value');
/** other stuff **/
function Foo(){
//You immediately have access to NAME here
}
Only downside to true constants is, that they are constant ... meaning, they can’t be changed at a later point in your script.
You can read more about 'scope' here: http://php.net/manual/en/language.variables.scope.php
include() works as if the contents of the file being included are literally cut/paste into the spot where the include() call is:
variables.php:
<?php
$foo = 'bar';
test.php:
<?php
var_dump($foo); // notice: undefined variable
include('variables.php');
var_dump($foo); // string(3) "bar"
Note that standard PHP variable scoping rules apply. So if you do the include() inside a function:
<?php
var_dump($foo); // notice: undefined variable
function test() {
var_dump($foo); // notice: undefined variable
include('variables.php');
var_dump($foo); // string(3) "bar"
}
test(); // call the test function
var_dump($foo); // notice: undefined variable
notice how $foo doesn't exist before/after the function is defined/called - it will only exist WITHIN the function, and only AFTER it's been included().
If you want your standard variables to be truly global, you'll have to include the file at a global scope, or declare them global:
variables.php:
<?php
global $foo;
$foo = 'bar';
and then using the same script, $foo will "magically" appear for the final var_dump, because it's been made global.

global variables scope in php

I didn't understand this sentence from php.net:
Note:
Using global keyword outside a function is not an error. It can be used if the file is included from inside a function.
what does it mean? can anyone demonstrate briefly?
Global Variables:
In contrast to local variables, a global variable can be accessed in any part of the program. However, in order to be modified, a global variable must be explicitly declared to be global in the function in which it is to be modified. This is accomplished, conveniently enough, by placing the keyword GLOBAL in front of the variable that should be recognized as global. Placing this keyword in front of an already existing variable tells PHP to use the variable having that name.
Example
$somevar = 15;
function addit(){
GLOBAL $somevar;
$somevar++;
print "Somevar is $somevar";
}
addit();
Output
Somevar is 16
"It can be used if the file is included from inside a function" means that it will even work like this:
page.php
<?php
global $d;
$d = "HI";
?>
index.php
<?php
getpage();
function getpage(){
include 'page.php';
echo $d;
}
?>

PHP Variable Scope Issue

In my code, I use a public load_snippet function of a class when I need to include HTML or PHP snippets. (I do this instead of a direct include_once because the directory structure varies depending on certain variables).
I had some issues with variable scopes, so I've narrowed down the problem to this: let's say I define a variable within my page:
$variable = 'Hello World!";
Then, I need load in a snippet:
$APP->load_snippet("slider");
The snippet renders perfectly, except that PHP gives an undefined variable error if I try to reference $variable in the slider code. If I directly include the php file, it works as expected, so I don't understand why I'm having this problem, since this is the load_snippet function:
public function load_snippet($snippet){
if(file_exists("app/".$this->APP_TYPE."/snippets/".$snippet.".php")){
include "app/".$this->APP_TYPE."/snippets/".$snippet.".php";
}
else{
include 'common/txt/404.txt';
}
}
Any help you can give me is much appreciated.
The file is being included within the context of the load_snippet() function, and therefore has only those variables which exist within that function. One way to modify this is to make your function accept two variables: the filename and an array of values.
public function load_snippet($snippet, $content) {
if (is_array($content)) extract($content);
if (file_exists("app/".$this->APP_TYPE."/snippets/".$snippet.".php")) {
include "app/".$this->APP_TYPE."/snippets/".$snippet.".php";
} else {
include 'common/txt/404.txt';
}
}
Then
$arr = array('variable' => 'Hello world!');
load_snippet('slider', $arr);
I think include inside a function makes no sense to me... I think that you should put in function
global $variable;
Note that include will put the code inside the function(include will be replaced by code) as i know..
The way you are doing it is an ugly one, but you can use global $variable inside the snipped to refer to the variable. However if you include the snipped inside a function or a method, you'll have to make the variables in that function/method global as well
If you need $variable inside of the App::load_snippet() method, it would probably be best to pass it in:
public function load_snippet($snippet, $var='Hello world'){
if(file_exists("app/".$this->APP_TYPE."/snippets/".$snippet.".php")){
include "app/".$this->APP_TYPE."/snippets/".$snippet.".php";
}else{
include 'common/txt/404.txt';
}
}
//do something with $var
}
You can set a default for when $variable hasn't been set. No globals, no out of scope variables.
Instead you can use the constants like define('VARIALABLE','value'). which will be available to you anywhere in your file
You are including inside a class. Which means that the included file has the same variable scope as the line of code which includes it has. TO fix this all you need to do is put
global $variable;
Above the include.

Unable to access global variable in included file

I am having an unexpected issue with scope. The include documentation (also applies to require_once) says the required file should have access to all variable at the line it was required.
For some reason I am not able to access a class instantiated with global scope inside a function that was required in.
Would anyone know why? I am obviously missing something.
I got it working through a reference to $GLOBALS[], but I still want to know why it is not working.
UPDATE:
The error I am getting is:
Fatal error: Call to a member function isAdmin() on a non-object in <path>.php on <line>
Code:
$newClass = new myClass();
require_once("path to my file");
----- inside required file -----
function someFunction() {
$newClass->someMethod(); // gives fatal error. (see above).
}
Functions define a new scope, so inside a function you cannot access variables in the global scope.
Variable Scope
within user-defined functions a local
function scope is introduced. Any
variable used inside a function is by
default limited to the local function
scope
About included files, the manual states:
When a file is included, the code it
contains inherits the variable scope
of the line on which the include
occurs.
So if you include something in a function, the included file's scope will be that of the function's.
UPDATE: Looking at your code example edited into the question, global $newClass; as the first line of the function should make it working.
$newClass = new myClass();
require_once("path to my file");
----- inside required file -----
function someFunction() {
global $newClass;
$newClass->someMethod();
}
Be aware though that using global can quickly make your code more difficult to maintain. Don't rely on the global scope, you can pass the object to the function as a parameter, or use a Singleton/Registry class (some tend to argue against the latter, but depending on the case it can be a cleaner solution).
The included code doesn't have a scope different than the code surrounding it. For example:
function a() {
echo $b;
}
This will fail even if echo $b is in an included file. If you replace the above with:
function a() {
include 'file.php';
}
... and file.php contains:
echo $b;
... then it's the same thing as if you wrote:
function a() {
echo $b;
}
Think of it this way: whenever you use include / require, the contents of the included file is going to replace the include / require statement, just as if you removed the statement and pasted the contents of the file in its place.
It doesn't do anything else as far as scope is concerned.

How to Pass a variable into an include file?

I have use
include ('base.php')
script in my other scripts ( more.php). Now base.php should receive one variable from more.php. How to pass a variable from more.php into base.php?
If you include a script file A into a script file B, then A has the same global variable scope as B has:
When a file is included, the code it contains inherits the variable scope of the line on which the include occurs. Any variables available at that line in the calling file will be available within the called file, from that point forward. However, all functions and classes defined in the included file have the global scope. — include manual page
So if you define a variable in A, then you have access to that variable in B:
// A.php
$varInA = 'foobar';
include 'B.php';
// B.php
echo $varInA;
Create a function within base.php, like so:
function setup($config) {
// Do something with config
}
and call it from more.php..
setup($somevar);
Or, you could try using classes and member variables and constructors.

Categories