Consider the following situation
file: ./include/functions/table-config.php
containing: .
.
$tablePages = 'orweb_pages';
.
.
file: ./include/classes/uri-resolve.php
containing: class URIResolve {
.
.
$category = null ;
.
.
function process_uri() {
...
$this->category = $tablePages;
...
}
.
.
}
file: ./settings.php
containing: .
.
require_once(ABSPATH.INC.FUNC.'/table-config.php');
require_once(ABSPATH.INC.CLASS.'/uri-resolve.php');
.
.
Will this work. I mean will the access to $tablePages from process_uri() be acceptable or will it give erronous results.
Please suggest corrections or workarounds if error might occur.
Use the global keyword:
In the file where you're assigning the value.
global $tablePages;
$tablePages = 'orweb_pages';
And in the other file:
class URIResolve {
var $category;
function process_uri() {
global $tablePages;
$this->category = $tablePages;
}
}
Also, all global variables are available in the $GLOBALS array (which itself is a superglobal), so you can access the global variable anywhere without using the global keyword by doing something like this:
$my_value = $GLOBALS['tablePages'];
This also serves to make it harder to accidentally overwrite the value of the global. In the former example, any changes you made to $tablePages would change the global variable. Many a security bug has been created by having a global $user and overwriting it with a more powerful user's information.
Another, even safer approach is to provide the variable in the constructor to URIResolve:
class URIResolve {
var $category;
function __construct ($tablePages) {
$this->category= $tablePages;
}
function process_uri() {
// Now you can access table pages here as an variable instance
}
}
// This would then be used as:
new URIResolve($tablePages);
Use a global (not recommended), a constant or a singleton configuration class.
Simply including
$tablePages = 'orweb_pages';
will give your variable local scope so it won't be visible inside other classes. If you use a constant:
define('TABLE_PAGES', 'orweb_pages');
TABLE_PAGES will be available for read access throughout the application regardless of scope.
The advantage of a constant over a global variable is that you dont have to worry about it being overridden in other areas of the application.
<?php
//Use variable php : $GLOBALS in __construct
$x = "Example variable outer class";
class ExampleClass{
public $variables;
function __construct()
{
$this->variables = $GLOBALS; //get all variables from $GLOBALS
}
// example get value var
public function UseVar(){
echo $this->variables['x']; // return Example variable outer class
}
// example set value var
public function setVar(){
$this->variables['x'] = 100;
}
}
echo $x // return Example variable outer class;
$Example = new ExampleClass();
$Example->UseVar(); // return Example variable outer class
$Example->setVar(); // $x = 100;
// or use attr variables
echo $Example->variables['x']; // 100
$Example->variables['x'] = "Hiii";
?>
Related
I have code something like this:
<?
$a="localhost";
function body(){
global $a;
echo $a;
}
function head(){
global $a;
echo $a;
}
function footer(){
global $a;
echo $a;
}
?>
is there any way to define the global variable in one place and make the variable $a accessible in all the functions at once? without making use of global $a; more?
The $GLOBALS array can be used instead:
$GLOBALS['a'] = 'localhost';
function body(){
echo $GLOBALS['a'];
}
From the Manual:
An associative array containing references to all variables which are currently defined in the global scope of the script. The variable names are the keys of the array.
If you have a set of functions that need some common variables, a class with properties may be a good choice instead of a global:
class MyTest
{
protected $a;
public function __construct($a)
{
$this->a = $a;
}
public function head()
{
echo $this->a;
}
public function footer()
{
echo $this->a;
}
}
$a = 'localhost';
$obj = new MyTest($a);
If the variable is not going to change you could use define
Example:
define('FOOTER_CONTENT', 'Hello I\'m an awesome footer!');
function footer()
{
echo FOOTER_CONTENT;
}
If a variable is declared outside of a function its already in global scope. So there is no need to declare. But from where you calling this variable must have access to this variable. If you are calling from inside a function you have to use global keyword:
$variable = 5;
function name()
{
global $variable;
$value = $variable + 5;
return $value;
}
Using global keyword outside a function is not an error. If you want to include this file inside a function you can declare the variable as global.
// config.php
global $variable;
$variable = 5;
// other.php
function name()
{
require_once __DIR__ . '/config.php';
}
You can use $GLOBALS as well. It's a superglobal so it has access everywhere.
$GLOBALS['variable'] = 5;
function name()
{
echo $GLOBALS['variable'];
}
Depending on your choice you can choose either.
Add your variables in $GLOBALS super global array like
$GLOBALS['variable'] = 'localhost';
and use it globally as
echo $GLOBALS['variable']
or you can use constant which are accessible throughout the script
define('HOSTNAME', 'localhost');
usage for define (NOTE - without the dollar)
echo HOSTNAME;
This answer is very late but what I do is set a class that holds Booleans, arrays, and integer-initial values as global scope static variables. Any constant strings are defined as such.
define("myconstant", "value");
class globalVars {
static $a = false;
static $b = 0;
static $c = array('first' => 2, 'second' => 5);
}
function test($num) {
if (!globalVars::$a) {
$returnVal = 'The ' . myconstant . ' of ' . $num . ' plus ' . globalVars::$b . ' plus ' . globalVars::$c['second'] . ' is ' . ($num + globalVars::$b + globalVars::$c['second']) . '.';
globalVars::$a = true;
} else {
$returnVal = 'I forgot';
}
return $returnVal;
}
echo test(9); ---> The value of 9 + 0 + 5 is 14.
echo "<br>";
echo globalVars::$a; ----> 1
The static keywords must be present in the class else the vars $a, $b, and $c will not be globally scoped.
You can try the keyword use in Closure functions or Lambdas if this fits your intention... PHP 7.0 though. Not that's its better, but just an alternative.
$foo = "New";
$closure = (function($bar) use ($foo) {
echo "$foo $bar";
})("York");
demo |
info
You can declare global variables as static attributes:
class global {
static $foo = "bar";
}
And you can use and modify it every where you like, like:
function echoFoo() {
echo global::$foo;
}
You answered this in the way you wrote the question - use 'define'. but once set, you can't change a define.
Alternatively, there are tricks with a constant in a class, such as class::constant that you can use. You can also make them variable by declaring static properties to the class, with functions to set the static property if you want to change it.
What if you make use of procedural function instead of variable and call them any where as you.
I usually make a collection of configuration values and put them inside a function with return statement. I just include that where I need to make use of global value and call particular function.
function host()
{
return "localhost";
}
$GLOBALS[] is the right solution, but since we're talking about alternatives, a function can also do this job easily:
function capital() {
return my_var() . ' is the capital of Italy';
}
function my_var() {
return 'Rome';
}
I have code something like this:
<?
$a="localhost";
function body(){
global $a;
echo $a;
}
function head(){
global $a;
echo $a;
}
function footer(){
global $a;
echo $a;
}
?>
is there any way to define the global variable in one place and make the variable $a accessible in all the functions at once? without making use of global $a; more?
The $GLOBALS array can be used instead:
$GLOBALS['a'] = 'localhost';
function body(){
echo $GLOBALS['a'];
}
From the Manual:
An associative array containing references to all variables which are currently defined in the global scope of the script. The variable names are the keys of the array.
If you have a set of functions that need some common variables, a class with properties may be a good choice instead of a global:
class MyTest
{
protected $a;
public function __construct($a)
{
$this->a = $a;
}
public function head()
{
echo $this->a;
}
public function footer()
{
echo $this->a;
}
}
$a = 'localhost';
$obj = new MyTest($a);
If the variable is not going to change you could use define
Example:
define('FOOTER_CONTENT', 'Hello I\'m an awesome footer!');
function footer()
{
echo FOOTER_CONTENT;
}
If a variable is declared outside of a function its already in global scope. So there is no need to declare. But from where you calling this variable must have access to this variable. If you are calling from inside a function you have to use global keyword:
$variable = 5;
function name()
{
global $variable;
$value = $variable + 5;
return $value;
}
Using global keyword outside a function is not an error. If you want to include this file inside a function you can declare the variable as global.
// config.php
global $variable;
$variable = 5;
// other.php
function name()
{
require_once __DIR__ . '/config.php';
}
You can use $GLOBALS as well. It's a superglobal so it has access everywhere.
$GLOBALS['variable'] = 5;
function name()
{
echo $GLOBALS['variable'];
}
Depending on your choice you can choose either.
Add your variables in $GLOBALS super global array like
$GLOBALS['variable'] = 'localhost';
and use it globally as
echo $GLOBALS['variable']
or you can use constant which are accessible throughout the script
define('HOSTNAME', 'localhost');
usage for define (NOTE - without the dollar)
echo HOSTNAME;
This answer is very late but what I do is set a class that holds Booleans, arrays, and integer-initial values as global scope static variables. Any constant strings are defined as such.
define("myconstant", "value");
class globalVars {
static $a = false;
static $b = 0;
static $c = array('first' => 2, 'second' => 5);
}
function test($num) {
if (!globalVars::$a) {
$returnVal = 'The ' . myconstant . ' of ' . $num . ' plus ' . globalVars::$b . ' plus ' . globalVars::$c['second'] . ' is ' . ($num + globalVars::$b + globalVars::$c['second']) . '.';
globalVars::$a = true;
} else {
$returnVal = 'I forgot';
}
return $returnVal;
}
echo test(9); ---> The value of 9 + 0 + 5 is 14.
echo "<br>";
echo globalVars::$a; ----> 1
The static keywords must be present in the class else the vars $a, $b, and $c will not be globally scoped.
You can try the keyword use in Closure functions or Lambdas if this fits your intention... PHP 7.0 though. Not that's its better, but just an alternative.
$foo = "New";
$closure = (function($bar) use ($foo) {
echo "$foo $bar";
})("York");
demo |
info
You can declare global variables as static attributes:
class global {
static $foo = "bar";
}
And you can use and modify it every where you like, like:
function echoFoo() {
echo global::$foo;
}
You answered this in the way you wrote the question - use 'define'. but once set, you can't change a define.
Alternatively, there are tricks with a constant in a class, such as class::constant that you can use. You can also make them variable by declaring static properties to the class, with functions to set the static property if you want to change it.
What if you make use of procedural function instead of variable and call them any where as you.
I usually make a collection of configuration values and put them inside a function with return statement. I just include that where I need to make use of global value and call particular function.
function host()
{
return "localhost";
}
$GLOBALS[] is the right solution, but since we're talking about alternatives, a function can also do this job easily:
function capital() {
return my_var() . ' is the capital of Italy';
}
function my_var() {
return 'Rome';
}
I have a small PHP snippet.
How can I assign a new value to my global from within a main class?
Example:
$GlobalValue = 0;
class SampleModuleController extends SampleController {
public function doSomething() {
$NewValue = 1;
$GlobalValue = $NewValue
}
}
echo $GlobalValue;
//This always echo's 0, When I try to output or print outside the class or use somewhere above in the php code.
//I need to be able to assign the new value from within my class
//and the function doSomething so it should be 1
You can pass parameter as reference in the method doSomething() and then call that function passing your variable $GlobalValue. However it's not very recommended to have global variables. You should consider change your code to more OOP.
$GlobalValue = 0;
class SampleModuleController {
private $newValue = 3;
public function doSomething(&$variable) {
$variable = $this->newValue;
}
}
$ModuleController = new SampleModuleController();
$ModuleController->doSomething($GlobalValue);
echo $GlobalValue; //print 1
If i understood it right what you are trying to do can be achieved quite easily with this:
global $GlobalValue;
$GlobalValue = 0;
class SampleModuleController {
public function doSomething() {
global $GlobalValue;
$NewValue = 1;
$GlobalValue = $NewValue;
}
}
$ModuleController = new SampleModuleController();
$ModuleController->doSomething();
echo $GlobalValue; //print 1
They key is in the "global" keyword (which is the same as accessing the $GLOBAL["your_var_name"] container.
Beside this, as others said relying on global variables should be discouraged.
I am new to PHP5 and classes, am struggling with being able to get global variable to work when inside a function, to better explain it please check the code bellow.
class alpha{
#first function
public function n_one(){
#variable
$varr = 1;
#inner function
function n_two(){
global $varr;
#Unable to get variable
echo $varr;
if($varr)
{
echo 'yessssss';
}
}
echo $varr // Returns variable fine
}
}
I seem to be doing something wrong violating how classes and functions work, can't figure what is it.
Move the 'inner function', and the property.
class Alpha
{
private $varr = 1;
public function n_one()
{
// to access a property ore another method, do this
$this->varr = $this->doSomething();
return $this->varr; // Returns variable fine
}
private function doSomething()
{
// manipulate $this->varr here
}
}
Also, don't ever echo from within the class, instead return the variable and echo it.
echo $alpha->n_one();
global means to access the variable in the global scope, not just the containing scope. When you refer to $varr in the inner function it's treated as $GLOBALS['varr'].
If you want it to refer to the same variable as in the outer function you need to declare the variable global there as well. Otherwise it's a local variable in that function, while the inner function accesses the global variable.
#first function
public function n_one(){
global $varr;
#variable
$varr = 1;
#inner function
function n_two(){
global $varr;
#Unable to get variable
echo $varr;
if($varr)
{
echo 'yessssss';
}
}
echo $varr // Returns variable fine
}
Alternatively you can use the use() declaration to declare a variable that should be inherited from the outer scope.
#inner function
function n_two() use($varr) {
global $varr;
#Unable to get variable
echo $varr;
if($varr)
{
echo 'yessssss';
}
}
I was wondering if anyone could help me understand this particular aspect of OO PHP as it has caught me out a few times now.
I have specified a var at the top of my file like so
$route = explode('/', $_SERVER["REQUEST_URI"]);
// Shorthand
$r1=$route[0]; $r2=$route[1]; $r3=$route[2];
I am then tring to use $r1 etc inside a function written just below the above code.
function edit($id)
{
$_SESSION['path'] = $r1 . "/" . $r2 . "/" . $r3;
require 'app/controller/edit.php';
new Controller($id);
}
The $r1,$r2, $r3 vars cannot be seen for some reason inside this function.
Notice: Undefined variable: r1 in C:\wamp\www\options.ex\public_html\app\options.php on line 77
If I were to pass the $r vars to the function, I'd image there would be no problem, but since they are declared globally I was wondering why they were not visible without doing this as their scope presumably is global?
Thanks.
EDIT - full code.
<?php
require_once 'load.php';
// Clean and prepare query string
$route = explode('/', $_SERVER["REQUEST_URI"]);
// Trim outer exmpty parameters caused by leading/trailing slash
if($route[count($route)-1]=='') unset($route[count($route)-1]);
if($route[0]=='') unset($route[0]);
$route = array_values($route);
// If any parameters are undefined, set them to ''
if(!isset($route[0])) { $route[0]=''; $route[1]=''; $route[2]=''; }
elseif(!isset($route[1])) { $route[1]=''; $route[2]=''; }
elseif(!isset($route[2])) { $route[2]=''; }
// Shorthand
$r1=$route[0]; $r2=$route[1]; $r3=$route[2];
// Choose route, else default to dash
if($r1=='dashboard' && $r2=='' && $r3=='') dashboard();
elseif($r1=='staff' && $r2=='add' && $r3=='') add_staff();
elseif($r1=='staff' && $r2=='edit' && $r3!='') edit_staff($r3);
else header("location: http://local.options.ex/dashboard");
// Dashboard: Main entry point after login.
function dashboard()
{
require 'app/controller/dashboard/dashboard.php';
new Controller();
}
// Staff related interfaces ----------------------------------------------------
function add_staff()
{
require 'app/controller/staff/add_staff.php';
new Controller();
}
// ----------------------------------------
function edit_staff($staff_id)
{
$_SESSION['path'] = $r1 . "/" . $r2 . "/" . $r3;
require 'app/controller/staff/edit_staff.php';
new Controller($staff_id);
}
// ----------------------------------------
Just to clear up, the $r* variables are not used again beyond here, hence the convenient use of storing in session.
That's not OOP - in OOP you'd declare a class, make r1, r2 and r3 its properties, and then they would be available in every method of the class. See a little tutorial about classes here.
Using global variables is a bad idea.
EDIT
Here's a sample code, like Sohnee asked:
Class Route {
var $r1;
var $r2;
var $r3;
function __construct($url)
{
$route = explode('/', $url);
// Shorthand
$this->r1=$route[0]; $this->r2=$route[1]; $this->r3=$route[2];
}
function test()
{
$path = $this->r1 . "/" . $this->r2 . "/" . $this->r3;
echo $path;
}
}
$a = new Route('http://stackoverflow.com/questions/');
$a->test();
In order to use global variables inside a function, you have to do it via the following way
$route = explode('/', $_SERVER["REQUEST_URI"]);
// Shorthand
$r1=$route[0]; $r2=$route[1]; $r3=$route[2];
// ...
function edit($id)
{
global $r1, $r2, $r3; // after this the variables are available in function scope
}
Another option is to use global array $GLOBALS. Using this array a global variable can be accessed from any scope like this:
if ($GLOBALS["r1"] == "some value")
{
// do something
}
ADD this inside the function.
global $r1, $r2, $r3;
This tells the function to use the variables from the global scope.
global variables can be seen inside a method using $GLOBALS
$GLOBALS — References all variables available in global scope
http://php.net/manual/en/reserved.variables.globals.php
<?php
$baz = 'foo';
clas Bar {
public function __construct() {
echo $GLOBALS['baz'];
}
}
or inside a function declaring variables global
function bar() {
global $baz;
echo $baz
}
If $r1, $r2, and $r3 are defined outside any class or function definition, you can use the global keyword to access them, or directly call them from the $GLOBALS array. e.x.:
function edit($id){
global $r1, $r2, $r3; //Rest of the function below this
or
$_SESSION['path'] = $GLOBALS['r1'].'/' //... etc.
Global variables can be accessed within functions, if you declare them as global (which creates a local reference to the global). However, globals are bad.
If the variable definition happens in "app/controller/edit.php", then the problem is as the warning tells you: the variables aren't defined yet. You use them on one line, but don't include the file that defines them until the next, so they aren't yet defined. It's the same as if the function were:
function edit($id) {
$_SESSION['path'] = $r1 . "/" . $r2 . "/" . $r3;
$route = explode('/', $_SERVER["REQUEST_URI"]);
// Shorthand
$r1=$route[0]; $r2=$route[1]; $r3=$route[2];
...
}
I recommend against the obvious fix: moving the require to before the line that uses the variables, as this shares one of the big problems with globals: the variables seemingly magically spring into existence, with no indication of how or where, making it harder to understand the function (and the rest of the code) simply by reading the function. It's a form of coupling.
Executing code by including files can occasionally be a useful trick, but it also often causes problems (as this question demonstrates). Generally, include files should only define things. For an OO approach, take whatever tasks are being performed by the included file and figure out what jobs the code is trying to achieve overall. Then, assign each task to the class that has the (single) responsibility of achieving each overall job. In this case, the specific task is breaking up a request into a route, and the overall job is dispatching a request to a controller. There should then be a dispatcher class that dispatches a request to the appropriate controller, with a method that parses the route. The method (which might be private or protected and called from the constructor) could store the route in instance variables for time-efficiency.
class RouteDispatcher {
protected $route;
function __construct() {
$this->_parseRoute();
...
}
function dispatch() {
...
}
protected function _parseRoute() {
$this->route = explode('/', $_SERVER['REQUEST_URI']);
}
...
}
The entry point (the script that is first called to handle each request) would instantiate a RequestDispatcher, set any appropriate properties or call any necessary methods, then call RequestDispatcher::dispatch, which would create the appropriate controller and hand off control to its request handler.
In the general case, a good design can be trickier than this because your goal as a designer in creating classes that have a single responsibility is to cut down on the need to change them. If a class has only one responsibility, then the class will need to be changed only if the requirements for that responsibility change.