gpt4 book ai didi

php - 我正在尝试结合 PDO 和 OOP,但无法正常工作

转载 作者:行者123 更新时间:2023-11-29 01:22:43 25 4
gpt4 key购买 nike

所以我基本上有两个文件。最后我会有更多,但我想创建一个名为 DB 的类,它会使用 PDO 数据库操作,然后我会扩展这个类,使我的所有功能都可以使用数据库.所以 DB 类将扩展到 dbADD 类,它将具有针对不同数据库表的所有添加功能。

这叫做 config.php:

<?php

DEFINE ('DBHOST', 'localhost');
DEFINE ('DBUSER', 'REMOVED');
DEFINE ('DBPSW', 'REMOVED');
DEFINE ('DBNAME', 'REMOVED');

class DB {
public $db;
private static $instance;

public function __constructor(){
$config ['db'] = array(
'host' => DBHOST,
'username' => DBUSER,
'password' => DBPSW,
'dbname' => DBNAME,
);

$this->db = new PDO('mysql:host =' . $config['db']['host'] . ';dbname=' . $config['db']['dbname'],$config['db']['username'],$config['db']['password']) ;
}

public static function getInstance()
{
if (!isset(self::$instance))
{
$object = __CLASS__;
self::$instance = new $object;
}
return self::$instance;
}

public function GetArticles ($search){
$sql = "SELECT `FirstColumn`, `SrcColumn`, `article` FROM `test_table` WHERE `FirstColumn` = 23";

//$dbs = new DB();
$dbs = DB::getInstance();
$query = $dbs->db->prepare($sql);
//$query->bindValue(':search', $search, PDO::PARAM_INT);
$query->execute();

while ($row = $query->fetch(PDO::FETCH_OBJ)) {
// = $row['article'],'</br>';
$return = $row['article'];
}
return $return;
}
}
?>

这个文件是我的测试文件,它并不重要,只是一个测试场。调用了test.php:

<?php
require_once('app_core/config.php');
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Untitled Document</title>

<link rel="stylesheet" href="/style/style.css" type="text/css" media="screen" />
</head>

<body>
<?php
$db = new DB();
//echo $db->db;
//echo $db->GetTestDB();
//$test = $db->TestThis();
//print_r($test);
echo $db->GetArticles('23');
?>
</body>
</html>

如果可能的话,我还有另外两个问题:第一个问题是安全问题——这是否是一种好的做法?另一个问题是如何隐藏包含此密码数据的文件,以便我可以使用它们但没有人可以读取它们?

最佳答案

好的,你在这里有很多事情要做,所以我将尝试一次解决一个问题,以使这个类以面向对象的方式正确运行(而不是不完全-相关方法)。

首先,你的构造函数:

//  Make these private, will find out why in a moment...
private $db;
// __construct, not __constructor!!
private function __construct() {
// This whole array doesn't serve any purpose because the constants
// are defined and available in all scopes
// while this array is local to the __construct().
// Just get rid of it and use the
// constants directly in the PDO connection
//$config ['db'] = array(
// 'host' => DBHOST,
// 'username' => DBUSER,
// 'password' => DBPSW,
// 'dbname' => DBNAME,
//);

// Use some error checking when establishing your connection
try {
// Some extra bad whitespace removed around =
$this->db = new PDO('mysql:host=' . DBHOST . ';dbname=' . DBNAME, DBUSER, DBPSW);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
}

接下来是您的单例访问器 getInstance()。

// No code changes necessary....
public static function getInstance()
{
if (!isset(self::$instance))
{
$object = __CLASS__;
self::$instance = new $object;
}
return self::$instance;
}

由于您已经定义了一个方法来将类作为单例访问,因此 $db 属性和 __construct() 被设置为 private .您永远不会调用 $DB_class-instance = new DB() 来实例化它,或调用 $DB_class_instance->db 来直接访问连接。相反,您将调用 DB::getInstance() 来访问单例实例,并调用 GetArticles() 等方法来执行查询。

现在进入您的查询方法:

public function GetArticles ($search){
// Ok a SQL string, no problem...
$sql = "SELECT `FirstColumn`, `SrcColumn`, `article` FROM `test_table` WHERE `FirstColumn` = :search";

// There's no need for this. You already defined $db as
// a class property, so you should be using $this->db
// $dbs = DB::getInstance();

$query = $this->db->prepare($sql);
// bind the $search input parameter...
$query->bindParam(':search', $search);

// Test for success
if ($query->execute()) {

$row = $query->fetch(PDO::FETCH_OBJ) {
// I suppose you know what you want here. If you're only expecting
// one article, there's no real need for the while loop.
// You can just fetch() once.
$return = $row->article;

// OR.....

// However, if you are expecting *multiple* rows, you should be accumulating them
// into an array like this:
$return = array();
while ($row = $query->fetch(PDO::FETCH_OBJ)) {
// Append to an array
$return[] = $row->article;
// OR to get multiple columns returned as an object...
$return[] = $row;
}
return $return;
}
else {
// Query failed, return false or something
return FALSE;
}
}

最后是你的 Controller 代码:

// The constructor is private, so you can't do this
// $db = new DB();
// Instead you need to use getInstance()
$db = DB::getInstance();
// Returns an array, so print_r()
print_r($db->GetArticles('23'));

由于我们将类的 $db 属性设为 private,因此无法在类外访问它。因此,您需要为计划运行的任何其他查询定义类似于 GetArticles() 的查询方法。如果您认为有时需要构建不是类方法的临时查询,那么您可以将其更改为

public $db

然后,您可以像下面这样在类之外执行操作,而不必构建类方法来执行它。但是,您确实仍然需要调用 getInstance()

$dbs = DB::getInstance();
// Run a query via the PDO connection $dbs->db
$result = $dbs->db->query('SELECT * FROM sometable');

小样式问题:

这实际上不会造成问题,因为标识符不区分大小写,但在风格上它很奇怪。 define() 是一个函数调用,通常使用小写:

define('DBHOST', 'localhost');
define('DBUSER', 'REMOVED');
define('DBPSW', 'REMOVED');
define('DBNAME', 'REMOVED');

关于您的文件安全

只要您的网络服务器配置正确,其他人就无法读取这些文件。如果 Web 服务器将 .php 文件发送到 PHP 解释器而不是将其内容转储到浏览器,则这些文件是安全的。如果您在共享主机上并且该主机没有将您的文件与其他租户正确隔离,那是他们的问题,唯一好的解决方案是获得更好的主机。

然而,明智的做法是将敏感文件存储在网络服务器的文档根目录之上。这样,即使配置错误的 Web 服务器也不会意外地将其内容转储到客户端。 PHP 只能通过 include 访问它们。

关于php - 我正在尝试结合 PDO 和 OOP,但无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13665421/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com