PHP 全局函数 [英] PHP global in functions

查看:26
本文介绍了PHP 全局函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

全局关键字有什么用处?

是否有任何理由更喜欢一种方法而不是另一种方法?

Are there any reasons to prefer one method to another?

  • 安全?
  • 性能?
  • 还有什么吗?

方法一:

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

方法二:

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

什么时候使用 global 有意义?

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.

提前致谢!

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

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.

推荐答案

全局是邪恶的

这适用于 global 关键字以及从局部作用域到全局作用域的所有其他内容(静态、单例、注册表、常量).您不想使用它们.一个函数调用不应该依赖任何外部的东西,例如

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.

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

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();

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

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
}

然后你做

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

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

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.

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

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.

更多资源:

  • http://c2.com/cgi/wiki?GlobalVariablesAreBad
  • How is testing the registry pattern or singleton hard in PHP?
  • Flaw: Brittle Global State & Singletons
  • static considered harmful
  • Why Singletons have no use in PHP
  • SOLID (object-oriented design)

这篇关于PHP 全局函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆