有时我会看到关于连接数据库的问题

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

Here's how I'm doing it:

首先,这里是我的文件 struct (stripped down):

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');

I know there's a better, or more correct, way to include classes, but can't remember what it was. Haven't gotten the time to look into it yet, but I think it was something with 100. something like that...

configure.php

connect.php
我已经把连接放到了一个类上,这样其他类就可以extends这个了.

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();
//

Here I do believe there's room for massive improvement since I recently started learning OOP, and using PDO instead of mysql.
So I've just followed a couple of beginners tutorials and tried out different stuff...

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)

在我的sqlQuery-class(extends-connect_pdo-class)中,我有一个名为getAreaName的公共函数,用于处理对数据库的请求

Works like a charm
所以我基本上就是这么做的.
此外,每当我需要从数据库中从类以外的位置获取某些内容时,我只需执行类似的操作:

$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内的一个变量中,我只需要引用它,就可以开始了.它起作用了.我得到了我预期的结果...

但不管怎样,如果你们能告诉我我是不是走得太远了,我会非常感激的.我应该做什么,我可以或应该改变的地方,等等…

我很想学习...

推荐答案

目标

在我看来,你的目标有两个:

  • for each 数据库创建并维护单个/可重用的连接
  • 确保连接已正确设置

解决方案

我建议使用匿名函数和工厂模式来处理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 );
    }

}

这种方式将使您拥有一个集中的 struct ,确保仅在需要时创建连接.它还将使单元测试和维护过程更加容易.

本例中的提供程序将在 bootstrap 阶段的某个位置找到.这种方法还会给出一个明确的位置来定义您用来连接到数据库的配置.

请记住,这是一张extremely simplified example美元的钞票.您还可以从观看以下两个视频中获益:

另外,我强烈推荐阅读a proper tutorial篇关于PDO用法的文章(网上有一些糟糕的教程日志(log)).

Php相关问答推荐

PHPHPML用现有的HTML文件上的文本替换 node 值

如果WooCommerce产品具有特定的产品标签,则将元盒添加到管理WooCommerce产品

SQLSTATE [42S02]:找不到基表或视图:1146 Table eshop. sessions不存在'''

管理员订单列表中的自定义列与WooCommerce 8.6.1一起消失

LaravelEloquent 的地方条件父/子与第三模型多对多

使用PHP阅读XML提要

具有重叠捕获组的PHP正则表达式

无法在WooCommerce中发送客户笔记邮箱通知

中继器内置中继器的ACF WordPress组

为什么只有最后一次点击的点赞/心形会按预期改变 colored颜色 ,而其他的保持正常 colored颜色 ?

针对给定产品类别的WooCommerce计数审核

根据发货类别在WooCommerce产品页面中显示快捷代码

如何将LARAVEL模块路径和项目路径合并,因为当我使用模块路径时,它们会覆盖项目路径

限制联系人页面仅允许在WooCommerce中登录的用户

打折时更改 Woocommerce 产品名称

调用未定义的方法 mysqli::execute_query()

使用 Composer 找不到 Google APIClient 类

Symfony:指定 data_class 时,提交的表单获取初始化前不得访问

在 GA4 Data API V1 Beta 中使用 inListFilter 过滤器时出错

使用 GROUP_CONCAT 规范化/转置来自查询的数据