Why can't functions defined in Drupal blocks access globals? - php

Scenario: I've defined a custom block in Drupal 6.20 under PHP 5.2.14. I've enabled PHP Code and I'm attempting to do something like this:
<?php
$a = "success";
function test() {
global $a;
print $a;
}
test();
?>
It prints nothing on my system, because I cannot seem to scope variable $a. I've also tried $GLOBALS['a'] to no avail. What gives? I feel like I'm going crazy.
Incidentally, using the global keyword in the outer scope will happily make drupal's globals available.

I'm not hugely familiar with Drupal but I'm guessing that the blocks are included inside some other function/method somewhere, so you're effectively dealing with a nested function, the include being in that outer function's local scope.
With that, it makes sense that $a = "success" can't be addressed from within the test() function.
If I'm right, it should work if you slap the global keyword on both scopes.

Related

Can global variables be created with the keyword global and through a superglobal variable within a function in PHP?

I have heard using global variables is not good, however I am just trying to understand how the PHP language works. I am a beginner in the coding world.
Why can global variables be created within functions? Whether it is through the use of the global keyword or through a superglobal variable. I thought these two actions were used to access global variables in a function. I thought the only way you can create a global variable is to create it outside a function; in the global scope. I have looked at many different websites including w3schools.com and php.net
This is just some simple code I created to try and understand the way global variables work with functions:
<?php
function sample1() {
global $a;
echo $a = "this ";
}
sample1();
function sample2() {
echo $GLOBALS['$b'] = "is ";
}
sample2();
function sample3() {
global $c;
$c = "an ";
}
sample3();
echo $c;
function sample4() {
$GLOBALS['$d'] = "example ";
}
sample4();
echo $GLOBALS['$d'];
?>
This is the result of the code:
this is an example
All of the code works, but I don't understand how I created a global variable on any of these blocks of code? The global variables were not created outside of the functions. How can they be created inside of a function? What am I missing? Any response is appreciated - If possible, please keep the answer simple - I would like to discuss this further in the comment section, because I'm sure I will have follow up questions - Thank you
Variables can be created in the global scope in the two ways you just did - there's nothing saying that a function can't create (or change) a variable in the global scope - WHEN you explicitly ask for it through $GLOBALS or the global keyword.
The issue is that your belief "I thought the only way you can create a global variable is to create it outside a function; in the global scope." is not an exact statement. When you're using $GLOBALS and global, you're referring to the global scope. You're introducing a reference to the global scope inside your function.
With global you're in effect linking the local reference to the global reference, while with $GLOBALS you're explicitly referencing the global scope (which internally inside PHP can be introduced to the local scope in the same way).
In that case you're explicitly saying "I want this variable to be available in the global scope, make it so!" and PHP does what you're asking it to. This behaviour differ between languages, but as you've discovered for PHP, it's allowed.
It's not something I would recommend using in any way - it makes your code very hard to follow and argue around, so consider it an esoteric detail.

PHP Accessing function in global scope from a class method

I have the following simple code:
$a = 'hello';
function myfunc() {
echo 'in myfunc';
}
class myclass {
function __construct() {
myfunc();
echo $a;
}
}
$m1 = new myclass();
The echo $a within the method gives an error as you would expect since $a is in the global scope and cannot be accessed from within the class without first declaring it as global. That is documented in the PHP manual.
The call to myfunc() does work and I don't understand why. It is also declared in the global scope but the method can access it without first declaring it as global. I can't seem to find anything in the PHP manual that explains why this works.
Maybe I've been doing PHP for too long and this is something so simple I've forgotten how it works. Any insight or a link to where in the PHP manual it says you can access a global function from within a class method would be appreciated.
thanks in advance.
Functions aren't scoped (except if you use namespaces). Only methods are in classes and variables everywhere.
It's supposed to work; everything is correct: you can call functions, once defined, from everywhere.
I'm not sure if this is a new thing for namespaces...
http://www.php.net/manual/en/language.namespaces.fallback.php
Blockquote
For functions and constants, PHP will fall back to global functions or constants if a namespaced function or constant does not exist.

Forbid specific variable access from global scope

Is there a way to forbid a variable from being picked out of global scope?
Something like:
#index.php
$forbidden = 'you should not be able to access me outside this scope'; // maybe invoke a function or namespaces?
require 'stuff.php';
echo new stuff();
#stuff.php
class stuff
{
public function __toString()
{
global $forbidden; // to result in an error or something?
/*
just a random example, but yes, any way
to somehow make a variable not global?
*/
return 'I am forbidden';
}
}
Have no idea if it's possible, but anyways, interested in OOP only fashion.
Reason?
To disallow a specific class from being instantiated into a variable and then taken out from global scope to reuse it's functions. Make class completely "private", kind of like a master class that does all the automation.
Hope I've made myself clear.
The only way I can think of would be to "fake" global scope...
//index.php
function scope() {
require 'actual.php';
}
scope();
and now, putting code in actual.php looks like "normal" code but it actually is inside function scope. Obviously you can't declare functions or classes in actual.php now, but otherwise it behaves the same, with the exception that any variables declared will be in the function's scope instead of global scope.
I really wouldn't do this though. A beating with a stick usually works if someone does something stupid like globals like that ;)

A function inside an if structure

can I put a function in PHP inside a if structure? like this:
<?php
if(true){
function HelloWorld(){
echo "Hello World!!!";
}
HelloWorld();
}
?>
because I have tried and it works, but I don't know if it is correct or not. Thanks
This is perfectly legal - it simply defines the function within the if statement block. That said, quite why you'd want to do this is somewhat of a mystery.
It's also worth noting that this function will be available in the global scope (i.e.: outside of the if statement block), as...
All functions and classes in PHP have
the global scope - they can be called
outside a function even if they were
defined inside and vice versa.
See the PHP User-defined functions manual page for more information.
As middaparka says, this is perfectly legal, but in terms of using it, you might want to check if a function exists before declaring it:
if (!function_exists("foo"))
{
function foo()
{
return "bar";
}
}
function_exists documentation
It looks a bit strange, but yes it's legal
As of PHP 5.3 if you need a function with a limited scope (say for a callback) you can use anonymous functions / closures
I wanted to add an answer here, because there's a caveat that isn't addressed in the other answers.
Based on my testing in 5.3, it appears that functions that are defined inside if structures are defined at runtime, rather than at compile time like other functions.
For example, outside a conditional block, this:
foo();
function foo(){
echo 'foo!';
}
works fine because the function is defined at compile time, and executed at runtime. But calling the function before defining it while inside a condition block:
if(1){
foo(); // Call to undefined function!
function foo(){
echo 'foo!';
}
}
Will produce a call to undefined function error, at least as of version 5.3.
But defining the function in an if block before calling it is valid:
if(1){
function foo(){
echo 'foo!';
}
foo(); // No errors, since function is defined!
}
So there is a major gotcha to be aware of when defining functions inside a conditional: the function must be defined in the code before calling the function, since conditional functions don't seem to get defined at compile time.
The OP also asked about performance. If the conditional function is defined at runtime instead of compile time like most other functions, then this function will not benefit from performance boosters like OpCode caching, which depending on the circumstances, could slow down your application. For example, if your master php file looked like:
if($IsLoggedIn){
// include files/functions and bootstrap here...
}
Then the entire application might not benefit from OpCode caching at all.
Basically yes, according to the manual:
Any valid PHP code may appear inside a
function, even other functions and
class definitions.
Personally I haven't had a situation in which I'd actually do such a thing. Most of the time it would be easier to group your functions on a place where it actually can be found! ;-)

global array in php

i have to function in two different files.
one of them should add a new item to an array each time is called and the array should be accessible .what i did for it is :
function1(){
global $array;
$array[] = 'hi';
}
but it just create one item in array even if i call this function 4 times .
What you did should work.
<?php
function function1(){
global $array;
$array[] = 'hi';
}
function1();
function1();
function1();
print_r($array);
Test it.
You probably have another problem. Please note that the lifetime of all variables is the current run of your script. They won't exist in a successive run. For that you need to use some sort of persistence like session, cookie, file system, database.
For more help post your complete code.
I'm a bit confused by the wording of your question. When you say "i have to function in two different files." does you mean you have "two" functions?
If you have two functions both trying to use your $array variable, you'll need to call global $array; in both functions.
The reason for this is that global is a bit misleading. All it's really doing is assigning a reference to a member of $_GLOBALS to a variable in the local scope which has the same name as the $_GLOBALS index. In other words, if you do something like this:
global $variable;
it's essentially the same thing as saying this:
$variable =& $_GLOBALS['variable']; (assign by reference)
The actual variable $variable is still scoped at the function level, it just happens to have a reference to a global variable.
The implication of this is that if you don't define global $variable in every function, you're just creating a brand new variable within the scope of that function. When the function ends, the variable is unset and any changes made to it within the function are lost.
With all of that said, global variables still tend to be a bad idea. It's a lot clearer if you just maintain a local variable, and pass it as a parameter to other functions when needed.
I had the problem that a global $array was not known in a function. But when I placed the first def: $array = array(); before the first function call, it worked.

Categories