php 是否有准备发言的简写?

1cosmwyk  于 2023-04-28  发布在  PHP
关注(0)|答案(2)|浏览(95)

最近我开始使用预处理语句。然而,我觉得我的代码变得有点太混乱了,因为所有的临时变量和仅仅为了进行一个查询所需的额外行。
到目前为止,我的代码看起来像下面这样:

$stmt = $conn->prepare("SELECT * FROM locations WHERE location_id = ?");
$stmt->bind_param("i", $_GET['location_id']);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($location_id, $owner);
//all the other $stmt->fetch() related code here...

是否有任何速记方法来做同样的事情?

8cdiaqws

8cdiaqws1#

使用预处理语句是在PHP中执行SQL语句的正确方法,我不得不真诚地赞扬您使用了正确的方法。
但是,正如您所注意到的,API不适合在应用程序代码中使用。大多数现代PHP应用程序都使用PDO,即使如此,它也与某种抽象层一起使用。这些API并不是为了单独使用而设计的。
如果你必须使用mysqli,那么你可以自己编写一个非常简单的 Package 类。 Package 器至少应该有两样东西。使用默认参数打开连接的一种简单直观的方法和用于执行预处理语句的一行程序方法。
看看我的例子:

<?php

class DBClass extends mysqli {
    public function __construct($host, $user = null, $pass = null, $db = null, $port = null, $socket = null) {
        // enable error reporting
        mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
        // instantiate mysqli
        parent::__construct($host, $user, $pass, $db, $port, $socket);
        // set the correct charset
        $this->set_charset('utf8mb4');
    }

    /**
     * Executes prepared statement
     *
     * @param string $sql SQL query with placeholders e.g. SELECT * FROM users WHERE Id=?
     * @param array $params An array of parameters to be bound
     * @return array|null
     */
    public function safeQuery(string $sql, array $params = []): ?array {
        // prepare/bind/execute
        $stmt = $this->prepare($sql);
        if ($params) {
            $stmt->bind_param(str_repeat("s", count($params)), ...$params);
        }
        $stmt->execute();
        // If the query produces results then fetch them into multidimensional array
        if ($result = $stmt->get_result()) {
            return $result->fetch_all(MYSQLI_BOTH);
        }
        // return nothing if the query was successfully executed and it didn't produce results
        return null;
    }

    public function row(string $sql, array $params = []): ?array {
        return $this->safeQuery($sql, $params)[0] ?? [];
    }

    public function single(string $sql, array $params = []) {
        $data = $this->row($sql, $params);
        return array_shift($data);
    }
}

这是一个简单的类,它扩展了mysqli并添加了3个新方法:safeQueryrowsingle。您可以使用它们执行静态查询或预准备语句,并分别检索多行、单行或单个值。
下面是如何使用这样的类而不是mysqli:

$db = new DBClass('localhost', 'user', 'pass', 'dbname');

// select multiple rows
$id = 2;
foreach ($db->safeQuery('SELECT title FROM movie WHERE directorId=?', [$id]) as $row) {
    echo $row['title']."\n";
}

// select a single row
$movie = $db->row('SELECT id FROM movie WHERE title=?', ['Titanic']);
if ($movie) {
    echo $movie['id']."\n";
}

// select a single column from a single row
echo $db->single('SELECT title FROM movie WHERE id=1');

值得指出的是,store_result()bind_result()方法并不是非常有用,使用它们可能会导致脏代码。如果您使用一个抽象类,即使像这里演示的那样简单,您也可以保存绑定变量并逐个获取它们的麻烦。

nmpmafwu

nmpmafwu2#

截至2022年5月,PHP8.2允许您享受更简洁的预处理语句执行。
对于您的示例代码段,查询特定位置id并返回一个平面关联数组可以写成一行。
代码:(PHPize.online Demo

var_export(
     $mysqli->execute_query("SELECT * FROM locations WHERE location_id = ?", [2])->fetch_assoc()
);

输出:

array (
  'location_id' => 2,
  'owner' => 'Potato Gun',
)

一些参考资料:

相关问题