当前位置: 首页 > 面试题库 >

如何正确设置PDO连接

羿宏硕
2023-03-14
问题内容

我不时看到有关连接数据库的问题。
大多数答案不是我做的方式,否则我可能只是无法正确获得答案。无论如何; 我从未考虑过,因为我的工作方式对我有效。

但是这里有个疯狂的想法;也许我做错了所有,如果是这样的话;我真的很想知道如何使用PHP和PDO正确连接到MySQL数据库并使其易于访问。

这是我的做法:

首先,这是我的文件结构 (向下精简)

public_html/

* index.php

* initialize/  
  -- load.initialize.php  
  -- configure.php  
  -- sessions.php

index.php
在最顶部,我有require('initialize/load.initialize.php');

load.initialize.php

#   site configurations
    require('configure.php');
#   connect to database
    require('root/somewhere/connect.php');  //  this file is placed outside of public_html for better security.
#   include classes
    foreach (glob('assets/classes/*.class.php') as $class_filename){
        include($class_filename);
    }
#   include functions
    foreach (glob('assets/functions/*.func.php') as $func_filename){
        include($func_filename);
    }
#   handle sessions
    require('sessions.php');

我知道有一种更好或更正确的方法来包含类,但是不记得它是什么了。 还没来得及研究它,但是我认为这是与之有关的autoload。像那样的东西

configure.php
在这里,我基本上只是重写一些 php.ini -properties并对该站点进行其他一些全局配置

connect.php
我已经将连接放到一个类上,以便其他类可以 扩展 此类…

class connect_pdo
{
    protected $dbh;

    public function __construct()
    {
        try {
            $db_host = '  ';  //  hostname
            $db_name = '  ';  //  databasename
            $db_user = '  ';  //  username
            $user_pw = '  ';  //  password

            $con = new PDO('mysql:host='.$db_host.'; dbname='.$db_name, $db_user, $user_pw);  
            $con->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
            $con->exec("SET CHARACTER SET utf8");  //  return all sql requests as UTF-8  
        }
        catch (PDOException $err) {  
            echo "harmless error message if the connection fails";
            $err->getMessage() . "<br/>";
            file_put_contents('PDOErrors.txt',$err, FILE_APPEND);  // write some details to an error-log outside public_html  
            die();  //  terminate connection
        }
    }

    public function dbh()
    {
        return $this->dbh;
    }
}
#   put database handler into a var for easier access
    $con = new connect_pdo();
    $con = $con->dbh();
//

我确实在这里相信,自从我最近开始学习OOP并使用PDO代替mysql以来,还有很大的改进空间。
因此,我只是遵循了一些初学者教程,并尝试了不同的方法…

sessions.php
除了处理常规会话外,我还将一些类初始化为如下所示的会话:

if (!isset($_SESSION['sqlQuery'])){
    session_start();
    $_SESSION['sqlQuery'] = new sqlQuery();
}

这样,该课程可在各处使用。这可能不是一个好习惯(?)…
总之,这就是我可以从任何地方做的事情:

echo $_SESSION['sqlQuery']->getAreaName('county',9);  // outputs: Aust-Agder (the county name with that id in the database)

在my sqlQuery- class (即extendsmy connect_pdo- class)内部
,有一个名为的公共函数getAreaName来处理对数据库的请求。
我觉得很整洁。

就像魅力一样工作,
所以基本上这就是我的做法。
此外,每当我需要从不在类内的数据库中获取某些内容时,我都会做类似的事情:

$id = 123;

$sql = 'SELECT whatever FROM MyTable WHERE id = :id';
$qry = $con->prepare($sql);
$qry -> bindParam(':id', $id, PDO::PARAM_INT);
$qry -> execute();
$get = $qry->fetch(PDO::FETCH_ASSOC);

由于我将连接放入 connect_pdo.php中 的变量中,因此我只用引用它就可以了。有用。我得到了预期的结果…

但是不管怎样;如果你们能告诉我我是否要离开这里,我将不胜感激。我应该做的是,我应该或应该改变以改进的领域等。

我渴望学习…


问题答案:

目标

正如我所看到的,在这种情况下,您的目标是双重的:

  • 为每个数据库创建并维护一个/可重复使用的连接
  • 确保已正确建立连接

我建议同时使用匿名函数和工厂模式来处理PDO连接。它的用法如下所示:

$provider = function()
{
    $instance = new PDO('mysql:......;charset=utf8', 'username', 'password');
    $instance->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $instance->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
    return $instance;
};

$factory = new StructureFactory( $provider );

然后在其他文件中或在同一文件中的较低文件中:

$something = $factory->create('Something');
$foobar = $factory->create('Foobar');

工厂本身应如下所示:

class StructureFactory
{
    protected $provider = null;
    protected $connection = null;

    public function __construct( callable $provider )
    {
        $this->provider = $provider;
    }

    public function create( $name)
    {
        if ( $this->connection === null )
        {
            $this->connection = call_user_func( $this->provider );
        }
        return new $name( $this->connection );
    }

}

这种方式将使您拥有集中式的结构,从而确保仅在需要时才创建连接。这也将使单元测试和维护过程变得更加容易。

在这种情况下,提供程序将在引导阶段找到。这种方法还将提供一个清晰的位置,用于定义配置,以用于连接到数据库。

请记住,这是一个 极其简化的示例 。您还可以从观看以下两个视频中受益:

  • 全球州和单身人士
  • 不要找东西!

另外,我强烈建议您阅读有关PDO使用的适当教程(在线上有不良教程的日志)。



 类似资料:
  • 问题内容: 我在设置布局时遇到一些问题。(不要介意按钮的大小,我只想正确地了解布局)。 Here’s my code: 谁能帮助我了解布局的工作原理? 我一直在观看很多视频,并尝试过不同的布局,但仍然无法正确完成。告诉我是否使用了正确的布局,或者是否应该更改布局 。 问题答案: 如 该答案中所建议的那样,可以为左部分提供所需的全部控制。如果您愿意为简单起见而牺牲一些控制权,则可以在a里面放两个面板

  • 问题内容: 我正在尝试运行Java程序,但是它采用默认的GMT时区而不是OS定义的时区。我的JDK版本是1.5,操作系统是Windows Server Enterprise(2007) Windows指定了中央时区,但是当我运行以下程序时,它给了我GMT时间。 这是输出 请注意,我不想从应用程序中设置时区。我希望JVM使用的时区应该是操作系统中指定的时区。(对于具有JDK 1.4版和Microso

  • 问题内容: 我有一个关于mysql时区的怪异问题。 在我的网站配置文件中,我这一行设置了时区: 有趣的是,如果我在此之后添加另一行,例如: 执行该代码后,时间将正确显示。 但是,在其他一些查询中,我在表中插入行,这些表的列名为date,默认为CURRENT_TIMESTAMP。 这样插入行: (“会话”表的列默认为CURRENT_TIMESTAMP) 但是插入到数据库中的值仍指向服务器的时区:((

  • 问题内容: 遵循OnlyOffice帮助中心的说明,将创建由浏览器声明为无效的安全证书,因为它是自签名的。 目的是在适用于NextCloud的Docker上使用OnlyOffice的服务器,该服务器已在另一台服务器上正常运行。 当前,已在说明建议的目录中创建证书: 我已经按照所有给定的步骤进行操作,但是它不起作用。 有没有办法使用LetsEncrypt代替自签名证书? 我不是IT管理人员,我是一个

  • 问题内容: 我正在使用PDO从MySQL服务器获取数据。我注意到的是:如果MySQL服务器不可用,则此代码返回异常 实际上 需要(相对)长的时间: 如果使用MySQL,则发生异常(SQLSTATE [HY000] [2003]无法在…上连接到MySQL服务器)仅需2分钟以上,而在PostgreSQL上则需要30秒(SQLSTATE [08006] [7]超时已过期) )。 我尝试使用PDO ::

  • 我目前正在做一个游戏,你必须避免小行星。我开始使用任意单位。 此外,我正在使用一个: 在游戏屏幕中,小行星看起来变形了: