为什么使用" global"内部函数引用?

时间:2012-01-03 17:08:36

标签: php security function scope encapsulation

  

可能重复:
  Are global variables in PHP considered bad practice? If so, why?
  global in functions

编辑:问题在上面的链接中回答。

不,php中的“global”与其他语言中的global不同,虽然它没有引入任何安全问题,但它可以使代码对其他人的理解变得不那么容易理解。


OP:

项目摘要 - 我正在编写一个Web CMS,以便熟悉PHP / MySQL。为了分解代码,我有一个基本层/模块的概念:

数据
  - MySQL表
  - PHP变量

功能
  - SQL - 获取/设置/等
  - 前端 - 显示页面
  - 后端 - 经理

演示
  - HTML模板
  - 页面内容
  - CSS样式表

目标很普遍。使用MySQL来保存站点设置和页面内容,使用php来获取/操作正在提供的页面的内容数据,然后插入到html模板中并回显到浏览器。来自C#等OO语言,我遇到的第一个问题是使用包含和函数时的可变范围问题。

从一开始我就编写了仅限函数的php文件,并将其包含在其他具有现有变量数组定义的文件中。例如,暂时忽略数据层,一个简单的页面通常可能如下所示:

文件1(页面)

$DATA_PAGE = Array
(
  'temp'  = null,
  'title' = null,
  [...]
);

include 'functions.php';

get_data ( 'page.php' );

[...]

run_html ();

文件2(功能)

function get_data ( $page_name )
{
  global $DATA_PAGE;

  $DATA_PAGE [ 'temp'  ] = 'template';
  $DATA_PAGE [ 'title' ] = 'test page';
  [...]
}

function run_html ()
{
  global $DATA_PAGE;

  echo '<html>';
  echo '<head>';
  echo '<title>' . $DATA_PAGE [ 'title' ] . '</title>';
  [...]
}

我选择这种方法有几个原因:

  • sql fetch之后这些数组中的数据可能会在任何地方使用,包括页面内容
  • 我不想拥有十几个函数参数,或者传递整个数组

代码运行良好。但是在我发现的每一篇文章中,我的函数中的“全局”调用被称为不良实践,即使这些文章从未说明为什么?我认为这意味着“使用父范围”。我在我的应用程序中引入了一个安全漏洞?有更好的方法吗?提前谢谢。

5 个答案:

答案 0 :(得分:8)

我认为避免这种情况的一个主要原因是它隐藏了依赖关系。

您的功能get_datarun_html不会以任何方式宣传他们共享数据,但他们却以一种很大的方式进行宣传。如果没有调用run_html,那么就没有办法(没有阅读代码)知道get_data将毫无用处。

随着代码库复杂性的增加,这种潜在的依赖性将使您的代码变得脆弱且难以推理。

答案 1 :(得分:2)

因为全局变量可以被进程修改而不需要代码的其他部分知道它会产生意外结果。

您应该始终尽量保持变量作为本地范围 - 这不仅可以帮助您进行调试,还可以使您的代码更容易,更清晰地阅读和返回并修改。

如果您希望跨多个函数共享数据,您可能会考虑为数据创建一个类,然后定义操作封装在对象中的数据的方法。 (面向对象的编程)

答案 2 :(得分:1)

出于多种原因,例如:

  • 很难用全局变量支持代码。您不知道全局变量可能会影响您的逻辑,也不会控制对它们的访问

  • 安全性 - 如果您有复杂的系统(尤其是插件),有人可能会使用全局变量危害所有系统。

答案 3 :(得分:1)

全局变量中的设置很好,但正如tkone所说,将可修改的数据放入全局变量可能会产生意想不到的结果。

尽管如此,我不同意应该不惜一切代价避免全局变量的想法 - 只需尝试将它们包装成单例设置类。

答案 4 :(得分:0)

将不同范围的变量用于您自己的变量是不好的做法,因为它会降低您的代码的可移植性。换句话说,如果我想在其他项目的其他地方使用get_data()函数,我必须先定义$DATA_PAGE变量才能使用它。

AFAIK这是应该避免的唯一原因 - 但这是一个很好的理由。

我会通过引用传递。

function get_data (&$data_page, $page_name )
{
  $data_page['temp'] = 'template';
  $data_page['title'] = 'test page';
  [...]
}
get_data($DATA_PAGE);