PHP 全局函数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5166087/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 17:00:40  来源:igfitidea点击:

PHP global in functions

phplanguage-design

提问by Pascal Qyy

What is the utility of the global keyword?

global 关键字的用途是什么?

Are there any reasons to prefer one method to another?

有什么理由更喜欢一种方法而不是另一种方法吗?

  • Security?
  • Performance?
  • Anything else?
  • 安全?
  • 表现?
  • 还要别的吗?

Method 1:

方法一:

function exempleConcat($str1, $str2)
{
  return $str1.$str2;
}

Method 2:

方法二:

function exempleConcat()
{
  global $str1, $str2;
  return $str1.$str2;
}

When does it make sense to use global?

什么时候使用有意义global

For me, it appears to be dangerous... but it may just be a lack of knowledge. I am interested in documented(e.g. with example of code, link to documentation...) technical reasons.

对我来说,这似乎很危险……但它可能只是缺乏知识。我对文档化(例如代码示例、文档链接...)技术原因感兴趣。

Thanks in advance!

提前致谢!



Bounty

赏金

This is a nice general question about the topic, I (@Gordon) am offering a bounty to get additional answers. Whether your answer is in agreement with mine or gives a different point of view doesn't matter. Since the globaltopic comes up every now and then, we could use a good "canonical" answer to link to.

这是关于该主题的一个很好的一般性问题,我(@Gordon)提供赏金以获取其他答案。你的答案是否与我的一致或给出不同的观点并不重要。由于这个global话题不时出现,我们可以使用一个很好的“规范”答案来链接。

回答by Gordon

Globals are evil

全局是邪恶的

This is true for the globalkeyword as well as everything else that reaches from a local scope to the global scope (statics, singletons, registries, constants). You do not want to use them. A function call should not have to rely on anything outside, e.g.

对于global关键字以及从局部范围到全局范围(静态、单例、注册表、常量)的所有其他内容都是如此。您不想使用它们。函数调用不应该依赖于任何外部的东西,例如

function fn()
{
    global $foo;              // never ever use that
    $a = SOME_CONSTANT        // do not use that
    $b = Foo::SOME_CONSTANT;  // do not use that unless self::
    $c = $GLOBALS['foo'];     // incl. any other superglobal ($_GET, …)
    $d = Foo::bar();          // any static call, incl. Singletons and Registries
}

All of these will make your code depend on the outside. Which means, you have to know the full global state your application is in before you can reliably call any of these. The function cannot exist without that environment.

所有这些都会使您的代码依赖于外部。这意味着,您必须先了解应用程序所处的完整全局状态,然后才能可靠地调用其中任何一个。没有那个环境,这个函数就不可能存在。

Using the superglobals might not be an obvious flaw, but if you call your code from a Command Line, you don't have $_GETor $_POST. If your code relies on input from these, you are limiting yourself to a web environment. Just abstract the request into an object and use that instead.

使用超全局变量可能不是一个明显的缺陷,但是如果您从命令行调用代码,则没有$_GET$_POST。如果您的代码依赖于这些输入,则您将自己限制在 Web 环境中。只需将请求抽象为一个对象并使用它。

In case of coupling hardcoded classnames (static, constants), your function also cannot exist without that class being available. That's less of an issue when it's classes from the same namespace, but when you start mix from different namespaces, you are creating a tangled mess.

在耦合硬编码类名(静态、常量)的情况下,如果该类不可用,您的函数也无法存在。当它是来自同一命名空间的类时,这不是什么问题,但是当您从不同的命名空间开始混合时,就会造成混乱。

Reuse is severly hampered by all of the above. So is unit-testing.

重用受到上述所有因素的严重阻碍。单元测试也是如此

Also, your function signatures are lying when you couple to the global scope

此外,当您耦合到全局范围时,您的函数签名是在说谎

function fn()

is a liar, because it claims I can call that function without passing anything to it. It is only when I look at the function body that I learn I have to set the environment into a certain state.

是骗子,因为它声称我可以调用该函数而无需向其传递任何内容。只有当我查看函数体时,我才知道必须将环境设置为某种状态。

If your function requires arguments to run, make them explicit and pass them in:

如果您的函数需要运行参数,请将它们显式化并传入:

function fn($arg1, $arg2)
{
    // do sth with $arguments
}

clearly conveys from the signature what it requires to be called. It is not dependent on the environment to be in a specific state. You dont have to do

从签名中清楚地传达了它需要调用的内容。处于特定状态不依赖于环境。你不必做

$arg1 = 'foo';
$arg2 = 'bar';
fn();

It's a matter of pulling in (global keyword) vs pushing in (arguments). When you push in/inject dependencies, the function does not rely on the outside anymore. When you do fn(1)you dont have to have a variable holding 1 somewhere outside. But when you pull in global $oneinside the function, you couple to the global scope and expect it to have a variable of that defined somewhere. The function is no longer independent then.

这是拉入(全局关键字)与推入(参数)的问题。当您推入/注入依赖项时,该函数不再依赖于外部。当你这样做时,你不必fn(1)在外面的某个地方有一个变量保持 1 。但是当你在$one函数内部引入 global 时,你耦合到全局作用域并期望它在某处定义一个变量。该功能不再独立。

Even worse, when you are changing globals inside your function, your code will quickly be completely incomprehensible, because your functions are having sideeffects all over the place.

更糟糕的是,当您在函数内部更改全局变量时,您的代码将很快变得完全无法理解,因为您的函数到处都有副作用。

In lack of a better example, consider

在缺乏更好的例子的情况下,考虑

function fn()
{
    global $foo;
    echo $foo;     // side effect: echo'ing
    $foo = 'bar';  // side effect: changing
}

And then you do

然后你做

$foo = 'foo';
fn(); // prints foo
fn(); // prints bar <-- WTF!!

There is no way to see that $foogot changed from these three lines. Why would calling the same function with the same arguments all of a sudden change it's output or change a value in the global state? A function should do X for a defined input Y. Always.

没有办法看到$foo从这三行中改变了。为什么使用相同的参数调用相同的函数会突然改变它的输出或改变全局状态中的值?一个函数应该为定义的输入 Y 做 X。总是。

This gets even more severe when using OOP, because OOP is about encapsulation and by reaching out to the global scope, you are breaking encapsulation. All these Singletons and Registries you see in frameworks are code smells that should be removed in favor of Dependency Injection. Decouple your code.

这在使用 OOP 时会变得更加严重,因为 OOP 是关于封装的,并且通过扩展到全局范围,您正在破坏封装。您在框架中看到的所有这些单例和注册表都是代码异味,应该删除以支持依赖注入。解耦你的代码。

More Resources:

更多资源:

回答by deceze

The one big reason against globalis that it means the function is dependent on another scope. This will get messy very quickly.

反对的一个重要原因global是这意味着该函数依赖于另一个作用域。这会很快变得混乱。

$str1 = 'foo';
$str2 = 'bar';
$str3 = exampleConcat();

vs.

对比

$str = exampleConcat('foo', 'bar');

Requiring $str1and $str2to be set up in the calling scope for the function to work means you introduce unnecessary dependencies. You can't rename these variables in this scope anymore without renaming them in the function as well, and thereby also in all other scopes you're using this function. This soon devolves into chaos as you're trying to keep track of your variable names.

要求$str1$str2在调用范围内设置函数才能工作意味着您引入了不必要的依赖项。你不能再在这个范围内重命名这些变量而不在函数中重命名它们,因此在你使用这个函数的所有其他范围内也是如此。当您试图跟踪变量名称时,这很快就会陷入混乱。

globalis a bad pattern even for including global things such as $dbresources. There willcome the day when you want to rename $dbbut can't, because your whole application depends on the name.

global即使包含诸如$db资源之类的全局事物也是一种糟糕的模式。有来的一天,当你想重命名$db,但不能,因为你的整个应用程序依赖于名字。

Limiting and separating the scope of variables is essentialfor writing any halfway complex application.

限制和分离变量的范围对于编写任何复杂的应用程序都是必不可少的。

回答by Loek Bergman

Globals are unavoidable.

全球化是不可避免的。

It is an old discussion, but I still would like to add some thoughts because I miss them in the above mentioned answers. Those answers simplify what a global is too much and present solutions that are not at all solutions to the problem. The problem is: what is the proper way to deal with a global variable and the use of the keyword global? For that do we first have to examine and describe what a global is.

这是一个古老的讨论,但我仍然想补充一些想法,因为我在上面提到的答案中想念它们。这些答案简化了全局的含义,并提供了根本不是问题解决方案的解决方案。问题是:处理全局变量和使用关键字 global 的正确方法是什么?为此,我们首先必须检查和描述全局是什么。

Take a look at this code of Zend - and please understand that I do not suggest that Zend is badly written:

看看 Zend 的这段代码 - 请理解我并不建议 Zend 写得不好:

class DecoratorPluginManager extends AbstractPluginManager
{
/**
 * Default set of decorators
 *
 * @var array
 */
protected $invokableClasses = array(
    'htmlcloud' => 'Zend\Tag\Cloud\Decorator\HtmlCloud',
    'htmltag'   => 'Zend\Tag\Cloud\Decorator\HtmlTag',
    'tag'       => 'Zend\Tag\Cloud\Decorator\HtmlTag',
   );

There are a lot of invisible dependencies here. Those constants are actually classes. You can also see require_once in some pages of this framework. Require_once is a global dependency, hence creating external dependencies. That is inevitable for a framework. How can you create a class like DecoratorPluginManager without a lot of external code on which it depends? It can not function without a lot of extras. Using the Zend framework, have you ever changed the implementation of an interface? An interface is in fact a global.

这里有很多不可见的依赖。这些常量实际上是类。您还可以在此框架的某些页面中看到 require_once。Require_once 是一个全局依赖,因此创建了外部依赖。这对于框架来说是不可避免的。如何在没有大量依赖的外部代码的情况下创建像 DecoratorPluginManager 这样的类?如果没有很多附加功能,它就无法运行。使用 Zend 框架,您是否曾经更改过接口的实现?一个接口实际上是一个全局的。

Another globally used application is Drupal. They are very concerned about proper design, but just like any big framework, they have a lot of external dependencies. Take a look at the globals in this page:

另一个全球使用的应用程序是 Drupal。他们非常关心正确的设计,但就像任何大框架一样,他们有很多外部依赖。看看这个页面中的全局变量:

/**
 * @file
 * Initiates a browser-based installation of Drupal.
 */

/**
 * Root directory of Drupal installation.
 */
define('DRUPAL_ROOT', getcwd());

/**
 * Global flag to indicate that site is in installation mode.
 */
define('MAINTENANCE_MODE', 'install');

// Exit early if running an incompatible PHP version to avoid fatal errors.
if (version_compare(PHP_VERSION, '5.2.4') < 0) {
  print 'Your PHP installation is too old. Drupal requires at least PHP 5.2.4. See the     <a     href="http://drupal.org/requirements">system requirements</a> page for more     information.';
  exit;
}

// Start the installer.
require_once DRUPAL_ROOT . '/includes/install.core.inc';
install_drupal();

Ever written a redirect to the login page? That is changing a global value. (And then are you not saying 'WTF', which I consider as a good reaction to bad documentation of your application.) The problem with globals is not that they are globals, you need them in order to have a meaningful application. The problem is the complexity of the overall application which can make it a nightmare to handle. Sessions are globals, $_POST is a global, DRUPAL_ROOT is a global, the includes/install.core.inc' is an unmodifiable global. There is big world outside any function that is required in order to let that function do its job.

曾经写过重定向到登录页面吗?这正在改变一个全球价值。(然后你不是说'WTF',我认为这是对你的应用程序的糟糕文档的一个很好的反应。)全局变量的问题不在于它们是全局变量,你需要它们才能有一个有意义的应用程序。问题是整个应用程序的复杂性可能使它成为处理的噩梦。会话是全局变量,$_POST 是全局变量,DRUPAL_ROOT 是全局变量,includes/install.core.inc' 是不可修改的全局变量。为了让该功能完成其工作所需的任何功能之外都有很大的世界。

The answer of Gordon is incorrect, because he overrates the independence of a function and calling a function a liar is oversimplifying the situation. Functions do not lie and when you take a look at his example the function is designed improperly - his example is a bug. (By the way, I agree with this conclusion that one should decouple code.) The answer of deceze is not really a proper definition of the situation. Functions always function within a wider scope and his example is way too simplistic. We will all agree with him that that function is completely useless, because it returns a constant. That function is anyhow bad design. If you want to show that the practice is bad, please come with a relevant example. Renaming variables throughout an application is no big deal having a good IDE (or a tool). The question is about the scope of the variable, not the difference in scope with the function. There is a proper time for a function to perform its role in the process (that is why it is created in the first place) and at that proper time may it influence the functioning of the application as a whole, hence also working on global variables. The answer of xzyfer is a statement without argumentation. Globals are just as present in an application if you have procedural functions or OOP design. The next two ways of changing the value of a global are essentially the same:

Gordon 的答案是不正确的,因为他高估了函数的独立性,而将函数称为骗子则过于简单化了情况。函数不会说谎,当您查看他的示例时,该函数的设计不正确 - 他的示例是一个错误。(顺便说一句,我同意应该解耦代码的这个结论。) deceze 的答案并不是对情况的正确定义。函数总是在更广泛的范围内起作用,他的例子太简单了。我们都会同意他的观点,那个函数完全没用,因为它返回一个常量。无论如何,该功能是糟糕的设计。如果你想表明这种做法是不好的,请拿出一个相关的例子。拥有一个好的 IDE(或一个工具)在整个应用程序中重命名变量并不是什么大问题。问题是关于变量的作用域,而不是作用域与函数的区别。函数有适当的时间在流程中发挥作用(这就是为什么它首先被创建),并且在适当的时间它可能会影响整个应用程序的功能,因此也可以处理全局变量. xzyfer 的回答是一个没有论证的陈述。如果您有过程函数或 OOP 设计,那么全局变量也同样存在于应用程序中。下面两种改变全局值的方法本质上是一样的:因此也在处理全局变量。xzyfer 的回答是一个没有论证的陈述。如果您有过程函数或 OOP 设计,那么全局变量也同样存在于应用程序中。下面两种改变全局值的方法本质上是一样的:因此也在处理全局变量。xzyfer 的回答是没有论证的陈述。如果您有过程函数或 OOP 设计,那么全局变量也同样存在于应用程序中。下面两种改变全局值的方法本质上是一样的:

function xzy($var){
 global $z;
 $z = $var;
}

function setZ($var){
 $this->z = $var;
}

In both instances is the value of $z changed within a specific function. In both ways of programming can you make those changes in a bunch of other places in the code. You could say that using global you could call $z anywhere and change there. Yes, you can. But will you? And when done in inapt places, should it then not be called a bug?

在这两种情况下,$z 的值都在特定函数中发生了变化。在这两种编程方式中,您都可以在代码中的许多其他地方进行这些更改。你可以说使用 global 你可以在任何地方调用 $z 并在那里改变。是的你可以。但是你会吗?当在不恰当的地方完成时,它不应该被称为错误吗?

Bob Fanger comments on xzyfer.

Bob Fanger 对 xzyfer 的评论。

Should anyone then just use anything and especially the keyword 'global'? No, but just like any type of design, try to analyze on what it depends and what depends on it. Try to find out when it changes and how it changes. Changing global values should only happen with those variables that can change with every request/response. That is, only to those variables that are belonging to the functional flow of a process, not to its technical implementation. The redirect of an URL to the login page belongs to the functional flow of a process, the implementation class used for an interface to the technical implementation. You can change the latter during the different versions of the application, but should not change those with every request/response.

那么有人应该使用任何东西,尤其是关键字“全局”吗?不,但就像任何类型的设计一样,尝试分析它依赖于什么以及依赖于什么。尝试找出它何时发生变化以及如何变化。更改全局值应该只发生在那些可以随每个请求/响应而更改的变量中。也就是说,仅适用于属于流程功能流的那些变量,而不属于其技术实现。将 URL 重定向到登录页面属于流程的功能流,是用于技术实现接口的实现类。您可以在应用程序的不同版本期间更改后者,但不应在每个请求/响应中更改这些。

To further understand when it is a problem working with globals and the keyword global and when not will I introduce the next sentence, which comes from Wim de Bie when writing about blogs: 'Personal yes, private no'. When a function is changing the value of a global variable in sake of its own functioning, then will I call that private use of a global variable and a bug. But when the change of the global variable is made for the proper processing of the application as a whole, like the redirect of the user to the login page, then is that in my opinion possibly good design, not by definition bad and certainly not an anti-pattern.

为了进一步了解使用 globals 和关键字 global 时出现问题,何时不出现问题,我将介绍下一句,这句话来自 Wim de Bie 在写博客时:“个人是,私人否”。当一个函数为了它自己的功能而改变全局变量的值时,我会称这种私有使用全局变量和错误。但是当全局变量的改变是为了整个应用程序的正确处理时,比如将用户重定向到登录页面,那么在我看来这可能是好的设计,从定义上来说不是坏的,当然也不是反模式。

In retrospect to the answers of Gordon, deceze and xzyfer: they all have 'private yes'(and bugs) as examples. That is why they are opposed to the use of globals. I would do too. They, however, do not come with 'personal yes, private no'-examples like I have done in this answer several times.

回顾 Gordon、deceze 和 xzyfer 的回答:他们都以“私人是”(和错误)为例。这就是为什么他们反对使用全局变量。我也会这样做。然而,他们并没有像我在这个答案中多次做的那样带有“个人是的,私人的否”的例子。

回答by xzyfer

Simply put there is rarely a reason to globaland never a good one in modern PHP code IMHO. Especially if you're using PHP 5. And extra specially if you're develop Object Orientated code.

简而言之,global恕我直言,现代 PHP 代码中很少有理由也从来没有一个好的理由。特别是如果您使用的是 PHP 5。如果您正在开发面向对象的代码,则尤其如此。

Globals negatively affect maintainability, readability and testability of code. Many uses of globalcan and should be replaced with Dependency Injection or simply passing the global object as a parameter.

全局变量对代码的可维护性、可读性和可测试性产生负面影响。global可以而且应该用依赖注入或简单地将全局对象作为参数来代替的许多用途。

function getCustomer($db, $id) {
    $row = $db->fetchRow('SELECT * FROM customer WHERE id = '.$db->quote($id));
    return $row;
}

回答by unity100

Dont hesitate from using global keyword inside functions in PHP. Especially dont take people who are outlandishly preaching/yelling how globals are 'evil' and whatnot.

不要犹豫在 PHP 中的函数内使用 global 关键字。特别是不要接受那些古怪地鼓吹/大喊全球性如何“邪恶”之类的人。

Firstly, because what you use totally depends on the situation and problem, and there is NO one solution/way to do anything in coding. Totally leaving aside the fallacy of undefinable, subjective, religious adjectives like 'evil' into the equation.

首先,因为您使用的完全取决于情况和问题,并且在编码中没有一种解决方案/方法可以做任何事情。完全抛开诸如“邪恶”之类的不可定义的、主观的、宗教形容词的谬误。

Case in point :

案例:

Wordpress and its ecosystem uses global keyword in their functions. Be the code OOP or not OOP.

Wordpress 及其生态系统在其功能中使用 global 关键字。是代码 OOP 还是非 OOP。

And as of now Wordpress is basically 18.9% of internet, and its running the massive megasites/apps of innumerable giants ranging from Reuters to Sony, to NYT, to CNN.

到目前为止,Wordpress 基本上占互联网的 18.9%,它运行着无数巨头的大型网站/应用程序,从路透社到索尼,到纽约时报,再到 CNN。

And it does it well.

它做得很好。

Usage of global keyword inside functions frees Wordpress from MASSIVE bloat which would happen given its huge ecosystem. Imagine every function was asking/passing any variable that is needed from another plugin, core, and returning. Added with plugin interdependencies, that would end up in a nightmare of variables, or a nightmare of arrays passed as variables. A HELL to track, a hell to debug, a hell to develop. Inanely massive memory footprint due to code bloat and variable bloat too. Harder to write too.

在函数内部使用 global 关键字使 Wordpress 免于由于其庞大的生态系统而发生的大规模膨胀。想象一下,每个函数都在询问/传递来自另一个插件、核心和返回所需的任何变量。添加了插件相互依赖关系,这将导致变量的噩梦,或者作为变量传递的数组的噩梦。跟踪的地狱,调试的地狱,开发的地狱。由于代码膨胀和变量膨胀也导致巨大的内存占用。也比较难写。

There may be people who come up and criticize Wordpress, its ecosystem, their practices and what goes on around in those parts.

可能有人站出来批评 Wordpress、它的生态系统、他们的做法以及这些部分发生的事情。

Pointless, since this ecosystem is pretty much 20% of roughly entire internet. Apparently, it DOES work, it does its job and more. Which means its the same for the global keyword.

毫无意义,因为这个生态系统几乎占整个互联网的 20%。显然,它确实有效,它完成了它的工作等等。这意味着它与 global 关键字相同。

Another good example is the "iframes are evil" fundamentalism. A decade ago it was heresy to use iframes. And there were thousands of people preaching against them around internet. Then comes facebook, then comes social, now iframes are everywhere from 'like' boxes to authentication, and voila - everyone shut up. There are those who still did not shut up - rightfully or wrongfully. But you know what, life goes on despite such opinions, and even the ones who were preaching against iframes a decade ago are now having to use them to integrate various social apps to their organization's own applications without saying a word.

另一个很好的例子是“iframes are evil”原教旨主义。十年前,使用 iframe 是异端。并且有成千上万的人在互联网上反对他们。然后是 facebook,然后是社交,现在 iframe 无处不在,从“喜欢”框到身份验证,瞧——每个人都闭嘴。有些人仍然没有闭嘴——不管是对还是错。但是你知道吗,尽管有这些意见,生活仍在继续,即使是十年前反对 iframe 的人现在也不得不使用它们将各种社交应用程序集成到他们组织自己的应用程序中,一言不发。

......

......

Coder Fundamentalism is something very, very bad. A small percentage among us may be graced with the comfortable job in a solid monolithic company which has enough clout to endure the constant change in information technology and the pressures it brings in regard to competition, time, budget and other considerations, and therefore can practice fundamentalism and strict adherence to perceived 'evils' or 'goods'. Comfortable positions reminiscent of old ages these are, even if the occupiers are young.

编码器原教旨主义是非常非常糟糕的东西。我们中的一小部分人可能会在一家坚实的整体公司中获得一份舒适的工作,该公司有足够的影响力来承受信息技术的不断变化及其带来的竞争、时间、预算和其他方面的压力,因此可以实践原教旨主义和严格遵守感知到的“邪恶”或“善”。舒适的位置让人想起年老,即使占用者很年轻。

For the majority however, the i.t. world is an ever changing world in which they need to be open minded and practical. There is no place for fundamentalism, leave aside outrageous keywords like 'evil' in the front line trenches of information technology.

然而,对于大多数人来说,IT 世界是一个不断变化的世界,他们需要思想开放和务实。没有原教旨主义的容身之地,在信息技术的前线战壕中留下像“邪恶”这样令人发指的关键词。

Just use whatever makes the best sense for the problem AT HAND, with appropriate considerations for near, medium and long term future. Do not shy away from using any feature or approach because it has a rampant ideological animosity against it, among any given coder subset.

只需使用最适合手头问题的方法,并适当考虑近期、中期和长期的未来。不要回避使用任何特性或方法,因为它在任何给定的编码器子集中都对它有猖獗的意识形态敌意。

They wont do your job. You will. Act according to your circumstances.

他们不会做你的工作。你会。根据您的情况采取行动。

回答by mAsT3RpEE

I think everyone has pretty much expounded on the negative aspects of globals. So I will add the positives as well as instructions for proper use of globals:

我认为每个人都对全局变量的消极方面进行了大量阐述。因此,我将添加正面以及正确使用全局变量的说明:

  1. The main purpose of globals was to share information between functions. back when there was nothing like a class, php code consisted of a bunch of functions. Sometimes you would need to share information between functions. Typically the global was used to do this with the risk of having data corrupted by making them global.

    Now before some happy go lucky simpleton starts a comment about dependency injection I would like to ask you how the user of a function like example get_post(1)would know all the dependencies of the function. Also consider that dependencies may differ from
    version to version and server to server. The main problem with dependency injection is dependencies have to be known beforehand. In a situation where this is not possible or unwanted global variables were the only way to do achieve this goal.

    Due to the creation of the class, now common functions can easily be grouped in a class and share data. Through implementations like Mediators even unrelated objects can share information. This is no longer necessary.

  2. Another use for globals is for configuration purposes. Mostly at the beginning of a script before any autoloaders have been loaded, database connections made, etc.

    During the loading of resources, globals can be used to configure data (ie which database to use where library files are located, the url of the server etc). The best way to do this is by use of the define()function since these values wont change often and can easily be placed in a configuration file.

  3. The final use for globals is to hold common data (ie CRLF, IMAGE_DIR, IMAGE_DIR_URL), human readable status flags (ie ITERATOR_IS_RECURSIVE). Here globals are used to store information that is meant to be used application wide allowing them to be changed and have those changes appear application wide.

  4. The singleton pattern became popular in php during php4 when each instance of an object took up memory. The singleton helped to save ram by only allowing one instance of an object to be created. Before references even dependancy injection would have been a bad idea.

    The new php implementation of objects from PHP 5.4+ takes care of most of these problems you can safely pass objects around with little to no penalty any more. This is no longer necessary.

    Another use for singletons is the special instance where only one instance of an object must exist at a time, that instance might exist before / after script execution and that object is shared between different scripts / servers / languages etc. Here a singleton pattern solves the solution quite well.

  1. 全局变量的主要目的是在函数之间共享信息。回到没有像类那样的东西时,php 代码由一堆函数组成。有时您需要在函数之间共享信息。通常,全局用于执行此操作,但存在通过将数据设置为全局而损坏数据的风险。

    现在,在一些快乐的幸运傻瓜开始评论依赖注入之前,我想问你一个函数的用户如何get_post(1)知道函数的所有依赖关系。还要考虑依赖项可能因
    版本和服务器而异。依赖注入的主要问题是必须事先知道依赖关系。在这种情况下,这是不可能的或不需要的全局变量是实现此目标的唯一方法。

    由于创建了类,现在可以轻松地将常用功能分组到一个类中并共享数据。通过像 Mediator 这样的实现,甚至不相关的对象也可以共享信息。这不再是必要的。

  2. 全局变量的另一个用途是用于配置目的。大多数情况下,在加载任何自动加载器、建立数据库连接等之前的脚本开头。

    在加载资源的过程中,可以使用全局变量来配置数据(即使用哪个数据库,库文件所在的位置,服务器的 url 等)。最好的方法是使用该define()函数,因为这些值不会经常改变并且可以很容易地放置在配置文件中。

  3. 全局变量的最终用途是保存通用数据(即 CRLF、IMAGE_DIR、IMAGE_DIR_URL)、人类可读的状态标志(即 ITERATOR_IS_RECURSIVE)。这里全局变量用于存储打算在应用程序范围内使用的信息,允许更改它们并使这些更改在应用程序范围内显示。

  4. 在 php4 期间,当对象的每个实例都占用内存时,单例模式在 php 中流行起来。单例通过只允许创建一个对象的一个​​实例来帮助节省 ram。在引用之前,甚至依赖注入都是一个坏主意。

    PHP 5.4+ 对象的新 php 实现解决了大多数这些问题,您可以安全地传递对象而几乎没有任何惩罚。这不再是必要的。

    单例的另一个用途是特殊实例,其中一次只能存在一个对象实例,该实例可能在脚本执行之前/之后存在,并且该对象在不同脚本/服务器/语言等之间共享。这里单例模式解决了解决方案很好。

So in conclusion if you are in position 1, 2 or 3 then using a global would be reasonable. However in other situations Method 1 should be used.

因此,总而言之,如果您处于第 1、2 或 3 位,那么使用全局变量是合理的。但是,在其他情况下,应使用方法 1。

Feel free to update any other instances where globals should be used.

随意更新应该使用全局变量的任何其他实例。

回答by Bob Fanger

It makes no sense to make a concat function using the global keyword.

使用 global 关键字创建 concat 函数是没有意义的。

It's used to access global variables such as a database object.

它用于访问全局变量,例如数据库对象。

Example:

例子:

function getCustomer($id) {
  global $db;
  $row = $db->fetchRow('SELECT * FROM customer WHERE id = '.$db->quote($id));
  return $row;
}

It can be used as a variation on the Singleton pattern

它可以用作单例模式的变体