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.
Related
Let's say I have the following:
class Submit extends \RightNow\Models\Base
{
function __construct()
{
parent::__construct();
}
function inner () {
return $i++;
}
function outer(){
$i = 0;
$this->inner();
echo $i;
}
}
$submit = new Submit();
$submit->outer();
How is it possible for inner() to access the variable $i that was declared in outer()? I've tried using global but this didn't work.
I understand in my very basic example, I could pass the variable in as a parameter but this just serves as an example for my question
I am using CodeIgniter
As you mentioned you are using Codeigniter, You can achieve it by the below code. In any class, you can use a class member variable in any of the member functions in the class.
class Submit extends \RightNow\Models\Base
{
public $i = 0;
function __construct()
{
parent::__construct();
}
function inner () {
return $this->i++;
}
function outer(){
$this->i = 0;
inner();
echo $this->i;
}
outer();
}
If all your methods are in a class you can use the below approach whereby the variable is a class reference set in the class and so automatically available to all class methods.
Variables in the class are called properties.
class Submit extends \RightNow\Models\Base
{
private $i = 0; // set class based variable;
function __construct()
{
parent::__construct();
}
function inner () {
return $this->i++;
}
function outer(){
// $i = 0; You probably don't want to set this each call?
$this->inner();
echo $this->i;
}
}
$submit = new Submit();
$submit->outer();
See above everything references the class property $i which is set in the class.
Alternatively if you're working with the same process over multiple varaibles from you can group them up into an array and simply pass the array as the single argument.
Your code will look slightly different depending on if the values are coming from inside or outside the class.
References :
PHP - passing variables to classes
https://www.php.net/manual/en/language.oop5.basic.php
https://www.php.net/manual/en/language.oop5.properties.php
You can pass a variable by reference. E.g.:
function inner (&$i) {
return $i++;
}
function outer(){
$i = 0;
inner($i);
echo $i; // 1
}
UPD
If you want to pass multiple variables:
you can pass an array by reference:
function inner (&$arr) {
$arr['i']++;
$arr['j']--;
}
function outer() {
$a = array('i' => 5, 'j' => 10);
inner($a);
echo $a['i'] . "\n" . $a['j']; // 6 9
}
You can pass an object. In this case it always passed by reference implicitly. E.g.
function inner($obj) { // no & needed, because it is an object reference itself
$obj->a++;
$obj->b--;
}
function outer() {
$obj = new \stdClass();
$obj->a = 5;
$obj->b = 10;
inner($obj);
echo $obj->a . "\n" . $obj->b; // 6 9
}
inside the same class you can use private members, but make sure the functions are not recursive (i.e. the same field is not reused simultaneously in different places):
class Submit extends \RightNow\Models\Base
{
private $_i;
function __construct()
{
parent::__construct();
}
function inner () {
$this->_i++;
}
function outer(){
$this->_i = 0;
$this->inner();
echo $this->_i;
}
}
how do you define a variable in a class? seems like global only works inside the function.
<?php
$a = '20';
$b = '10';
class test {
global $a; $b;
function add() {
echo $a;
}
}
$answer = new test();
$answer->add();
?php>
i tried this one (use global inside a class but gets error instead)
also, how can you define multiple variables in just 1 line of code instead of defining it each.
To define a class property (or variable), you would do like so:
class Foo {
private $myVar = 'my var'; // define a class property
public function add() {
echo $this->myVar;
}
}
How about passing the data in via the constructor?
Code: (Demo)
$a_outside = '20';
$b_outside = '10';
class test {
public $a_inside;
public $b_inside;
public function __construct($a_passed_in, $b_passed_in)
{
$this->a_inside = $a_passed_in;
$this->b_inside = $b_passed_in;
}
public function add()
{
echo $this->a_inside + $this->b_inside;
}
}
$answer = new test($a_outside, $b_outside);
$answer->add(); // output: 30
Pass the variable to the class via arguments in the constructor call.
Define the values as variables in the class within construct call.
Access the variables within the add() method.
I'm working on a WordPress shortcode plugin, so I need to define a function to use with add_action('wp_footer', 'fnc_name') for example. I have created the plugin as a class with public functions and static variables.
Here's an example of what I'm trying to do (use $count in the local function tryToGetIt):
class Test {
public static $count;
public function now () {
if (!$this::$count) {
$this::$count = 0;
}
$this::$count++;
$count = (string) $this::$count;
echo 'count should be '.$count;
function tryToGetIt() {
global $count;
echo 'count is '.$count;
}
tryToGetIt();
}
};
$test = new Test();
$test->now();
You can see the demo on IDEONE: http://ideone.com/JMGIFr
The output is 'count should be 1 count is ';
As you can see I've tried declaring the $count variable with global to use the variable from the outer function, but that is not working. I've also tried $self = clone $this and using global $self within the local function.
How can the local function use the variables from within the class's public function?
This is not possible with global. PHP has exactly two variable scopes: global, and local.
<?php
$foo = 'bar'; // global scope <-----------
\
function x() { |
$foo = 'baz'; // function local scope |
|
function y() { |
global $foo; // access global scope /
echo $foo;
}
y();
}
x(); // outputs 'bar'
You COULD try a closure, e.g.
function foo() {
$foo = 'bar';
$baz = function() use (&$foo) { ... }
}
There is no practical way to access a scope defined at some intermediate level of a function call chain. You only ever have the local/current scope, and the global scope.
You could do:
function tryToGetIt($count) {
echo 'count is '.$count;
}
tryToGetIt($count);
Or to select the static variable use:
Test::$count within the tryToGetIt() function.
I tried this code, which works
class Test {
public static $count;
public function now () {
if (!$this::$count) {
$this::$count = 0;
}
$this::$count++;
$count = (string) $this::$count;
echo 'count should be '.$count;
function tryToGetIt() {
echo 'count is '. Test::$count;
}
tryToGetIt();
}
};
$test = new Test();
$test->now();
But I'm not sure I understand why you are trying to do this. Why not make tryToGetIt() a private function within Test rather than nested within now()?
How can I use class instance inside independent method?
I some file have:
global $l;
$l = new l('bg');
include('second.php');
In second.php I have:
function a() {
print_r($l);
}
$l is coming like NULL;
class l declaration:
class l {
var $lang = array();
function l($lang) {
}
function g($string) {
}
}
My question - how can I use $l instance inside of my function a.
Thanks.
In function a $l is not defined.
Either you pass it in as a parameter or you use global.
function a($l) {
print_r($l);
}
global is not like var. It does not define a variable to be used as a global. Instead, global allows you to pull variables from the global scope, like:
$l = new l();
function a() {
global $l;
print_r($l);
}
I should also add that the use of global is heavily frowned upon, it breaks dependency expectations. This means that if you look at your function a you can't see that it needs $l. If it's a parameter then you know it needs $l.
I was looking at the source for Drupal 7, and I found some things I hadn't seen before. I did some initial looking in the php manual, but it didn't explain these examples.
What does the keyword static do to a variable inside a function?
function module_load_all($bootstrap = FALSE) {
static $has_run = FALSE
It makes the function remember the value of the given variable ($has_run in your example) between multiple calls.
You could use this for different purposes, for example:
function doStuff() {
static $cache = null;
if ($cache === null) {
$cache = '%heavy database stuff or something%';
}
// code using $cache
}
In this example, the if would only be executed once. Even if multiple calls to doStuff would occur.
Seems like nobody mentioned so far, that static variables inside different instances of the same class remain their state. So be careful when writing OOP code.
Consider this:
class Foo
{
public function call()
{
static $test = 0;
$test++;
echo $test . PHP_EOL;
}
}
$a = new Foo();
$a->call(); // 1
$a->call(); // 2
$a->call(); // 3
$b = new Foo();
$b->call(); // 4
$b->call(); // 5
If you want a static variable to remember its state only for current class instance, you'd better stick to a class property, like this:
class Bar
{
private $test = 0;
public function call()
{
$this->test++;
echo $this->test . PHP_EOL;
}
}
$a = new Bar();
$a->call(); // 1
$a->call(); // 2
$a->call(); // 3
$b = new Bar();
$b->call(); // 1
$b->call(); // 2
Given the following example:
function a($s){
static $v = 10;
echo $v;
$v = $s;
}
First call of
a(20);
will output 10, then $v to be 20. The variable $v is not garbage collected after the function ends, as it is a static (non-dynamic) variable. The variable will stay within its scope until the script totally ends.
Therefore, the following call of
a(15);
will then output 20, and then set $v to be 15.
Static works the same way as it does in a class. The variable is shared across all instances of a function. In your particular example, once the function is run, $has_run is set to TRUE. All future runs of the function will have $has_run = TRUE. This is particularly useful in recursive functions (as an alternative to passing the count).
A static variable exists only in a
local function scope, but it does not
lose its value when program execution
leaves this scope.
See http://php.net/manual/en/language.variables.scope.php
To expand on the answer of Yang
If you extend a class with static variables, the individual extended classes will hold their "own" referenced static that's shared between instances.
<?php
class base {
function calc() {
static $foo = 0;
$foo++;
return $foo;
}
}
class one extends base {
function e() {
echo "one:".$this->calc().PHP_EOL;
}
}
class two extends base {
function p() {
echo "two:".$this->calc().PHP_EOL;
}
}
$x = new one();
$y = new two();
$x_repeat = new one();
$x->e();
$y->p();
$x->e();
$x_repeat->e();
$x->e();
$x_repeat->e();
$y->p();
outputs:
one:1
two:1
one:2
one:3 <-- x_repeat
one:4
one:5 <-- x_repeat
two:2
http://ideone.com/W4W5Qv
static variable in a function means that no matter how many times you call the function, there's only 1 variable.
<?php
class Foo{
protected static $test = 'Foo';
function yourstatic(){
static $test = 0;
$test++;
echo $test . "\n";
}
function bar(){
$test = 0;
$test++;
echo $test . "\n";
}
}
$f = new Foo();
$f->yourstatic(); // 1
$f->yourstatic(); // 2
$f->yourstatic(); // 3
$f->bar(); // 1
$f->bar(); // 1
$f->bar(); // 1
?>
Inside a function, static means that the variable will retain its value each time the function is called during the life of the page load.
Therefore in the example you've given, if you call a function twice, if it set $has_run to true, then the function would be able to know that it had previously been called because $has_run would still be equal to true when the function starts the second time.
The usage of the static keyword in this context is explained in the PHP manual here: http://php.net/manual/en/language.variables.scope.php