-1

私は PDO クラスラッパーを持っています:

class DB {

        private $dbh;
        private $stmt;

        public function __construct($user, $pass, $dbname) {

            $dsn = 'mysql:host=localhost;dbname=' . $dbname;

            $options = array(
                PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',
                PDO::ATTR_PERSISTENT => true
            );

            try {
                $this->dbh = new PDO($dsn, $user, $pass, $options);
            }
            catch (PDOException $e) {
                echo $e->getMessage();
                die();
            }
        }

        public function query($query) {
            $this->stmt = $this->dbh->prepare($query);
            return $this;
        }

        public function bind($pos, $value, $type = null) {

            if( is_null($type) ) {
                switch( true ) {
                    case is_int($value):
                        $type = PDO::PARAM_INT;
                        break;
                    case is_bool($value):
                        $type = PDO::PARAM_BOOL;
                        break;
                    case is_null($value):
                        $type = PDO::PARAM_NULL;
                        break;
                    default:
                        $type = PDO::PARAM_STR;
                }
            }

             $this->stmt->bindValue($pos, $value, $type);
             return $this;
        }

        public function execute() {
            $this->stmt->execute();
        }

        public function resultset() {
            $this->execute();
            return $this->stmt->fetchAll(PDO::FETCH_ASSOC);

        }

        public function single() {
            $this->execute();
            return $this->stmt->fetch();
        }
    }

質問 1: 以下のリクエストがあります。

$ids_set = implode(",", $ids); // return 2,4
$sql = 'SELECT `id`, `qty` FROM `products` WHERE `id` IN (:products_ids) ORDER BY `id`';
$arr = $this->db->query($sql)->bind(":products_ids", $ids_set)->resultset();

ただし、このリクエストは配列内の 1 つの要素のみを返します。

Array
(
    [0] => Array
        (
            [id] => 2
            [qty] => 1
        )

)

ただし、2 つの要素を返す必要があります。クラスを変更する理由と方法

質問2

私のクラスバインド関数は、db インジェクションに対して安全ですか?

質問 3

私は動的クエリを持っています:

$sql    = 'SELECT COUNT(*) FROM `orders` WHERE 1=1';

if ($filter["order"] != 0) {
    $sql .= ' AND `gatewayid` = '.intval($filter["order"]).'';
}

$count  = $this->db->query($sql)->single()[0];

この場合、バインド機能を使用するにはどうすればよいですか? ありがとう!

4

1 に答える 1

2

率直に言って、あなたのクラスは今のところ役に立たないと思います。生の PDO でもすべて同じことができます。

$arr = $this->db->prepare($sql)->execute([":product_id" => $id])->fetchAll();

複雑なデータ型のバインドについて言えば、唯一の適切な解決策、追加のプレースホルダー型を考案することです。そして、そのようなプレースホルダーをサポートすることが、このクラスの本当の目的です。

質問1

この回答で説明されているように、プレースホルダーを使用して動的に文字列を作成する必要があります

質問2

はい

質問 3

クラスはこれに対して非常に信頼できないため、クエリを動的に作成するだけでなく、 Shown を PDOにバインドするデータを含む配列を作成する必要があります。

$sql  = 'SELECT COUNT(*) FROM `orders` WHERE 1=1';
$data = [];
if ($filter["order"] != 0) {
    $sql .= ' AND `gatewayid` = :getewayid';
    $data[":getewayid"] = $filter["order"];
}
$count = $this->db->prepare($sql)->execute($data)->fetchColumn();
于 2013-09-04T06:01:44.787 に答える