【问题标题】:PHP: PDO global database variable?PHP:PDO 全局数据库变量?
【发布时间】:2012-08-22 02:00:22
【问题描述】:

我已经编写 php 代码已经有一段时间了,但我最近开始接触面向对象的编程。

在我使用 mysql_connect()、mysql_query() 和所有这些函数之前,但后来我听说 PDO 会是更好的选择。

我想为什么不呢,然后看了一个基本的 PDO 视频。

try {
    global $db;
    $db = new PDO("mysql:host=$db_host;dbname=$db_name", $db_user, $db_pw);
} catch (PDOException $e) {
    die("ERROR: " . $e->getMessage());
}

print(gettype($db)."<br>");

function test() {
print(gettype($db));
}

test();

所以这里的问题是,我想创建一个函数,以便我可以轻松地将新项目插入我的表中。但是我遇到了这个问题,我的 $db 不是全局的。所以我在使用该功能时必须重新连接到我的数据库,但我不能这样做,这根本不好。

那么如何解决这个问题呢? 哦,上面的代码输出:

object
Notice: Undefined variable: db in /home/vhosts/ollie.ceify.net/www/ip-bless/connect.php on line 25 NULL

【问题讨论】:

标签: php mysql oop function object


【解决方案1】:

您也需要使用global 来获取全局变量。

function test() {
  global $db;
  print(gettype($db));
}

【讨论】:

  • 拥有超过 29k 的代表,您应该知道最好不要像那样使用 global
  • @Matt 当然我知道,但是你应该让操作知道如何在函数中使用全局变量。
  • @Matt 你能解释一下为什么将 $db PDO 对象作为参数传递比像“global $db”那样获取它更好吗?
  • @Matt 在知道某些东西不好之前,您必须先知道如何使用它,仅此而已。经验来自实践。
  • @Matt:在 Web 应用程序中使数据库句柄全局化并不是不合理的。从设计的角度来看,它并不完美,但这是一个可以接受的折衷方案。
【解决方案2】:

将变量作为参数传递给您的函数。

function test($dbObj) {
    print(gettype($dbObj));
}

您可以将您的函数放在一个对象中,并将$db 作为成员变量:

class myClass {
    public $db;

    public function __construct($dbObj) {
        $this->db = $db;
    }

    public function test() {
        print(gettype($this->db));
    }
}

$myVar = new myClass();
$myVar->test();

【讨论】:

  • 但是如果他有 100 个函数,每个函数有 5 个参数?他需要在每个函数中用这个 $db 添加 1 个新参数吗?
  • @boyd 这就是糟糕设计的代价。添加更多设计缺陷并不能修复设计缺陷。
  • @xdazz 我假设您是在引用我在函数中遗漏的public?接得好。固定的。谢谢!
  • @Matt 正常的设计是使用DI。
  • @Cory 看看我在 SO 上的历史,你会发现我不是巨魔。在捍卫最佳实践时,我可能有点过分热心,但当我错了时我承认。 xdazz 帮助我解决了我的错误,为此我向他表示了应有的感谢。
【解决方案3】:

我通常做的是定义一个函数来连接到数据库或获取已经可用的句柄。

function dbHandle()
{
    global $dbh;
    if (is_resource($dbh)) return $dbh;
    return $dbh = new PDO(...); # All your DB credentials here.
}

...举个简单的例子,如果您有更复杂的设置,例如,您可以将此信息存储在类的静态成员中。

【讨论】:

  • 不要这样使用global。这是非常糟糕的做法。
  • 超过 6 年的经验。 (如果包括大学,则为十个)。
  • @Matt 假设程序员都缺乏经验并且不能编写好的代码是一个谬论。如果您不能自己编写一个好的应用程序,那是您的问题。请不要用这些东西、权威谬误和使用黄鼠狼的话来误导新手。你看起来像个巨魔。
  • 这不是我的意见。这是业界公认的事实。
  • @Matt 但它你的意见。虽然一般来说避免使用全局变量是一个很好的经验法则,但在某些情况下,使用全局变量可以 简化您的代码。这是其中之一。请注意,这是基于了解范围之类的事情以及global 的实际作用,而不是插入它来解决直接问题(这总是一个坏主意)。如果您了解它的作用以及使用它的潜在风险;当然,为什么不呢?
【解决方案4】:

创建一个包含私有 PDO 对象的 on 对象,并定义一个接受表名、列名和值参数并可重复调用的公共查询方法:

class DatabaseObject{
  private $db;

  public function __construct() {
    $this->createDB();
  }

  private function createDB() {
    $this->db = PDO("mysql:host=localhost;dbname=yourdatabase", 'username', 'password');
        $this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
  }

  public function insert($table, $column, $value) {
    try {
      $this->db->query(sprintf("
        INSERT INTO %s (%s)
        VALUES (%s)",
        $table, $column, $value));
    }
    catch (PDOException $e) {
      return $e->getMessage();
    }
  }
}

$db = new DatabaseObject();
$db->insert('table_name', 'column_name', 'value');

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多