PHP 全局函数

发布于 2024-10-19 21:45:14 字数 838 浏览 5 评论 0原文

全局关键字的用途是什么

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

  • 安全?
  • 表现?
  • 还要别的吗?

方法 1:

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

方法 2:

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

什么时候使用 global 有意义?

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


赏金

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

What is the utility of the global keyword?

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?

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.


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 global topic comes up every now and then, we could use a good "canonical" answer to link to.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

〃温暖了心ぐ 2024-10-26 21:45:14

全局变量是邪恶的

对于 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
}

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

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

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

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

另外,当您耦合到全局范围时,您的函数签名是

function fn()

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

如果您的函数需要参数才能运行,请明确它们并传入它们:

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

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

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

,这是拉入(全局关键字)与推入(参数)的问题。当您推入/注入依赖项时,该函数不再依赖于外部。当您执行 fn(1) 时,您不必在外部某个地方有一个保存 1 的变量。但是,当您在函数内引入全局 $one 时,您就会耦合到全局范围并期望它在某处定义一个变量。那么这个函数就不再是独立的了。

更糟糕的是,当您更改函数内部的全局变量时,您的代码很快就会完全难以理解,因为您的函数到处都有副作用。

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

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

然后你做

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

没有办法看到 $foo 从这三行发生了变化。为什么使用相同的参数调用相同的函数会突然改变它的输出或改变全局状态中的值?函数应该对定义的输入 Y 执行 X。始终如此。

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

更多资源:

Globals are evil

This is true for the global keyword 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.

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 $_GET or $_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.

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 $one inside 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.

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 $foo got 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.

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.

More Resources:

一抹微笑 2024-10-26 21:45:14

全局是不可避免的。

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

看一下 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',
   );

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

另一个全球使用的应用程序是 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();

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

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

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

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

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

鲍勃·范格 (Bob Fanger) 对 xzyfer 发表评论。

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

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

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

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.

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

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.

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:

/**
 * @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.

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:

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?

Bob Fanger comments on 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.

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.

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.

孤千羽 2024-10-26 21:45:14

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

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

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

要求在调用作用域中设置 $str1$str2 以使函数正常工作相比,意味着您引入了不必要的依赖项。如果不在函数中重命名这些变量,则无法再在此范围内重命名这些变量,因此在您使用此函数的所有其他范围中也是如此。当您试图跟踪变量名称时,这很快就会陷入混乱。

即使对于包含诸如 $db 资源之类的全局事物,global 也是一个糟糕的模式。有一天,您想要重命名 $db 但无法重命名,因为您的整个应用程序取决于名称。

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

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

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

vs.

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

Requiring $str1 and $str2 to 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.

global is a bad pattern even for including global things such as $db resources. There will come the day when you want to rename $db but can't, because your whole application depends on the name.

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

破晓 2024-10-26 21:45:14

简而言之,在现代 PHP 代码中,很少有理由使用 global,而且从来都不是一个好的理由。特别是如果您使用 PHP 5。更特别的是如果您正在开发面向对象的代码。

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

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

Simply put there is rarely a reason to global and 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.

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

function getCustomer($db, $id) {
    $row = $db->fetchRow('SELECT * FROM customer WHERE id = '.$db->quote($id));
    return $row;
}
流心雨 2024-10-26 21:45:14

不要犹豫在 PHP 函数内部使用全局关键字。特别是不要接受那些古怪地宣扬/大喊大叫全局变量是“邪恶”之类的人。

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

例证:

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

截至目前,Wordpress 基本上占据了互联网的 18.9%,它运行着无数巨头的大型网站/应用程序,包括路透社、索尼、纽约时报、CNN。

而且它做得很好。

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

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

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

另一个很好的例子是“iframe 是邪恶的”原教旨主义。十年前,使用 iframe 是异端邪说。成千上万的人在互联网上宣扬反对他们。然后是 Facebook,然后是社交,现在 iframe 无处不在,从“点赞”框到身份验证,瞧,每个人都闭嘴。有些人仍然没有闭嘴——无论正确还是错误。但你知道吗,尽管有这样的观点,生活仍在继续,甚至那些十年前鼓吹反对 iframe 的人现在也不得不使用它们将各种社交应用程序集成到其组织自己的应用程序中,而无需多言。

......

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

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

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

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

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.

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.

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.

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.

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

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.

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.

......

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.

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.

纸伞微斜 2024-10-26 21:45:14

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

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

示例:

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

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

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

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

也只是曾经 2024-10-26 21:45:14

我想每个人都已经阐述了全局变量的负面影响。因此,我将添加积极的一面以及正确使用全局变量的说明:

  1. 全局变量的主要目的是在函数之间共享信息。回来时
    没有什么比类更好的了,php 代码由一堆函数组成。有时
    您需要在功能之间共享信息。通常,全局用于
    这样做会冒着使数据全局化而导致数据损坏的风险。

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

    由于类的创建,现在常用的函数可以很容易地分组在一个类中
    并共享数据。通过像中介者这样的实现,即使不相关的对象也可以共享
    信息。这不再是必要的。

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

    在资源加载过程中,可以使用全局变量来配置数据(即
    使用库文件所在的数据库、服务器的 URL 等)。最好的
    执行此操作的方法是使用 define() 函数,因为这些值不会经常更改
    并且可以轻松地放置在配置文件中。

  3. 全局变量的最终用途是保存通用数据(即CRLF、IMAGE_DIR、IMAGE_DIR_URL),
    人类可读的状态标志(即 ITERATOR_IS_RECURSIVE)。这里使用全局变量来存储
    旨在在应用程序范围内使用的信息,允许对其进行更改和
    让这些更改出现在应用程序范围内。

  4. 单例模式在 php4 期间在 php 中变得流行,当时对象的每个实例
    占用了内存。单例通过只允许一个实例来帮助节省内存
    要创建的对象。在引用之前,即使依赖注入也是很糟糕的
    想法。

    PHP 5.4+ 中对象的新 php 实现解决了大部分问题
    你可以安全地传递物体,几乎不会受到任何惩罚。这不再是
    必要的。

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

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

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

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.

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.

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文