Global Variables in static PHP classes - php

Is there a way to use a global variable everywhere in the code?
I want to use a Path variable to the located configured Folder in each Path I'll declare in my code.
Here's my Code:
Index.php
<?php
require_once('Common.php');
require_once('Path.php');
?>
Common.php
<?php
$RootPath = '.';//in this case its root
//add the RootPath for global using
$GLOBALS['RootPath'] = $RootPath;
?>
Path.php
<?php
class Path {
public static $TemplatePath = $GLOBALS['RootPath'].'/Template.php';
}
?>
This won't work because it says, "Parse error: syntax error, unexpected T_VARIABLE" when I try to call $GLOBALS when declaring a static variable.
Is there a way to do this?
Thanks in Anticipation
Alex

What you are looking for are constants.
It's very common to use them to define certain path's, f.e.
define('PATH_ROOT', $_SERVER['DOCUMENT_ROOT']);
define('PATH_TEMPLATES', PATH_ROOT.'/templates');

Class constants and static class variables cannot be initialized with dynamic data.
What about defining method instead?
class Path {
public static getTemplatePath()
{
return $GLOBALS['RootPath'].'/Template.php';
}
}
And why you would keep settings as global variables, and not encapsulate them in some kind of Registry?

whenever you want to use a global variable inside a function that is out of the scope, you must first declare it within the function/class method with "global $varname".
In your case:
Common.php
<?php
$RootPath = '.';//in this case its root
//add the RootPath for global using
// $GLOBALS['RootPath'] = $RootPath; // no need for this, $[GLOBALS] is about the Superglobals, $_SERVER, $_SESSION, $_GET, $_POST and so on, not for global variables.
?>
Path.php
<?php
class Path {
public static $TemplatePath;// = $GLOBALS['RootPath'].'/Template.php';
public method __construct(){
global $RootPath;
self::TemplatePath = $RootPath.'/Template.php';
}
}
?>

Tranform your (bad) public static attribute, to a public static getter/setter.
Also, global variables are a bad pratice, introducing side effect and name collision.

Related

Access global variable from other document

I'm starting with OOP in PHP and I have an issue with global variables.
Example of my current structure:
test.php REQUIRES globals.php and also INCLUDES classes.php.
globals.php has this code:
global $something;
$something = "my text";
and classes.php looks like this:
global $something;
class myClass {
public $abc = "123";
public $something;
public function doSomething() {
echo $this->abc."<br>";
echo $this->something;
}
}
$class = new myClass();
$class_Function = $class->doSomething();
print_r($class_Function);
At the end, test.php only shows "123".
I tried using "include()" instead of "require" for globals.php but didn't work. Neither did including globals.php in classes.php.
$this->something was never initialized. The global $something is totally outside of scope and is not related to the class attribute $this->something. If you need to access a global inside a function or method you need to declare it as global:
public function doSomething() {
global $something;
echo $this->abc."<br>";
echo $something;
}
However you need to stop using globals because is not a good solution. If you need do define some constant values that are global to your system it's prefered to use define()
define("SOMETHING","My text")
And then you can access it in any part of your code:
echo SOMETHING;
Also see: PHP global variable scope inside a class
and Use external variable inside PHP class

Global variable in object created from another object

There are two classes, each one in its own file:
<?php
namespace test;
class calledClass {
private $Variable;
function __construct() {
global $testVar;
require_once 'config.php';
$this->Variable = $testVar;
echo "test var: ".$this->Variable;
}
}
?>
and
<?php
namespace test;
class callingClass {
function __construct() {
require_once 'config.php';
require_once 'calledClass.php';
new calledClass();
}
}
new callingClass();
?>
and simple config.php:
<?php
namespace test;
$testVar = 'there is a test content';
?>
When I start callingClass.php (which creates object calledClass), the property $Variable in calledClass is empty. But when I start calledClass.php manually, it reads meaning $testVar from config.php, and assumes it to $Variable.
If I declare $testVar as global in callingClass, it helps - calledClass can read $testVar from config.php.
Can somebody tell me why an object created from another object can't declare variables as global, and use them?
When including (include/require) a file inside a function, all variable declarations inside that file get the scope of the function. So $testVar is created within the scope of callingClass::__construct. Since you use require_once, it will not be re-created elsewhere inside calledClass::__construct! It works when calling only calledClass since you're actually including the file for the first time there.
It has nothing to do with OOP at all, just the rules of function scope and your particular use of require_once.

Passing variables to an included file

I have a template class which goes like this:
class Template{
public $pageTitle = "";
public function __construct($pageTitle){
$this->pageTitle = $pageTitle;
}
public function display(){
include "/includes/head.php";
include "/includes/body.php";
}
}
Now, I'm used to Java's workings but I don't understand why I'm getting an undefined variable ($pageTitle) error. The included files need to be able to access that variable. I know it's going to be very simple but I actually haven't found out why.
What do I need to do to allow includes to see this variable?
The includes will also have to use $this->pageTitle. Effectively, the include makes them part of the method body.
The included file lives in the same scope as your object. So you need to call:
$this->pageTitle
If you don't want to do the whole $this->, you can do something like the following... The extract function will extract the array $this->data into variables with names respective to the key/index of each item. So now you will be able to do echo $pageTitle;
class Template{
public $data = Array();
public function __construct($pageTitle){
$this->data['pageTitle'] = $pageTitle;
}
public function display(){
extract($this->data);
include "/includes/head.php";
include "/includes/body.php";
}
}
Scope is a little different in PHP than in java.
For your specific case you need
$this->pageTitle
To access a variable declared outside the class, you'll need to make it global
global $myVar;

alias to include

i have alias to include() in my functions.php file:
function render_template($template)
{
include($template);
}
and simple template.html :
Hello, <?php echo $name ?>
But unfortunately, alias function gave me this output:
require 'functions.php';
$name = "world";
include('template.html'); // Hello, world
render_template('template.html'); // PHP Notice:Undefined variable: name
why is that? and how i can fix this?
thanks.
You have two more options to make it work around the scope issue. (Using global would require localising a long list of vars. Also it's not actually clear if your $name resides in the global scope anyway and always.)
First you could just turn your render_template() function into a name-resolver:
function template($t) {
return $t; // maybe add a directory later on
}
Using it like this:
$name = "world";
include(template('template.html'));
Which is nicer to read and has obvious syntactical meaning.
The more quirky alternative is capturing the local variables for render_template:
$name = "world";
render_template('template.html', get_defined_vars());
Where render_template would require this addition:
function render_template($template, $vars)
{
extract($vars); // in lieu of global $var1,$var2,$var3,...
include($template);
}
So that's more cumbersome than using a name-resolver.
The variable $name is not visible at the point where include is called (inside function render_template). One way to fix it would be:
function render_template($template)
{
global $name;
include($template);
}
Its a Scope Problem, you can set the variable to global, or encapsulate the whole thing a little bit more, for example like that:
class view{
private $_data;
public function __construct(){
$this->_data = new stdClass();
}
public function __get($name){
return $this->_data->{$name};
}
public function __set($name,$value){
$this->_data->{$name} = $value;
}
public function render($template){
$data = $this->_data;
include($template);
}
}
$view = new view;
$view->name = "world";
$view->render('template.html');
template.html :
Hello <?php print $data->name; ?>
If $name is in the global scope then you can get around it by declaring the variable global with the function. But a better solution would be to re-architect the code to require passing the relevant variable value into the function.
This is expected.
Look here.
You would be interested in the following quote, "If the include occurs inside a function within the calling file, then all of the code contained in the called file will behave as though it had been defined inside that function. So, it will follow the variable scope of that function. An exception to this rule are magic constants which are evaluated by the parser before the include occurs".

create superglobal variables in php?

is there a way to create my own custom superglobal variables like $_POST and $_GET?
Static class variables can be referenced globally, e.g.:
class myGlobals {
static $myVariable;
}
function a() {
print myGlobals::$myVariable;
}
Yes, it is possible, but not with the so-called "core" PHP functionalities. You have to install an extension called runkit7:
Installation
After that, you can set your custom superglobals in php.ini as documented here:
ini.runkit.superglobal
I think you already have it - every variable you create in global space can be accessed using the $GLOBALS superglobal like this:
// in global space
$myVar = "hello";
// inside a function
function foo() {
echo $GLOBALS['myVar'];
}
Class Registry {
private $vars = array();
public function __set($index, $value){$this->vars[$index] = $value;}
public function __get($index){return $this->vars[$index];}
}
$registry = new Registry;
function _REGISTRY(){
global $registry;
return $registry;
}
_REGISTRY()->sampleArray=array(1,2,'red','white');
//_REGISTRY()->someOtherClassName = new className;
//_REGISTRY()->someOtherClassName->dosomething();
class sampleClass {
public function sampleMethod(){
print_r(_REGISTRY()->sampleArray); echo '<br/>';
_REGISTRY()->sampleVar='value';
echo _REGISTRY()->sampleVar.'<br/>';
}
}
$whatever = new sampleClass;
$whatever->sampleMethod();
One other way to get around this issue is to use a static class method or variable.
For example:
class myGlobals {
public static $myVariable;
}
Then, in your functions you can simply refer to your global variable like this:
function Test()
{
echo myGlobals::$myVariable;
}
Not as clean as some other languages, but at least you don't have to keep declaring it global all the time.
No
There are only built-in superglobals listed in this manual
Not really. though you can just abuse the ones that are there if you don't mind the ugliness of it.
You can also use the Environment variables of the server, and access these in PHP
This is a good way to maybe store global database access if you own and exclusively use the server.
possible workaround with $GLOBALS:
file.php:
$GLOBALS['xyz'] = "hello";
any_included_file.php:
echo $GLOBALS['xyz'];
One solution is to create your superglobal variable in a separate php file and then auto load that file with every php call using the auto_prepend_file directive.
something like this should work after restarting your php server (your ini file location might be different):
/usr/local/etc/php/conf.d/load-my-custom-superglobals.ini
auto_prepend_file=/var/www/html/superglobals.php
/var/www/html/superglobals.php
<?php
$_GLOBALS['_MY_SUPER_GLOBAL'] = 'example';
/var/www/html/index.php
<?php
echo $_MY_SUPER_GLOBAL;
Actually, there is no direct way to define your own superglobal variables; But it's a trick that I always do to access simpler to my useful variables!
class _ {
public static $VAR1;
public static $VAR2;
public static $VAR3;
}
Then I want to use:
function Test() {
echo \_::$VAR2;
}
Notice: Don't forget to use \ before, If you want to use it everywhere you have a namespace too...
Enjoy...

Categories