php question about scope - php

i've been thinking if something like this is possible.
// this creates a variable $test in the scope it was called from
function create_var() {}
class A {
function test()
{
create_var();
// now we have a local to var() method variable $test
echo $test;
}
}
So, the question is, can a function create_var() create a variable outside of its scope, but not in a global scope? Example would be the extract() function - it takes an array and creates variables in the scope it was called from.

Nope, this is not possible. It's possible only to access the global scope from within a function.
You could make create_var() return an associative array. You could extract() that in your function:
function create_var()
{ return array("var1" => "value1", "var2" => "value2"); }
class A {
function test()
{
extract(create_var());
// now we have a local to var() method variable $test
echo $test;
}
}
Something a bit closer to what you want to do is possible in PHP 5.3 using the new closures feature. That requires declaring the variables beforehand, though, so it doesn't really apply. The same goes for passing variable references to create_var(): create_var(&$variable1, &$variable2, &$variable3....)
A word of warning: I can think of no situation where any of this would be the best coding practice. Be careful when using extract() because of the indiscriminate importing of variables that it performs. It is mostly better to work without it.

Related

Defining a global variable, and including functions that require it?

I have six functions that require a global variable. In an attempt to reduce redundancy, I wrote a new function that is triggered rather than triggering all six. This one function has a global $var that is required by the other functions.
So, it looks like this
function one_function_for_the_rest() {
global $importantVar;
functionOne();
functionTwo();
functionThree();
}
but the global variable is not being seen by the called functions. Am I doing this incorrectly, or is this a limitation I was not aware of?
You're not doing it correctly as the variable is defined when on_function_for... is called. An easier way for this would be just to have $importantVar; at the start of the code.
Or wrap your functions inside a class and put the variable inside the class.
e: so basically do : function myFunc($important) { stuff } and when calling the function do myFunc($importantVar)
example :
$asd = "lol";
class myclass {
public function lol($asd) {
echo $asd;
}
}
$obj = new myclass;
$obj->lol($asd);
You're not doing it correctly. Each function either needs to use the global scope identifier, like global $importantVar;, or have $importantVar passed as a parameter. Otherwise, the other functions don't have $importantVar in their respective scopes.
Simply calling a function from within one_function_for_the_rest does not tell that other function anything about global variables or variables used in one_function_for_the_rest. In technical terms, your function calls do not bring $importantVar into the respective scopes of functionOne, functionTwo, or functionThree.
PHP does not have the same scoping rules as most other languages have. That is the downside to not having to declare variables with var as in JavaScript or other similar constructs.
Basically in PHP, every function used is only available in that function. There are three exceptions:
The global keyword
The $this variable inside objects. This one is also "magic" as it's also available inside anonymous functions defined inside a class.
When declaring an anonymous functions you can bind variables to it using use.

Is it possible to declare a variable as "always global"?

Is there any way I can define a variable such a way that I don't need to global $var1; in every function? Just define it in beginning and keep using where ever needed. I know $GLOBALS exist, but don't want to use it.
First let me try to explain why you shouldn't use globals because they are extremely hard to manage. Say a team member overrides an $ADMIN variable in a file to be 1, and then all code that references the $ADMIN variable will now have the value of 1.
globals are so PHP4, so you need to pick a better design pattern, especially if this is new code.
A way to do this without using the ugly global paradigm is to use a class container. This might be known as a "registry" to some people.
class Container {
public static $setting = "foo";
}
echo Container::$setting;
This makes it more clear where this variable is located, however it has the weakness of not being able to dynamically set properties, because in PHP you cannot do that statically.
If you don't mind creating an object, and setting dynamic variables that way, it would work.
You need to pass the variable as a parameter to that function to avoid using GLOBALS.
The Problematic Scenario (Works ! but avoid it at all costs)
<?php
$test = 1;
function test()
{
global $test;
echo $test; // <--- Prints 1
}
test();
The right way...
<?php
$test = 1;
function test($test)
{
echo $test; // <--- Prints 1
}
test($test); //<--- Pass the $test param here
This behaviour called as superglobal variable. But php has limited predefined list of them: Superglobals.
So you cannot add your own superglobal variable.
Variable scope
My suggestions from the most to less radical:
Edit source code of PHP and add your own superglobals.
Do not write code at all.
Do not use PHP (use different language with different variable scope policy).
Do not use functions (write plain script).
Use constants instead of variables.
Use function params instead of using globals.
Use static variables instead of globals. (\G::$variable)

PHP Function scopes. Trouble coping up with $this vs. global declaration [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Access global variable from within a class
I want to fortify my knowledge in PHP. But most of the time I have trouble understanding with scopes. I am not sure when to use $this and global declaration keyword on my functions.
This is just an example class I just omitted the __construct()
class myClass{
public myVariable;
public function1() {
$this->myVariable=1;
}
public function2(){
global $myVariable;
$myVariable=1;
}
}
Which one is the best approach to use when assigning pre-declared variables inside a function? I am confused somehow by the different books by major publishers in PHP. I am not sure if I am asking the correct question or somehow relevant.
First off, thats not valid PHP, as Jared Farrish already said. Its public $myvar instead of public myvar. Variable names always begin with $.
When you declare a variable in a class:
<?php
class A
{
private $var;
}
That variable will be automatically available in all methods if accessed through $this (unless the method static, but that is another story). So this would work:
<?php
class A
{
private $var;
public function foo () {
// This works
$this->var = 1;
// This is a completely different thing and does not change
// the contents of A::$var
$var = 1;
}
}
Now global is a different thing altogether. In PHP, you cant do this:
<?php
$global_a = 123;
function myfunc ()
{
// You wont actually change the value of $global_a with this
$global_a = 1234;
}
echo $global_a; // still 123
You'd think this would work, but global variables aren't automatically available to functions. This is where global comes in:
<?php
$global_a = 123;
function myfunc ()
{
global $global_a;
$global_a = 1234;
}
echo $global_a; // now it will be 1234
I suggest you read about variable scope in PHP and then you can go on to OOP in PHP.
PHP is a very quirky language. Just because something works in most languages in a certain way doesn't mean it will work in PHP. Most of the times, it wont. So its best to educate yourself as much as possible.
Hope this helps
Which one is best often depends on the situation. In general it's best to avoid global variables as they bring risks with them of not knowing exactly where they're used.
Using a class variable is a good option if the variable is specific to that instance of the class. (You will have to prefix it with a $, though. I.e., public $myVariable;).
If the variable is only relevant to the function and instances outside the class, you'd do best to pass it as an reference. This is done by adding an & before the $ in the parameter space. I.e.:
public function3(&$myVariable) {
$myVariable = 1;
}
Or alternatively just return the value you wish and set it outside the function. I.e.,:
class MyClass {
public function3() {
return 1;
}
}
$myObject = new MyClass();
$myVariable = $myObject->function4();
try to avoid passing global variable,as there are many good reasons for that:
Reusing parts of the script is impossible :
If a certain function relies on global variables, it becomes almost impossible to use that function in a different context. Another problem is that you can’t take that function, and use it in another script.
Solving bugs is much harder :
Tracking a global variable is much harder than a non-global variable.
Understanding the code in a year will be much more difficult :
Globals make it difficult to see where a variable is coming from and what it does.
Now your questions:
Which one is the best approach to use when assigning pre-declared variables inside a function?
You can pass them by value or reference inside a function
By value
$firstVar = 1;
function abc($firstVar){
echo $firstVar ; // will give you 1
}
By reference
function abc(&$firstVar){
$firstVar = 3; // this will give utility to change that variable even
echo $firstVar ; // will give you 3
}
Now where to use $this variable:
$this is used to refer to the current object.
example:
class abc{
private $firstVar;
function abc(){
$this->firstVar = 2;
}
}

Variable usage outside the function where they were extracted

I have an array with associated keys that point to instantiated objects. For example:
$MyArray = array();
$MyArray['Object_A'] = new Object_A();
$MyArray['Object_B'] = new Object_B();
$MyArray['Object_C'] = new Object_C();
What I would like to do with this array is to extract it to variables as references to those objects.
extract($MyArray, EXTR_REFS);
The statement works and I am able to use those objects inside that array just as I would do $Var = new Object();.
$Object_A->SomeMethod();
However when I extract them in a function that I define they can no longer be used outside that function. They can be used inside the function like the example below but not outside.
function ExtractObj(&$Array)
{
extract($Array, EXTR_REFS);
$Object_A->SomeMethod(); // This works.
}
So I need a way to make the extracted variables from that function to be usable from outside the function.
function ExtractObj(&$Array)
{
extract($Array, EXTR_REFS);
}
$Object_A->SomeMethod(); // Not working (Yet).
NOTE: I have tried to use global, static variable modifiers or methods and so on but everything gives me an error.
Yes, you are correct. Variables have function scope, so they are not available outside the function. Learn to pass variables into a function as parameters, return needed values from the function and live with the function scope, it will make your programs better and more maintainable than one big messy global scope.

PHP Classes and global variables

I recently begun to use classes. I've been using procedural programming for quite a while so it has been a bit challenging.
My question.
If I have a class like this:
class Example {
public $name;
public $whatever;
public $yearAdded
public function __construct($name, $whatever=NULL, $dateAdded)
{
some trival code here;
}
}
How can I make $yearAdded use a global variable I set up somewhere else in another script?
FOR EXAMPLE:
global $currentYear = date('Y');
Would I have to do this way
new example($name, $whatever, $currentTime);
or is there a way to specify within the class to always use $currentYear for $yearAdded.
The global keyword doesn't work the way you think it does. It does not make a variable have global scope. All it does is specify to the function that you call it in that you want to use the variable in the outer scope.
For example:
$a="test";
function something() {
global $a;
echo $a; //Outputs: test
}
If you want to make a variable global so that it can be accessed from within a class, you need to use the $GLOBALS superglobal.
http://www.php.net/manual/en/reserved.variables.globals.php
This is not considered to be the best OOP way of doing things, but will get the job done.
You already have a builtin time() function, so why do you need a home-grown global variable in your constructor?
If you think carefully about how you are using globals, you'll find out that there are usually better ways of accessing the same info -- e.g. system environment variables, configuration files, etc.

Categories