PHP templating and variable scope - php

i am trying to find out a way to pass non global variables to included document.
page1.php
function foo()
{
$tst =1;
include "page2.php";
}
page2.php
echo $tst;
How can i make that variable be visible ? and how would i do this php templating so i can split header body and footer for html pages. like in a wordpress it has custom wp functions but i dont see them declaring external files to use them.
big thanks in advance.

I think you are not exactly understanding what is going on. Page 1 should probably be doing the echoing. So you include page 2 and the foo function is now available. You need to call it so that it actually executes. Use the global keyword to bring a global variable into the function scope. Then you can echo it.
page1:
include "page2.php";
foo();
echo $test;
page 2:
function foo()
{
global $test;
$test =1;
}

Variables in a function are not seen outside of them when they are not global. But an include in a function should be seen inside the second file.
$test="Big thing";
echo "before testFoo=".$test;
// now call the function testFoo();
testFoo();
echo "after testFoo=".$test;
Result : *after testFoo=Big thing*
function testFoo(){
// the varuiable $test is not known in the function as it's not global
echo "in testFoo before modification =".$test;
// Result :*Notice: Undefined variable: test in test.php
// in testFoo before modification =*
// now inside the function define a variable test.
$test="Tooo Big thing";
echo "in testFoo before include =".$test;
// Result :*in testFoo before include =Tooo Big thing*
// now including the file test2.php
include('test2.php');
echo "in testFoo after include =".$test;
// we are still in the function testFoo() so we can see the result of test2.php
// Result :in testFoo after include =small thing
}
in test2.php
echo $test;
/* Result : Tooo Big thing
as we are still in testFoo() we know $test
now modify $test
*/
$test = "small thing";
I hope that made the things more clear.

Related

php how to access language variable inside a function when the language page has already been included?

My php script includes another en.php file which contains the required english strings. This same page also calls a html page which uses the file and formats it using the contents of the en.php file.
I have a function in this script which references variables defined in the included script but I am getting error messages of the variable not being found. If I reference the variable outside the function, the variable is accessed correctly. Why can I not access these variables inside the function?
en.php
<?php
$lang_yes = 'Yes';
$lang_no = 'No';
?>
example.php
<?php
include_once('addons/assq/lang/en.php');
echo $lang_yes;
$q1 = convertToYesOrNoString(0);
echo $q1;
function convertToYesOrNoString($value){
//include_once('addons/assq/lang/en.php');
if ($value == 0){
return $lang_no;
}else if ($value == 1){
return $lang_yes;
}else{
return "---";
}
}
?>
My output is as follows:
Yes
Undefined variable: lang_no in example.php on the line in the function
I tried including the en.php directly into the function but that did not work either. How can I access these variables inside my function while including the file as implemented above?
You can either define it as a constant, pass it as an argument or declare it as a global within the function:
function convertToYesOrNoString($value){
global $lang_no, $lang_yes;
//...
}
That's a scope issue. That variable $lang_no will not be accessed under that function , you need to pass that as a parameter instead to the function definition.
function convertToYesOrNoString($value,$lang_no){ //<--- Like this.
Since you have mentioned that you have a lot of parameters .. you can write a turnaround like this...
Your en.php
<?php
//Map all those variables inside an array as key-value pair. as shown
$varArray=array('lang_yes'=>'Yes','lang_no'=>'No');
Some test.php
<?php
include('en.php');
function convertToYesOrNoString($varArray)
{
extract($varArray);
echo $lang_yes; // "prints" Yes
echo $lang_no; // "prints" No
}
convertToYesOrNoString($varArray);

how to access a php variable inside a function from an included file

I have a file called test1.php with lots of variable and some function definitions. I am trying to include this file to one another file called test2.php and use the variables and the functions.
test1.php
$i = "a";
$ii = "b";
$iii = "c";
function test1a(){ return "lol"; }
test2.php
function test2a(){ include 'test1.php'; return $i; }
function test2b() { include 'test1.php'; return test2c(); }
function test2c(){ include 'test1.php'; return $iii; }
function test2d() { include 'test1.php'; return test1a(); }
index.php
include 'test2.php'
echo test2a();
echo test2b();
echo test2c();
echo test2d();
Reason:
I have the same code base in two different servers. Only the test2.php file will be different.Each server will have different values inside the test2.php but with same variable name. test2.php will act somewhat like a localization file.
My problem is some of the variables or not showing up. Is there a better way to do this. I don't want to include the file in every function.
Thanks.
Just do it the other way round:
put all the different variables into one file in to an array, without any functions:
//config.php
$config['setting1'] = "val1";
$config['setting2'] = "val2";
$config['setting3'] = 42;
...
and further:
//index.php
include_once("config.php");
echo $config['setting1'];
....
now you may have different configs on different servers w/o need to change any functions.
You are trying to include file with one function several times. Functions are always global. So second include gives you an fatal error Fatal error: Cannot redeclare test1a() (previously declared in [..]).
You should put this function to separate file and use include_once.

How can I pass the currently defined variables into an included file by a function

I am trying to include a file using a function, and I have several variables defined. I want to access the included file to access the variables, but because I am including it using a function, it is not accessible. The sample scenerio is as follows:
i.e the contents of index is as follows
index.php
<?
...
function include_a_file($num)
{
if($num == 34)
include "test.php";
else
include "another.php"
}
...
$greeting = "Hello";
include_a_file(3);
...
?>
And the contents of test.php is as follows
test.php
<?
echo $greeting;
?>
The test file is throwing a warning saying the $greeting is not defined.
This will not work. include and require act as if the code you're including was literally part of the file at the point the include/require was executed. As such, your external files are going to be in the scope of the include_a_file() function, which means $greeting is OUT OF SCOPE within that function.
You'll have to either pass it in as a parameter, or make it global within the function:
function include_a_file($num, $var) {
^^^^-option #1
global $greeting; // option #2
}
$greeting = 'hello';
include_a_file(3, $greeting);
Are you sure your correctly including? And remember PHP is case sensitive:
$Test = "String";
$TEst = "String";
Both completely different variables..
Furthermore, don't just echo out a variable, wrap it within in a isset condition:
if (isset($greeting)){
echo $greeting;
} // Will only echo if the variable has been properly set..
Or you could use:
if (isset($greeting)){
echo $greeting;
}else{
echo "Default Greeting";
}

What issue(s) does include_once or require_once solve?

From the php manual
Include_once may help avoid problems such as function redefinitions, variable value reassignments, etc.
Ok, so include_once solves issues with function redefinitions, variable value reassignments, etc. but why are they an issue in the first place ?
I'm trying to understand what kind of risks are involved in redefining functions or reassigning variable values except for a decline in performance due to additional input/output and processing ?
Is it because php parser gets confused which version of function to load/use or is the original version of the function lost once redefined? What else and what about variable reassignments?
I do understand where to use include vs include_once.
Imagine the following include file, hello.php:
function hello()
{
return 'Hello World';
}
$a = 0;
Now imagine the following file, index.php:
include 'hello.php';
$a = 1;
hello();
include 'hello.php';
hello();
echo $a; // $a = 0, not 1
Your code would now have a fatal error, since the function has been defined twice. Using include_once would avert this, since it would only include hello.php once. Also, to do with variable value reassignment, $a (should the code compile) would be reset to 0.
From the comments, please consider this a side answer - If you're looking for something where resetting a set of variables many times was required, I'd look to use a class for this with a method like Reset, you can even make it static if you didn't want to have to instantiate it, like so:
public class MyVariables
{
public static $MyVariable = "Hello";
public static $AnotherVariable = 5;
public static function Reset()
{
self::$MyVariable = "Hello";
self::$AnotherVariable = 5;
}
}
Usage like:
MyVariables::$MyVariable = "Goodbye";
MyVariables::Reset();
echo MyVariables::$MyVariable; // Hello
Let's say you have an include script vars.inc.php:
<?php
$firstname = 'Mike';
$lastname = 'Smith';
?>
And then you have a script script.php:
<?php
echo "$firstname $lastname"; // no output
include('vars.inc.php');
echo "$firstname $lastname"; // Mike Smith
$firstname = "Tim";
$lastname = "Young";
echo "$firstname $lastname"; // Tim Young
include('vars.inc.php');
echo "$firstname $lastname"; // Mike Smith
?>
What happens is that if you modify your vars in code exection and then you include once again the file defining them, you are changing their content. include_once will ensure that this will never happens throwing an error.
It will stop you loading pages more than once. Typically you'll use this at the top of your pages to bring in your init, function, class files etc.
Especially useful if you are loading pages within pages dynamically.

run function block in context of global namespace in PHP

So the senario is that I want to have a custom function for requiring libraries. Something like:
define('E_ROOT', str_replace('//','/',dirname(__FILE__)));
/* ... */
function e_load($fn, $allowReloading = FALSE) {
$inc = E_ROOT.'/path/here/'.$fn.'.php';
if($allowReloading)
require $inc; // !!!
else
require_once $inc; // !!!
}
The problem being that require and require_once will load the files into the namespace of the function, which doesn't help for libraries of functions, classes, et cetera. So is there a way to do this?
(Something avoiding require and require_once altogether is fine, as long as it doesn't use eval since it's banned on so many hosts.)
Thanks!
Technically include() is meant to act as though you're inserting the text of included script at that point in your PHP. Thus:
includeMe.php:
<?php
$test = "Hello, World!";
?>
includeIt.php:
<?php
include('includeMe.php');
echo $test;
?>
Should be the exact same as:
<?php
/* INSERTED FROM includeMe.php */
$test = "Hello, World!";
/* END INSERTED PORTION */
echo $test;
?>
Realizing this, the idea of making a function for dynamically including files makes about as much sense (and is about as easy to do) as having dynamic code all-together. It's possible, but it will involve a lot of meta-variables.
I'd look into Variable Variables in PHP as well as the get_defined_vars function for bringing variables into the global scope. This could be done with something like:
<?php
define('E_ROOT', str_replace('//','/',dirname(__FILE__)));
/* ... */
function e_load($fn, $allowReloading = FALSE) {
$prev_defined_vars = get_defined_vars();
$inc = E_ROOT.'/path/here/'.$fn.'.php';
if($allowReloading)
require $inc; // !!!
else
require_once $inc; // !!!
$now_defined_vars = get_defined_vars();
$new_vars = array_diff($now_defined_vars, $prev_defined_vars);
for($i = 0; $i < count($new_vars); $i++){
// Pull new variables into the global scope
global $$newvars[$i];
}
}
?>
It may be more convenient to just use require() and require_once() in place of e_load()
Note that functions and constants should always be in the global scope, so no matter where they are defined they should be callable from anywhere in your code.
The one exception to this is functions defined within a class. These are only callable within the namespace of the class.
EDIT:
I just tested this myself. Functions are declared in the global scope. I ran the following code:
<?php
function test(){
function test2(){
echo "Test2 was called!";
}
}
//test2(); <-- failed
test();
test2(); // <-- succeeded this time
?>
So the function was only defined after test() had been run, but the function was then callable from outside of test(). Therefore the only thing you should need to pull into the global scope are your variables, via the script I provided earlier.
require_once E_ROOT.$libName.'.php';
KISS
Instead of doing this...
$test = "Hello, World!";
... you could consider doing this ...
$GLOBALS[ 'test' ] = "Hello, World!";
Which is safe and consistent in both local function context, and global include context. Probably not harmful to visually remind the reader that you are expecting $test to become global. If you have a large number of globals being dragged in by your libraries maybe there's justification for wrapping it in a class (then you have the benefit of spl_autoload_register which kind of does what you are doing anyhow).

Categories