函数值内的全局变量为NULL

时间:2012-03-12 15:01:38

标签: php mysqli phpunit global-variables

在我的代码中,我有一个初始化MySQLi类的文件。

File a

$db = new Database(); //MySQLi class

无论如何,有一个包含此数据库类的文件。该文件还包括其中声明了函数的其他文件。我正在使用global$db

联系

File b

function xy(){
   global $db;
   $sql = "..."
   return $db->getArray($sql);
}

Testfile

require "file_a.php";
require "file_b.php";
require_once "PHPUnit/Framework/TestCase.php";

class testProblemStatistics extends PHPUnit_Framework_TestCase {

  testArray(){
      $this->assertTrue(array_key_exists('xy', $this->xy())
  }
}

我明白了:
致命错误:在非对象上调用成员函数getArray()

我调查过:

var_dump($db);
function xy(){
  global $db;
  var_dump($db);
  ...
}

第一个转储给了我 MySQLi对象
第二个转储给了我 NULL

file_b中的全局变量有问题。

附加信息:我正在使用PHPUnit,我在命令提示符下运行它。在普通浏览器中,一切正常。

4 个答案:

答案 0 :(得分:10)

解决方案是将数据库类硬编码到$GLOBALS数组中。

$GLOBALS['db'] = $db;

将此添加为PHPUnit引导程序对我来说很好。它有点hacky,应该用在测试用例中。

答案 1 :(得分:4)

您必须完全理解PHPUnit的手册on Global State

  

默认情况下,PHPUnit以对全局更改的方式运行测试   和超全局变量($ GLOBALS,$ _ENV,$ _POST,$ _GET,$ _COOKIE,   $ _SERVER,$ _FILES,$ _REQUEST)不影响其他测试。 (可选)   这种隔离可以扩展到类的静态属性。

很可能,$ db全局变量是在测试期间创建的。因此,在测试之后将其擦除回null。您可以在setUp()中设置全局变量,或者自己管理您希望PHPUnit如何使用此全局变量。有几种方法可以做到这一点。

切换@backupGlobals的值,它不会在测试之间执行备份/恢复操作:

<?php

function xy(  ) {
    global $foo;
    var_dump( $foo ); 
    return $foo;
}

/**
 * @backupGlobals disabled
 */
class someTestCase extends PHPUnit_Framework_TestCase {

    public function testA(  ) {
        global $foo;
        $foo = 'bar';
    }  

    public function testB(  ) {
        global $foo;
        $this->assertEquals( $foo, 'bar' ); 
    }  
}

您是否明白为什么@backupGlobals enabled会使@backupGlobals disabledprotected $backupGlobalsBlacklist = array( 'db' ); 通过时失败?

如果要备份/恢复除$ db之外的全局变量,请定义这样的类属性:

{{1}}

这也有效。实际上,这会更好,因为测试隔离很好。

答案 2 :(得分:3)

似乎在PHPUnit中运行时,文件a中的顶级代码在某个方法中运行,而对$ db的赋值是指局部变量。使其显式全局化,以便在测试运行中保持这种状态:

global $db;
$db = new Database(); //MySQLi class

答案 3 :(得分:0)

zerkms的回答帮助我:https://stackoverflow.com/a/4074833/2016870

  

我打赌你通过在另一个函数中包含这个文件来执行这段代码。

     

所以你需要标记为全局第一个变量出现

     

顺便说一句,全局变量很奇怪,将数据传递给函数的更简单和正确的方法是使用伪造参数。