在 php 中使用“全局”

Posted

技术标签:

【中文标题】在 php 中使用“全局”【英文标题】:using 'global' in php 【发布时间】:2011-09-12 17:11:44 【问题描述】:

我在这里处于学习模式,对 php 非常陌生,所以我正在使用代码示例。 请原谅我在这里使用“全局”,但我想了解 php 变量范围。

这是 myGlobals.php:

<?php 
     global $db_server;
   // other code not shown
?>

这里是 connectToDb.php:

<?php
      require_once 'myGlobals.php';

      // no declared functions in this file, all inline code
      $db_server = mysql_connect(.....);
      mysql_select_db( "theDatabase", $db_server);
?>

这里是 addDbRecords.php:

<?php
       require_once 'myGlobals.php';

       // other inline code.....
       doAddDeleteRecord($db_server);

function doAddDeleteRecord($db_server)

  //global $db_server;

  if( !mysql_query($query, $db_server))
   
         // handle the error...
   
 
?>

这里是 index.php:

<?php
      require_once 'myGlobals.php';
      require_once 'connectToDb.php';
      require_once 'addDbRecords.php';

     // this is simplified, just trying to show that everything in inline code
 ?>

这就是问题所在。当我在文件 addDbRecords.php 中调用 doAddDeleteRecord($db_server) 时 上面,$db_server 无效——它为空——当我调用 mysql_query(.., $db_server, ...) 时——这是错误消息:

“警告:mysql_query() 期望 参数 2 为资源,给定 null 在 C:\xampp\htdocs\addDbRecords.php 上 第 29 行“

所以我尝试在doAddDeleteRecord()(上面注释掉)中使用“全局”声明——没有变化。mysql_query(...) 仍然失败,$db_server 的值为 NULL。

我知道mysql_connect(....) 有效,因为其他代码成功地将我的所有记录从我的数据库中提取出来(使用 SELECT)并且现有记录在浏览器中正确显示。

所以在我看来,$db_server 被声明为“全局”这一事实应该意味着 $db_server 的范围是这样的@ 将是与我的数据库的有效连接。

我只是想了解 php 作用域,而不是 OOAD 或其他任何东西(目前)。为什么$db_server() 在这里为空?

【问题讨论】:

永远不要使用require_once。使用要求 @yes123:为什么?大多数答案here 似乎声称这是一个神话。 如果你仍然使用旧的mysql_接口函数,你不必传递连接句柄。如果只打开一个,则隐式使用。 (除非你传递一个空值。) @require_once:这可能确实是这里出现问题的原因,因为myglobals.php 脚本实际上只是加载了一次,而 OP 可能打算将它包含在其中多次。 (不过,普遍的反对毫无意义。) @mario:除了 OP 没有在函数内部使用include[_once]。 OP 将它包含在每个文件的顶部,无论你如何剪切它仍然需要使用 global 修饰符才能在函数中使用这些变量。 【参考方案1】:

所以,你有:

<?php 
     global $db_server;
   // other code not shown
?>

你在需要的地方加入这个:

require_once 'myGlobals.php';
// other inline code.....
doAddDeleteRecord($db_server);

问题是如果你已经在别处包含了'myGlobals.php',它就不会被包含在这里。所以你不能保证全局会被纳入范围。

改为:

require 'myGlobals.php';
// other inline code.....
doAddDeleteRecord($db_server);

或者采取更好的方法:

// other inline code.....
doAddDeleteRecord($GLOBALS['db_server']);

【讨论】:

+1 你在函数中使用global 告诉 PHP 你想使用一个全局范围的变量,而不是创建一个只在函数中可见的私有范围的变量。 我不同意,我现在有一个四文件设置,它们全部使用require_once()。第一次执行语句global $db_server 就足够了。 @Darien:仅当您始终在全局范围内包含文件时。 实际上我的回答的问题在于,他的任何文件中根本都不需要global 这也是一个问题,但我的意思是global $foo; 的副作用,当(毫无意义地)在全局范围内完成时,也是全局的......只要它被包含在内一次,足够早,你永远不需要再次包含它。这就像您在全局范围内定义了一个函数或类一样。【参考方案2】:

我认为范围隐藏存在问题;也就是说,您对全局变量和函数局部变量使用相同的名称 ($db_server)。函数局部作用域隐藏了全局变量名。如果你有一个全局的,你不需要将它传递给你的函数;如果这样做,请不要使用相同的名称。

【讨论】:

我将变量名更改为“function doAddDeleteRecord($db_server_global_scope)”,并在对 mysql_query(.., $db_server_global_scope, ...) 的调用中使用了 db_server_global_scope——没有变化。仅供参考,我之前没有在任何地方使用“全局”,只是添加它来尝试解决这个问题。如果我在任何地方删除“全局”,它仍然是同样的问题。注意:对 doAddDeleteRecord($db_server_global_scope) 的调用失败是当我的“添加记录”表单回发到文件时——我由于 POST 重新输入代码的事实是否会以某种方式使 db_server 为空?

以上是关于在 php 中使用“全局”的主要内容,如果未能解决你的问题,请参考以下文章

何时在面向对象的 php 中的超级全局变量中使用“@”? [复制]

PHP-作用域相关

PHP函数声明

php中静态变量和静态方法

是否可以在不使用全局变量的 PHP 5.2.x 中模拟闭包?

php超级全局变量