【发布时间】:2011-01-04 19:31:45
【问题描述】:
根据许多来源,register_globals(即全局变量)应该在您的 php.ini 中禁用。 如果全局变量被禁用,我应该在我的代码中编写 define() 并使用常量吗?这些甚至是相关的吗?
【问题讨论】:
标签: php variables global constants
根据许多来源,register_globals(即全局变量)应该在您的 php.ini 中禁用。 如果全局变量被禁用,我应该在我的代码中编写 define() 并使用常量吗?这些甚至是相关的吗?
【问题讨论】:
标签: php variables global constants
常量,一旦定义,就无法更改。
不要将常量用作变量。如果您需要在函数中使用变量,请将它们传递给函数本身。以预期使用的方式使用所有内容。变量是variable,常量是constant。
【讨论】:
它们是相关的,因为它们具有全局作用域,但常量一旦定义就不会改变,这与页面可以在运行时修改的全局变量不同。所以只是切换到使用 define() 而不是全局不会有太大帮助。
最好重构方法以将变量作为参数并依靠它来传递变量。
【讨论】:
这里有几件事。
首先,您在 php.ini 中禁用的 register_globals 指的是旧的 PHP 功能,其中通过查询字符串 (GET) 或表单 (GET/POST) 发送的任何变量都将转换为全局 PHP 变量。这是在您关闭 register_globals 时(并且应该)禁用的功能。即使关闭此选项,您仍然可以在应用程序中定义全局变量。
在一般的编程术语中,全局变量(不是 PHP 的 register_globals)被认为是“坏的”,因为当您遇到一个程序员时,您不知道应用程序的其他部分可能正在使用或更改它,或者对您的对该全局的更改可能会发生。此外,如果您要定义一个新的全局变量,则有可能会覆盖其他人所依赖的现有变量。当变量在本地定义时(在单个函数中,或在其他语言中的单个块中),您可以检查本地范围并通常确定对该变量的更改会做什么。
另一方面,常数永远不会改变。你定义它们一次,它们就保持定义,没有人可以改变它们。这就是为什么拥有全局常量被认为比拥有全局变量“更糟糕”的原因。
【讨论】:
全局变量不是常量(您可以更改全局变量的值,但您只能定义一次常量)。
常量并不总是全局的(您可以在类中声明常量)。
此外,全局变量可以是任何类型:标量、数组或对象。常量只能是标量。
我不会说常量或全局变量是好是坏。如果使用得当,它们都有有益的用途。 register_globals 功能存在一些安全问题,这些问题与更一般的全局变量使用不同。
【讨论】:
一些常量示例:
<?php
// Certainly constant
define('MINUTES_PER_HOUR', 60);
define('DOZEN', 12);
// Constant, but specific to this application
define('GREETING', 'Dear %s');
define('TIMEOUT', 30);
// Configurable, but constant for this installation
define('DATABASE', 'mydb');
define('IMAGES_DIRECTORY', '/tmp/images');
// Not constant, or some other reason why can't be constant
$user = $_POST['userid'];
$days_of_week = array('Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su');
?>
【讨论】:
试试这个简单的测试:
文件A.php:
<?php
define('SOMEVAL', 2);
?>
fileB.php:
<?php
if(defined('SOMEVAL')) echo SOMEVAL;
else echo "SOMEVAL does not exists\n";
include 'fileA.php';
if(defined('SOMEVAL')) echo 'SOMEVAL='.SOMEVAL;
else echo "SOMEVAL does not exists\n";
?>
然后运行fileB.php,你会看到在你包含fileA.php之前,SOMEVAL没有被定义。所以这意味着在你定义任何东西之前,它对脚本是不可见的。
【讨论】:
需要考虑的其他事项——常量不能存储诸如数组或对象之类的东西,而定义到 $GLOBALS 的东西可以是任何变量类型。所以在某些情况下,如果你需要一些全局的东西,但不能通过使用 define() 将它存储到一个常量,你可能想要使用 $GLOBALS 来代替。
另外,register_globals 和 $GLOBALS 不是一回事!
【讨论】:
如果两者同名,你可以在函数内部更改全局变量,因为局部变量会覆盖全局变量,但不会改变外部全局变量的值。如果你想在不同的函数中使用同名变量,则在常量中这不允许你并给出错误,因为它定义了一次并在所有程序中使用,你不能在任何函数或块中更改此变量的值,它是固定值。
【讨论】: