(go) Use global variables in PHP

Source: Internet
Author: User

Brief introduction

Even if you develop a new large PHP program, you will inevitably need to use global data, because some of the data needs to be used in different parts of your code. Some common global data are: Program setting class, database connection class, user profile and so on. There are many ways to make this data global, the most common is to use the "global" keyword declaration, later in the article we will explain in detail.
The only drawback to using the "global" keyword to assert global data is that it is actually a very poor programming style and often leads to bigger problems in the program since the global data links the original pieces of code in your code. The consequence is that if you change some part of the code, it may cause other parts to go wrong. So if you have a lot of global variables in your code, your entire program must be hard to maintain.
This article will show you how to prevent this global variable problem with different techniques or design patterns. Of course, first let's look at how to use the "global" keyword to make global data and how it works.

Using global variables and the "global" keyword

PHP By default defines some "super Global (Superglobals)" variables, which are automatically global and can be called anywhere in the program, such as $_get and $_request, and so on. They usually come from data or other external data, and using these variables is usually not a problem because they are basically non-writable.
But you can use your own global variables. Using the keyword "global" You can import global data into the local scope of a function. If you do not understand the "variable use range", please refer to the instructions in the PHP manual for yourself.

Here's a demo example that uses the "global" keyword:

The following is the referenced content:
<?php
$my _var = ' Hello world ';
Test_global ();
function Test_global () {
Now in local scope
The $my _var variable doesn ' t exist
Produces error: "Undefined Variable:my_var"
echo $my _var;
Now let ' s important the variable
Global $my _var;
Works:
echo $my _var;
}
?>

As you can see in the example above, the "global" keyword is used to import global variables. It seems to work well, and it's simple, so why worry about using the "global" keyword to define global data?
Here are three good reasons:
1, code reuse is almost impossible.
If a function relies on global variables, it is almost impossible to use this function in a different environment. Another problem is that you cannot extract this function and then use it in other code.
2, debugging and solve the problem is very difficult.
Tracking a global variable is more difficult than tracking a non-global variable. A global variable may be redefined in some of the less obvious include files, even if you have a very Good program editor (or IDE) to help you, it will take you a few hours to discover the problem.
3. It will be very difficult to understand the code.
It's hard to figure out where a global variable comes from and what it does. In the process of development, you may know that every global variable is known, but about a year later, you may forget at least the general global variables, which you will regret for using so many global variables.
So what should we use if we don't use global variables? Let's take a look at some of these solutions.


Using function parameters

One way to stop using a global variable is simply to pass the variable as a function parameter, as shown here:

The following is the referenced content:

<?php
$var = ' Hello world ';
Test ($var);
function test ($var) {
Echo $var;
}
?>


If you only need to pass a global variable, then this is a very good or even excellent solution, but what if you want to pass a lot of values?
For example, if we want to use a database class, a program settings class and a user class. In our code, these three classes are used in all components, so they must be passed to each component. If we use the method of function arguments, we have to do this:

The following is the referenced content:
<?php
$db = new DBConnection;
$settings = new Settings_xml;
$user = new User;
Test ($db, $settings, $user);
Function test (& $db, & $settings, & $user) {
Do something
}
?>


Obviously, this is not worth it, and once we have new objects to join, we have to add one more function parameter to each function. So we need to use another way to solve this problem.

Use single piece (singletons)

One way to solve the function parameter problem is to use a single piece (singletons) instead of the function parameter. A single piece is a special class of objects that can only be instantiated once and contain a static method to return an interface to an object. The following example shows how to build a simple single piece:

The following is the referenced content:
<?php
Get instance of DBConnection
$db =& dbconnection::getinstance ();
Set User property on object
$db->user = ' sa ';
Set second variable (which points to the same instance)
$second =& dbconnection::getinstance ();
Should print ' sa '
Echo $second->user;
Class DBConnection {
var $user;
function &getinstance () {
Static $me;
if (Is_object ($me) = = True) {
return $me;
}
$me = new DBConnection;
return $me;
}
function Connect () {
Todo
}
function query () {
Todo
}
}
?>

The most important part of the above example is the function getinstance (). This function returns an instance of this class by using a static variable $me, ensuring that only one instance of the DbConnection class is available.
The advantage of using a single piece is that we do not need to explicitly pass an object, but simply use the getinstance () method to get to the object as follows:

The following is the referenced content:
<?php
function Test () {
$db = Dbconnection::getinstance ();
Do something with the object
}
?>

However, the use of a single piece also has a series of deficiencies. First, how do we need to globally multiple objects in a class? Because we use a single piece, so this is impossible (as its name is a single piece). Another problem is that a single piece cannot be tested with individual tests, and it is completely impossible, unless you introduce all the stacks, and this is obviously something you don't want to see. This is why the single piece is not the main reason for our ideal solution.

Registration mode

The best way to get some objects to be used by all the components in our code (the Translator notes: Global objects or data) is to use a central container object that contains all of our objects. Typically, this container object is called a registrar by people. It's very flexible and it's very simple. A simple Registrar object is as follows:

The following is the referenced content:

<?php
Class Registry {
var $_objects = array ();
function set ($name, & $object) {
$this->_objects[$name] =& $object;
}
function &get ($name) {
return $this->_objects[$name];
}
}
?>


The first step in using a Registrar object is to use method set () to register an object:

The following is the referenced content:
<?php
$db = new DBConnection;
$settings = new Settings_xml;
$user = new User;
Register objects
$registry =& New Registry;
$registry->set (' db ', $db);
$registry->set (' Settings ', $settings);
$registry->set (' user ', $user);
?>


Now that our Register object holds all of our objects, we refer to the need to pass this registrar object to a function (instead of passing three objects separately). Look at the following example:

The following is the referenced content:
<?php
Function test (& $registry) {
$db =& $registry->get (' db ');
$settings =& $registry->get (' Settings ');
$user =& $registry->get (' user ');
Do something with the objects
}
?>

A big improvement of the registrar compared to other methods is that when we need to add a new object to our code, we no longer need to change everything (the translator notes: All the code that uses the global object in the program), we just need to register a new object in the Registrar, Then it (the translator note: The newly registered object) can be called immediately in all components

To make it easier to use the Registrar, we changed its invocation to one-piece mode (translator Note: Do not use the previously mentioned function pass). Because only one registrar is required in our program, the single-piece mode makes it ideal for this task. Add a new method to the Registrar class as follows:

The following is the referenced content:

<?
function &getinstance () {
Static $me;
if (Is_object ($me) = = True) {
return $me;
}
$me = new Registry;
return $me;
}
?>


This allows it to be used as a single piece, such as:

The following is the referenced content:
<?php
$db = new DBConnection;
$settings = new Settings_xml;
$user = new User;
Register objects
$registry =& registry::getinstance ();
$registry->set (' db ', $db);

(go) Use global variables in PHP

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.