global array in php - 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.

Related

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 include_once inside a function to have global effect

I have a function in php:
function importSomething(){
include_once('something.php');
}
How do i make it sot that the include_once has a global effect? That everything imported will be included in the global scope?
You can return all the variables in the file like so...
function importSomething(){
return include_once 'something.php';
}
So long as something.php looks like...
<?php
return array(
'abc',
'def'
);
Which you could assign to a global variable...
$global = importSomething();
echo $global[0];
If you wanted to get really crazy, you could extract() all those array members into the scope (global in your case).
include() and friends are scope-restricted. You can't change the scope that the included content applies to unless you move the calls out of the function's scope.
I guess a workaround would be to return the filename from your function instead, and call it passing its result to include_once()...
function importSomething() {
return 'something.php';
}
include_once(importSomething());
It doesn't look as nice, and you can only return one at a time (unless you return an array of filenames, loop through it and call include_once() each time), but scoping is an issue with that language construct.
If you want ordinary variable definitions to be teleported into the global scope automatically, you could also try:
function importSomething(){
include_once('something.php');
$GLOBALS += get_defined_vars();
}
However, it if it's really just a single configuration array, I would also opt for the more explicit and reusable return method.
I know this answer is really late for this user, but this is my solution:
inside your function, simply declare any of the vars you need to ovewrite as global.
Example:
Need to have the $GLOBALS['text'] set to "yes":
Contents of index.php:
function setText()
{
global $text;
include("setup.php");
}
setText();
echo 'the value of $text is "'.$text.'"'; // output: the value of $text is "yes"
Contents of setup.php:
$text = "yes";
The solution is similar to mario's, however, only explicitely globally-declared vars are overwritten.
All variables brought in from an included file inherit current variable scope of the including line. Classes and functions take on global scope though so it depends what your importing.
http://uk.php.net/manual/en/function.include.php
(Final Paragraph before example)

How to modify variables outside of a function in PHP / better way to do something

I have a script with the following part:
function checkDays($oldDate){
// calculate time
// Print table row style based on number of days passed
// (eg less than 1 week, 1 week, 2 weeks, 3weeks+)
}
//Some code
checkdays($value)
I would like to put a counter of how many records of each time period there is, the function itself is inside a loop, so its called for each row of the table, and I can't seem to access variables defined outside the function itself so I can change them (eg. put a counter at the top of the script and modify it from the function).
Some people say use global variables but I understand that is a risk and not recommended. Is there an easy way to access the variables from the function? Also, is there a better way to do what I'm doing here overall?
DO NOT BE TEMPTED TO USE globals
You can pass variables by reference, this means the actual variable is passed rather than a copy of it:
$count = 0;
//Some code
checkdays($value, $count);
checkdays($value, $count);
checkdays($value, $count);
// This will output 3
echo $count;
// Use a & to pass by reference
function checkDays($oldDate, &$count){
// Your code goes here as normal
// Increment $count, because it was passed by reference the
// actual variable was passed
// into the function rather than a copy of the variable
$count++;
}
I think the risk you're referring to is with register_globals, which is something else entirely.
Inside the function, use the global keyword, e.g.
function myFunction($someParam) {
global $counter;
++$counter;
// do something
}
Alternatively, you can do what's called pass-by-reference to modify a variable in the outer scope that's passed to your function, e.g.
function myFunction($someParam, &$counter) {
++$counter;
// do something
}
Note the ampersand.
More information is available at the PHP Manual page about Variable Scope
You should probably create a class and use private properties for storing the data you want.
Rather than pollute the global namespace with useless variables, you can define static members of functions, that persist beyond the scope of the function, but only exist within the scope of the function:
function myFunction($param)
{
static $count;
if (empty($count)) $count = 0;
$count++;
//rest of your function
}
Unfortunately, I can't seem to find where this functionality is documented in the php docs.
Found it: variable scope
I can't seem to access variables defined outside the function itself
I had missed this line.
If you're in an OOP paradigm, use an object to store the counter. Otherwise, global variables are the way to go, but not directly. If you're coding in a scripted paradigm, and you're using the latest version of PHP, use namespaces to keep from polluting the root namespace's globals.
If you can't use namespaces, use pseudo-namespaces for everything. Instead of function someFunction, use function projectName_someFunction, or some combination thereof. That way you can combine multiple projects without worrying about using the wrong function. In that same manner, all global variables can then be stored as $projectName_someVar.
There are other methods for pseudo-namespacing your function/variable names.
The reason not to use global variables is that a global variable with a common name can easily be overwritten, and may be ambiguous: what does $count actually count in the global namespace?

php question about scope

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.

PHP Preserve scope when calling a function

I have a function that includes a file based on the string that gets passed to it i.e. the action variable from the query string. I use this for filtering purposes etc so people can't include files they shouldn't be able to and if the file doesn't exist a default file is loaded instead.
The problem is that when the function runs and includes the file scope, is lost because the include ran inside a function. This becomes a problem because I use a global configuration file, then I use specific configuration files for each module on the site.
The way I'm doing it at the moment is defining the variables I want to be able to use as global and then adding them into the top of the filtering function.
Is there any easier way to do this, i.e. by preserving scope when a function call is made or is there such a thing as PHP macros?
Edit: Would it be better to use extract($_GLOBALS); inside my function call instead?
Edit 2:
For anyone that cared. I realised I was over thinking the problem altogether and that instead of using a function I should just use an include, duh! That way I can keep my scope and have my cake too.
Edit: Okay, I've re-read your question and I think I get what you're talking about now:
you want something like this to work:
// myInclude.php
$x = "abc";
// -----------------------
// myRegularFile.php
function doInclude() {
include 'myInclude.php';
}
$x = "A default value";
doInclude();
echo $x; // should be "abc", but actually prints "A default value"
If you are only changing a couple of variables, and you know ahead of time which variables are going to be defined in the include, declare them as global in the doInclude() function.
Alternatively, if each of your includes could define any number of variables, you could put them all into one array:
// myInclude.php
$includedVars['x'] = "abc";
$includedVars['y'] = "def";
// ------------------
// myRegularFile.php
function doInclude() {
global $includedVars;
include 'myInclude.php';
// perhaps filter out any "unexpected" variables here if you want
}
doInclude();
extract($includedVars);
echo $x; // "abc"
echo $y; // "def"
original answer:
this sort of thing is known as "closures" and are being introduced in PHP 5.3
http://steike.com/code/php-closures/
Would it be better to use extract($_GLOBALS); inside my function call instead?
dear lord, no. if you want to access a global variable from inside a function, just use the global keyword. eg:
$x = "foo";
function wrong() {
echo $x;
}
function right() {
global $x;
echo $x;
}
wrong(); // undefined variable $x
right(); // "foo"
When it comes to configuration options (especially file paths and such) I generally just define them with absolute paths using a define(). Something like:
define('MY_CONFIG_PATH', '/home/jschmoe/myfiles/config.inc.php');
That way they're always globally accessible regardless of scope changes and unless I migrate to a different file structure it's always able to find everything.
If I understand correctly, you have a code along the lines of:
function do_include($foo) {
if (is_valid($foo))
include $foo;
}
do_include(#$_GET['foo']);
One solution (which may or may not be simple, depending on the codebase) is to move the include out in the global scope:
if (is_valid(#$_GET['foo']))
include $_GET['foo'];
Other workarounds exists (like you mentioned: declaring globals, working with the $_GLOBALS array directly, etc), but the advantage of this solution is that you don't have to remember such conventions in all the included files.
Why not return a value from your include and then set the value of the include call to a variable:
config.php
return array(
'foo'=>'bar',
'x'=>23,
'y'=>12
);
script.php
$config = require('config.php');
var_dump($config);
No need to mess up the place with global variables
Is there any easier way to do this, i.e. by preserving scope when a function call is made
You could use:
function doInclude($file, $args = array()) {
extract($args);
include($file);
}
If you don't want to explicitly pass the variables, you could call doInclude with get_defined_vars as argument, eg.:
doInclude('test.template.php', get_defined_vars());
Personally I would prefer to pass an explicit array, rather than use this, but it would work.
You can declare variables within the included file as global, ensuring they have global scope:
//inc.php
global $cfg;
$cfg['foo'] = bar;
//index.php
function get_cfg($cfgFile) {
if (valid_cfg_file($cfgFile)) {
include_once($cfgFile);
}
}
...
get_cfg('inc.php');
echo "cfg[foo]: $cfg[foo]\n";

Categories