PHP:函数甚至不知道变量是否存在

PHP:函数甚至不知道变量是否存在,php,function,variables,Php,Function,Variables,我注意到PHP(运行5.2.11)中有一个恼人的特性。如果一个页面包含另一个页面(并且都包含自己的变量和函数),那么两个页面都知道彼此的变量。但是,它们的函数似乎根本不知道任何变量(函数中声明的变量除外) 我的问题:为什么会发生这种情况?我怎样才能让它不发生,或者有什么更好的方法来实现这一点 下面是我描述的一个例子 主页: <?php $myvar = "myvar."; include('page2.php'); echo "Main script says: $somevar and

我注意到PHP(运行5.2.11)中有一个恼人的特性。如果一个页面包含另一个页面(并且都包含自己的变量和函数),那么两个页面都知道彼此的变量。但是,它们的函数似乎根本不知道任何变量(函数中声明的变量除外)

我的问题:为什么会发生这种情况?我怎样才能让它不发生,或者有什么更好的方法来实现这一点

下面是我描述的一个例子

主页:

<?php
$myvar = "myvar.";
include('page2.php');

echo "Main script says: $somevar and $myvar\n";
doStuff();
doMoreStuff();
function doStuff() {
    echo "Main function says: $somevar and $myvar\n";
}
echo "The end.";
?>

page2.php:

<?php
$somevar = "Success!";

echo "Included script says: $somevar and $myvar\n";

function doMoreStuff() {
    echo "Included function says: $somevar and $myvar\n";
}
?>

输出:

包含的脚本说:成功!和myvar。
主剧本说:成功!和myvar。
主要功能是:和
包含的函数表示:和
结束。

两个页面输出的变量都很好。它们的功能不起作用。

WRYYYYYY

在函数范围内使用外部定义变量之前,需要使用
global


function doStuff() {
    global $somevar, $myvar;
    echo "Main function says: $somevar and $myvar\n";
}
更多详细说明请参见:


正如评论和其他答案准确指出的那样,全球化可能是邪恶的。查看这篇解释原因的文章:

虽然您可以使用全局变量,但通常在调用函数时将变量作为参数传递给函数是一种很好的做法。这可以确保您确切地知道函数正确执行所需的变量。这不是一个bug,只是预期的功能

还要注意,函数作用域之外的变量本身不必具有匹配的名称作为函数参数。这允许您执行以下操作:

$badVar = 'look at me, im a bad var.';
goodFunction($badVar);

function goodFunction ($goodVar) {
    // output: look at me, im a good var
    echo str_replace('bad', 'good', $goodVar);
}

php没有作用域层次结构,也就是说,函数不知道彼此(或全局)的变量。如果您以前使用过其他语言,这有点奇怪,但这本质上是件好事,因为globals是“邪恶的”。最好的方法是完全避免使用它们。

没错,但这是个坏主意——在大多数情况下,全局变量仅次于使用参数。:-)这个想法很糟糕,但是它遵循了原始代码的想法。一个更明智的解决方案是将变量作为参数或类似的东西传递。Spooky-只是更新了我的评论,说::-)我不是说这是一个好的解决方案。只是指出一个在理论层面上有效的解决方案。这不应该用在制作阶段。谢谢Joel,这正是我需要的。请参阅我对cballou的回复,了解为什么我不能在我的情况下使用参数。+1用于做正确的事情(并花时间解释)。问题出现在这里:我有很多文件要处理,全局文件要记录正确的文件扩展名和目录等内容。所以我说的不是“images/avatars/$userID.jpg”,而是$FOLDER['avatars']$用户ID$文件_EXT['avatars']。。。我不会把那些东西当作论点来传递。谢谢你的回复。无论如何,你真的应该考虑把信息存储在某种对象结构中而不是全局的。好吧,我想我必须研究一下。有什么建议或链接可以让我走上正轨吗?(这学期刚结束,我学习了OOP)我想我不知道你为什么这么快就放弃了传递参数,因为你的函数没有理由不把文件夹名、用户id和文件扩展名作为参数。这将是一个很好的实践。这是许多语言中的行为,如果不是大多数其他语言的话。一点也不奇怪。相信我,这不是PHP中的一个bug或错误,如果它按照你所说的方式工作,那将是一片混乱。我认为最好是传递函数所需的任何变量,这使函数更易于移植,您可以在其他项目上轻松使用它
$badVar = 'look at me, im a bad var.';
goodFunction($badVar);

function goodFunction ($goodVar) {
    // output: look at me, im a good var
    echo str_replace('bad', 'good', $goodVar);
}