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

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

问题描述

全局关键字?

有没有理由偏爱一种方法而不是另一种方法?

Are there any reasons to prefer one method to another?

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

方法1:

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

方法2:

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

何时使用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的变量.但是,当您在函数内部引入全局$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与封装有关,并且通过扩展到全局范围,您正在破坏封装.您在框架中看到的所有这些Singletons和Registries是代码气味,应删除它们以利于依赖注入.解耦您的代码.

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天全站免登陆