2011-04-24 188 views
0

我的问题是我在我的通用脚本代码中和我的一个函数中使用变量$ db。它的目的是成为用于MySQL连接的变量。我需要在函数内部写入一些数据到数据库。在我的脚本中,我不能假定现有的数据库连接将会打开,因此我打开一个新的连接并在函数退出之前关闭它。自从这样做以后,脚本运行后说我的MySQL引用不好/不存在,我得到一个错误。PHP,变量范围问题

我可以将它固定在我的核心代码中的唯一我使用变量$ db作为数据库连接的变量名称。我也在函数中使用相同的变量。我没有想到这会是一个问题,因为我不在函数的$ db前面使用global。这应该意味着我的函数中的$ db引用在私有函数中,但似乎是关闭了公共$ db的连接。

有什么想法?我的代码

片段:

database.php中

db_connect() 
{ 
// open mysql db connection and return it; 
} 

db_close(&$db) 
{ 
// close the passed by reference db connection 
} 

api.php

api_verify($keyid, $userid, $key) 
{ 
    // open a new db connection 
    $db = db_connect(); 

    // check for errors. if any errors are found note them in the db 

    // close the db 
    db_close($db); 
} 

main.php

include api.php; 
include database.php; 

// open a connection to the db 
$db = db_connect(); 

// pull a list of things to process from the db and move through them one at a time 
    // call api_verify() on each key before working through it's data. 

db_close($db) 
+1

这取决于您的连接代码。如果实际上是从池中提供连接,并且其中一个内部方法关闭了连接,则外部方法之一所指向的连接可能会过时 – JohnP 2011-04-24 07:12:27

+2

不要关闭连接...如果您打开一个新连接使用相同的参数,它只是重用已经打开的连接,所以如果你关闭了你的api函数中的连接,你可以在任何地方关闭它 - 即使你不通过引用 – prodigitalson 2011-04-24 07:15:14

+0

为什么关闭连接? – zerkms 2011-04-24 07:16:18

回答

1

我假设你打开一个连接到同一个数据库,在你调用db_connect的每个地方都有相同的用户名/密码。这样做时,除非您的db_connect明确指定了您正在创建新链接,否则它将返回已打开的链接。如果使用db_close()关闭了该链接,则它也将关闭另一个连接,因为链接是相同。如果使用mysql_connect连接到数据库,则需要一个名为new link的参数

new_link 如果使用相同参数对mysql_connect()进行第二次调用,则不会建立新链接,而是已经打开的链接的链接标识符将被返回。 new_link参数修改了这个行为,并且使得mysql_connect()总是打开一个新的链接,即使mysql_connect()之前被调用了相同的参数。在SQL安全模式下,该参数被忽略。

参考http://php.net/manual/en/function.mysql-connect.php

我不知道这是否是你所面临的问题。希望能帮助到你。

+0

伟大的工作!这是我正在寻找的。我自己搜索谷歌和php.net,但那些知道它的人真的是最好的资源! – 2011-04-26 14:02:30

1

我会假设发生了什么是连接取消,因为已经有一个连接,然后关闭结束当前连接。
我会推荐A)在文件的开始处启动一个连接,并且知道它总是在那里(我所做的);或B)检查$ db变量是否已设置,如果没有,则创建连接,并始终在文件结尾处结束连接。

2

要管理数据库连接,您可以创建一个类而不是一对功能。如果你在哪里说“MySQL参考”,确切的错误是指“MySQL资源”,那么你正在使用过时的mysql扩展,并应该切换到更现代的扩展,比如PDO。

class DBConnection { 
    protected static $_connections = array(), 
    static connect($dsn) { 
     if (!isset(self::$_connections[$dsn])) { 
      $credentials = self::getCredentials(); 
      /* Create connection. For example: */ 
      try { 
       self::$_connections[$dsn][0] = new PDO($dsn, $credentials['username'], $credentials['password']); 
      } catch (PDOException $exc) { 
       // erase the frame w/ password from call trace to prevent leak. 
       throw new PDOException($exc->getMessage(), $exc->getCode()); 
      } 
      /* End create connection example */ 
      self::$_connections[$dsn][0]->dsn = $dsn; 
     } 
     ++self::$_connections[$dsn]['count']; 
     return self::$_connections[$dsn][0]; 
    } 
    static close($db) { 
     if (isset(self::$_connections[$db->dsn])) { 
      if (--(self::$_connections[$db->dsn]['count']) < 1) { 
       unset(self::$_connections[$db->dsn]); 
      } 
     } 
    } 
    static getCredentials() { 
     /* credentials can be stored in configuration file or script, in this method, or some other approach of your own devising */ 
    } 
} 

注意,这是不完全的OOP(它是,但只有在技术意义上)。以上不适用于单元测试。如果你想要更多的面向对象的方法(这将更适合单元测试),扩展或包装PDO。使用dependency injection也可以帮助解决上述的coupling问题。

+0

我喜欢你使用课堂的观点。根本不是一个坏主意=)。 – 2011-04-26 14:03:01

+0

@Mr。丢失:私有状态+函数= OOP(或函数式编程,但需要PHP 5.3或更高版本,结果仍然是OOP)。 – outis 2011-04-26 19:34:26