为什么使用包含连接一次是失败的pdo


Why Connecting using include once is failing with pdo?

为什么使用pdo连接一次包含失败?
当我连接到数据库,包括一个连接页面,它给了我一个错误,但当我把连接代码,我删除包括我没有得到错误。有什么问题吗?

Error Fatal error: Call to a member function prepare() on a non-object in C:'wamp'www'tish'A'view.php on line 167
连接页面:

<?php
  function connected_Db(){
    try {
      $con = new PDO('mysql:host=localhost;dbname=tish_database;charset=utf8','root','');
    } catch(PDOException $e){
      echo 'Connection failed'.$e->getMessage();
    }
  }
  connected_Db();
?>

我在其他页面中包含它的方式:

include_once('pdo.inc.php');
connected_Db();
global $con;

永远不要让$con在函数connected_Db之外可用。了解变量作用域。您应该从函数中return它,并像这样使用它:

require_once 'pdo.inc.php';
$con = connected_Db();

这也意味着您不应该catch连接错误(至少不在那里),因为如果函数不能返回PDO连接,您的脚本不需要继续。

首先,需要告诉PDO在连接错误时抛出异常。
其次,你不应该抓住它们,至少不要使用try ..抓住。

所以代码必须是

pdo.inc.php:

<?php
function connected_Db(){
    $dsn  = 'mysql:host=localhost;dbname=tish_database;charset=utf8';
    $opt  = array(
        PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
    );
    return new PDO($dsn,'root','', $opt);
}

(你也可能希望通过函数参数传递连接选项)

其他文件

include_once('pdo.inc.php');
$con = connected_Db();

你不能在全局作用域中设置函数变量为全局变量。变量$con早就被GC了:一旦函数返回,它就会被释放。试试这个:

function connected_Db()
{
   return new PDO('mysql:host=localhost;dbname=tish_database;charset=utf8','root','');
}
//global scope:
$con = connect_Db();

如果你坚持使用global关键字,这是不是一个好主意,你应该这样使用它:

function connected_Db()
{
    global $con;//use the global var, set at top of function
    $con = new PDO('mysql:host=localhost;dbname=tish_database;charset=utf8','root','');
}
$con = null;// declare global var (optional, but a notice will be issued if not declared)
connect_Db();
var_dump($con);

正如你所看到的,我已经——像decze和YourCommonSense建议的那样——删除了try-catch块(这里你不需要)。它还表明,您实际上也不需要函数调用。如果您这样写,您的脚本将工作得非常好(甚至稍微快一点):

//global scope (or whatever scope you need it to be)
$con = new PDO('mysql:host=localhost;dbname=tish_database;charset=utf8','root','');

您正在错误地使用global。它应该在函数中,指定变量来自函数外部,即在全局作用域中。

function connected_Db()
{
    global $con;
    $con = null;
    try
    {
       $con = new PDO(...);
    }
    catch(PDOException $e)
    {
        die('Could not connect: '.$e->getMessage());
    }
}

但是最好返回连接,而不是从全局作用域中拉入。

function connected_Db()
{
    try
    {
       return new PDO(...);
    }
    catch(PDOException $e)
    {
        die('Could not connect: '.$e->getMessage());
    }
}