gpt4 book ai didi

How to use PDO connection in other classes?(如何在其他课程中使用PDO连接?)

转载 作者:bug小助手 更新时间:2023-10-24 22:42:39 26 4
gpt4 key购买 nike



I think I've a problem in understanding how OOP works. I already changed the code that it works, but it isn't the propper way I think. Following scenario (No, I'm not creating a userlogin by myself, its really just for local dev. to understand OOP better):

我想我在理解OOP是如何工作的方面有问题。我已经改变了它的工作代码,但它不是我认为的正确方式。下面的场景(不,我不是自己创建一个用户登录,它真的只是为本地开发。更好地理解OOP):



I've a database.php file:

我有一个数据库.php文件:



class Database {

/* Properties */
private $conn;
private $dsn = 'mysql:dbname=test;host=127.0.0.1';
private $user = 'root';
private $password = '';

/* Creates database connection */
public function __construct() {
try {
$this->conn = new PDO($this->dsn, $this->user, $this->password);
} catch (PDOException $e) {
print "Error!: " . $e->getMessage() . "";
die();
}
return $this->conn;
}
}


So in this class I'm creating a database connection and I return the connection (object?)

在这个类中,我创建了一个数据库连接,并返回连接(对象?)



Then I have a second class, the famous User class (actually I'm not using autoload, but I know about it):

然后我还有第二个类,著名的User类(实际上我没有使用autoload,但我知道它):



include "database.php";

class User {
/* Properties */
private $conn;

/* Get database access */
public function __construct() {
$this->conn = new Database();
}

/* Login a user */
public function login() {
$stmt = $this->conn->prepare("SELECT username, usermail FROM user");
if($stmt->execute()) {
while($rows = $stmt->fetch()) {
$fetch[] = $rows;
}
return $fetch;
}
else {
return false;
}
}
}


So thatare my two classes. Nothing big, as you see. Now, don't get confued about the function name login - Actually I just try to select some usernames and usermails from database and displaying them. I try to achieve this by:

这就是我的两节课。如你所见,没什么大不了的。现在,不要对函数名LOGIN感到困惑--实际上,我只是尝试从数据库中选择一些用户名和用户邮件并显示它们。我试图通过以下方式来实现这一点:



$user = new User();
$list = $user->login();

foreach($list as $test) {
echo $test["username"];
}


And here comes the problem. When I execute this code, I get the following error message:

现在问题来了。当我执行此代码时,我收到以下错误消息:




Uncaught Error: Call to undefined method Database::prepare()




And I'm not sure that I really understand what causes this error.

我不确定我是否真的理解是什么导致了这个错误。



The code works well when I change the following things:

当我更改以下内容时,代码运行良好:



Change $conn in database.php to public instead of private (I think thats bad...? But when its private, I can only execute querys inside of the Database class, I'm right? So should I put all these querys in the Database class? I think that's bad, because in a big project it will get become really big..)

将datase.php中的$conn更改为PUBLIC而不是PRIVATE(我认为这很糟糕...?但是当它是私有的时,我只能在数据库类中执行查询,对吗?那么,我应该将所有这些查询放在数据库类中吗?我认为这很糟糕,因为在一个大项目中,它会变得非常大。)



And the second change I've to do is:
Change $this->conn->prepare to $this->conn->conn->prepare in the user.php file. And here I've really no Idea why.

我要做的第二个更改是:在user.php文件中将$This->Conn->Prepare更改为$This->Conn->Conn->Prepare。在这里,我真的不知道为什么。



I mean, in the constructor of the user.php I've a $this->conn = new Database() and since new Database will return me the connection object from DB class, I really don't know why there have to be a second conn->

我的意思是,在user.php的构造函数中,我有一个$This->conn=new Database(),既然new Database将从DB类返回给我Connection对象,我真的不知道为什么一定要有第二个conn->


更多回答

The constructor shouldn't return anything : stackoverflow.com/questions/6849572/… - to have access to that method your Database class would need to extend PDO

构造函数不应该返回任何内容:Stackoverflow.com/Questions/6849572/…-要访问该方法,您的数据库类需要扩展PDO

Your error is $this->conn->prepare( you're trying to call the prepare function on your Database class but there is no prepare function. you could make the $conn of Database public which would result in $this->conn->conn->prepare. the return value of your Database __construct() is returning a Database object not the connection even if you retrun $this->conn

您的错误是$This->conn->Prepare(您试图在数据库类上调用Prepare函数,但没有Prepare函数。您可以将数据库的$conn设置为公共的,这将导致$This->conn->conn->preparate。即使您返回$This->conn,数据库__构造()的返回值也是返回一个数据库对象而不是连接

that's right, because in your Database class conn is PDO instance and has such capabilities

没错,因为在您的数据库类中,conn是PDO实例,并且具有这样的功能

@Twinfriends yea I'm sure.. If you put the Login into the Database class, $this->conn is the PDO object of Database, not the Database object itself

@双胞胎朋友是的,我肯定..如果将Login放入数据库类,则$This->conn是数据库的PDO对象,而不是数据库对象本身

Inside the database class you'd be calling $this->conn - in which case that is a PDO instance so the method exists and you're good. When you instantiate Database however from outside, you're creating a new Database object which only has the methods you define - unless you extend another class.

在数据库类内部,您将调用$This->conn--在这种情况下,这是一个PDO实例,因此该方法存在,您就很好了。然而,当您从外部实例化数据库时,您正在创建一个新的数据库对象,该对象只具有您定义的方法--除非您扩展另一个类。

优秀答案推荐


  • Do not create classes such as your Database class as it's rather useless. It would make sense to create a database wrapper if it adds some extra functionality to PDO. But given its current code, better to use vanilla PDO instead.

  • Create a single $db instance from either vanilla PDO or your database class.

  • Pass it as a constructor parameter into every class that needs a database connection


database.php:

数据库.php:


<?php
$host = '127.0.0.1';
$db = 'test';
$user = 'root';
$pass = '';
$charset = 'utf8';

$dsn = "mysql:host=$host;dbname=$db;charset=$charset";
$opt = [
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
\PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_ASSOC,
\PDO::ATTR_EMULATE_PREPARES => false,
];
$pdo = new \PDO($dsn, $user, $pass, $opt);

user.php

User.php


<?php
class User {
/* Properties */
private $conn;

/* Get database access */
public function __construct(\PDO $pdo) {
$this->conn = $pdo;
}

/* List all users */
public function getUsers() {
return $this->conn->query("SELECT username, usermail FROM user")->fetchAll();
}
}

app.php

App.php


include 'database.php';
$user = new User($pdo);
$list = $user->getUsers();

foreach($list as $test) {
echo $test["username"],"\n";
}

output:

输出:


username_foo
username_bar
username_baz

Check out my (The only proper) PDO tutorial for more PDO details.

查看我的(唯一合适的)PDO教程,了解更多的PDO细节。


更多回答

While this is a nice way to solve it, I personally don't like to have the connection in my models. Might aswell to keep it "clean" extend a Base model which contains the connection methods.

虽然这是一个很好的解决方法,但我个人不喜欢在我的模型中有这种联系。也可以保持它“干净”,扩展一个包含连接方法的基本模型。

@NiekvanderMaaden if you extend a Base model, then you have the connection in the offspring class as well.

@NiekvanderMaden如果扩展基本模型,则在子代类中也有连接。

That's right but what i meant is your Child model will be "clean" in the sense of readability that it doesn't clog up with extra methods and variables. One way or another the only true way you wont have them in your model is using a static database class, but yeah not the proper way to do it.

没错,但我的意思是,您的子模型在可读性方面将是“干净的”,不会被额外的方法和变量堵塞。无论如何,在您的模型中不使用它们的唯一真正方法是使用静态数据库类,但确实不是正确的方法。

@NiekvanderMaaden if you want your classes to be clean look for the Data Mapper pattern.

@NiekvanderMaden如果您希望您的类是干净的,请寻找数据映射器模式。

If I have 3 objects that share the same db connection in the same iteration is a bad thing?

如果我有3个对象在同一迭代中共享相同的数据库连接,这是一件坏事吗?

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