自定义mysqli准备功能

问题描述 投票:2回答:1

我现在正在做自己的第一个数据库类,目前正在做prepare函数。

这个函数的作用是接收一个SQL查询,然后是一个包含语句变量的数组。我在将参数绑定到语句上时遇到了问题。

这是函数现在的样子

public function prepare($query, $var) {
    $types = '';
    foreach($var as $a) {
        $type = gettype($a);
        switch($type) {
            case 'integer':
                $types .= 'i';
                break;

            case 'string':
                $types .= 's';
                break;

            default:
                exit('Invalid type: ' . $a .' ' . $type . '(' . count($a) . ')');
                break;
        }
    }

    $stmt = self::$connection->prepare($query);
    $stmt->bind_param($types, $var); // How do I do here??
    $stmt->execute();
    $result = $stmt->get_result();
    while($row = $result->fetch_assoc()) {
        print_r($row);
    }
}

一切都能按照我的要求工作(我知道这个功能可以做一些打磨,但它做了它需要做的事情)。我已经注释了我不知道该怎么做的那一行。$var是一个数组,如果我没有记错的话,变量需要用逗号分开传递。这就是我不知道该怎么做的地方。

php class mysqli prepared-statement bindparam
1个回答
2
投票

自己的数据库类,这个想法非常好。这里很少有人分享它,由于某些原因,他们更喜欢在代码中使用原始的api调用。所以,你又进了一大步。然而,这里有一些反对意见。

  1. 不要使用mysqli 如果你要使用本地准备好的语句,你的第一个自己的数据库类。使用PDO来代替。它将为你省去一大堆麻烦。
  2. 尽管这个函数对你来说工作得很好,但它并没有什么意义。
    • switch($type) 代码块是无用的。Mysql可以将每个标量值理解为一个字符串--所以你可以将每个值绑定为 s 没有问题。
    • 大多数来自客户端的整数都是字符串类型。
    • 也有一些合法的类型,比如 floatNULL 或可以返回一个字符串的对象。所以,自动化在这里是行不通的。如果你想区分不同的类型,你必须实现 类型提示占位符 而不是。
    • 绝不 使用 exit 在你的脚本中。throw new Exception('put here your error message') 代替。
  3. 这实际上不是一个准备函数,因为它也会执行。所以,给它一个更通用的名字

但现在你的问题是,这是使用mysqli的直接后果。当处理准备好的语句时,它是一个噩梦。不仅是绑定,而且检索你的数据也是如此(因为 get_result() 并非到处都能用,在本地创建你的应用程序后,你会发现它在共享主机上无法工作)。) 你可以让自己有一个想法,看 这堆代码 就是为了这个目的--绑定动态数量的变量。

所以,尽可能的远离mysqli吧。在PDO中,你的函数会像这样简单。

public function query($query, $var=array())
{
    $stmt = self::$connection->prepare($query);
    $stmt->execute($var);
    return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
// and then used
$data = $db->("SELECT 1");
print_r($data);

您可以 看我的课 来获得一些想法。欢迎提出任何关于数据库类的问题--这是伟大的事情,我很高兴你能这样做。

要回答评论中的问题。

要让你知道,你不是网站的唯一用户。还有一些无辜的访问者。与你不同,他们不需要任何错误信息,他们会被一些奇怪的行为和缺乏熟悉的控件吓到。

带错误信息的exit()做了很多邪恶的事情。

  • 抛出一个错误信息,向潜在的攻击者透露一些系统内部信息。
  • 用奇怪的信息吓唬无辜的用户。"这是什么东西?谁是无效的?是我的错还是什么?或者可能是病毒?最好根本离开这个网站"--他们认为。
  • 在中间杀死脚本,所以它可能会导致撕裂的设计(或根本没有设计)显示。
  • 而抛出的异常可以被捕获并优雅地处理。

当连接到PDO时,不需要在这里抛出任何东西,因为异常 已抛出 由PDO。所以,摆脱 try ... catch 并只留下一行。

self::$connection = new PDO($dsn, $user, $pass); 

然后创建一个自定义的 异常处理程序 在2种模式下工作。

  • 在开发服务器上,让它在屏幕上抛出信息。
  • 在实时服务器上,让它 原木 在向用户显示通用错误页面的同时,也显示出了错误。

只有当你不想让整个脚本死掉的时候,才会使用try ... catch --即处理。可收回 只是问题。

对了,PDO默认不会在连接时抛出异常。你必须手动设置它。

$opt = array( PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION );
self::$connection = new PDO($dsn, $user, $pass, $opt); 
© www.soinside.com 2019 - 2024. All rights reserved.