4

Possible Duplicate:
Are global variables in PHP considered bad practice? If so, why?
global in functions

Edit: question answered in link above.

No, "global" in php is not the same thing as global in other languages, and while it does not introduce any security problems it can make the code less comprehensible to others.


OP:

Project summary - I am writing a web CMS to get my feet wet with PHP / MySQL. In order to break up the code I have a concept of these basic tiers / modules:

Data
- MySQL Tables
- PHP Variables

Function
- SQL - Get / Set / etc
- Frontend - Showing pages
- Backend - Manager

Presentation
- HTML Templates
- Page Content
- CSS Stylesheets

The goal is common enough. Use MySQL to hold site settings and page content, use php to get / manipulate content data for a page being served, then insert into an html template and echo to browser. Coming from OO languages like C# the first problem I ran into was variable scope issues when using includes and functions.

From the beginning I had been writing function-only php files and including them where needed in other files that had existing variable array definitions. For example, ignoring the data tier for a moment, a simple page might generically look like this:

File 1 (page)

$DATA_PAGE = Array
(
  'temp'  = null,
  'title' = null,
  [...]
);

include 'functions.php';

get_data ( 'page.php' );

[...]

run_html ();

File 2 (functions)

function get_data ( $page_name )
{
  global $DATA_PAGE;

  $DATA_PAGE [ 'temp'  ] = 'template';
  $DATA_PAGE [ 'title' ] = 'test page';
  [...]
}

function run_html ()
{
  global $DATA_PAGE;

  echo '<html>';
  echo '<head>';
  echo '<title>' . $DATA_PAGE [ 'title' ] . '</title>';
  [...]
}

I chose this method for a few reasons:

  • The data in these arrays after sql fetch might be used anywhere, including page content
  • I didnt want to have a dozen function arguments, or pass entire arrays

The code runs great. But in every article I find on the subject, the "global" calls in my functions are called bad practice, even though the articles never state why? I thought all that meant was "use parent scope". Am in introducing a security hole into my app? Is there a better method? Thanks in advance.

Community
  • 1
  • 1

5 Answers5

10

I think a top reason for avoiding this is that it hides dependencies.

Your functions get_data and run_html do not advertise in any way that they share data, and yet they do, in a big way. And there is no way (short of reading the code) to know that run_html will be useless if get_data has not been called.

As the complexity of your codebase grows, this kind of lurking dependency will make your code fragile and hard to reason about.

grossvogel
  • 6,465
  • 1
  • 23
  • 36
4

Because global variables can be modified by the process without other parts of your code knowing it producing unexpected results.

You should always try to keep variables scoped as locally as possible -- not only will this help you with debugging, but it will keep your code easier and cleaner to read and go back and modify.

If you are looking to share data across multiple functions, you might look into making a class for your data and then defining methods to operate on the data encapsulated in your object. (Object-Oriented programming)

tkone
  • 19,271
  • 5
  • 50
  • 77
  • But its not actually a global variable, it is just visible from the called file. There are parts of code that know how to use the arrays without knowing how the data is acquired, isn't this the basic idea behind encapsulation, with or without classes? –  Jan 03 '12 at 17:42
  • The instant you declare a variable with the `global` keyword in PHP it becomes, well, a global variable: "By declaring $a and $b global within the function, all references to either variable will refer to the global version. There is no limit to the number of global variables that can be manipulated by a function."[http://us.php.net/manual/en/language.variables.scope.php] – tkone Jan 03 '12 at 17:48
1

For many reasons, for example:

  • Hard to support code with global variables. You don't know where global variables can affect your logic and don't control access to them

  • Security - if you have complex system (especially with plugins), someone can compromise all system with global variables.

abdolence
  • 2,257
  • 1
  • 20
  • 26
  • I mean if you cannot control access to your variables, some bad or 3rdparty module/subsystem/plugin can change global variables in any way and compromise all system. – abdolence Jan 03 '12 at 21:23
1

Settings in a global variable are fine, but putting data that can be modified into a global variable can, as tkone said, have unexpected results.

That said, I don't agree with the notion that global variables should be avoided at all costs - just try wrapping them into, say, a singleton settings class.

Matt H
  • 6,195
  • 2
  • 23
  • 31
  • the arrays are simply holding data that has been fetched from a query, it was my first idea to not have to query the same table over and over, looks like I'm going to have to go back to objects whether I like it or not.. –  Jan 03 '12 at 18:15
0

It is bad practice to use variables from a different scope to your own, because it makes your code less portable. In other words, if I want to use the get_data() function somewhere else, in another project, I have to define the $DATA_PAGE variable before I can use it.

AFAIK this is the only reason this should be avoided - but it's a pretty good reason.

I would pass by reference instead.

function get_data (&$data_page, $page_name )
{
  $data_page['temp'] = 'template';
  $data_page['title'] = 'test page';
  [...]
}
get_data($DATA_PAGE);
DaveRandom
  • 84,004
  • 11
  • 142
  • 168
  • Is that deprecated in php 5? I like this idea –  Jan 03 '12 at 18:17
  • No, passing by reference is not deprecated. However, you must declare that it is a reference when you define the function, not when you call it - so do it exactly as above. – DaveRandom Jan 03 '12 at 20:36
  • I know this is old answer si just to update it from http://php.net/manual/en/language.references.pass.php: "Note: There is no reference sign on a function call - only on function definitions. Function definitions alone are enough to correctly pass the argument by reference. As of PHP 5.3.0, you will get a warning saying that "call-time pass-by-reference" is deprecated when you use & in foo(&$a);. And as of PHP 5.4.0, call-time pass-by-reference was removed, so using it will raise a fatal error. " – Strabek Feb 08 '16 at 14:30