PDOでUPDATEの使い方【PHP】

PHPのPDOで行の更新を行うUPDATE文の書き方をまとめました。

例として、下記のテーブルをサンプルコードで使用します。

table名:yasai_item
id name
(UNIQUE)
price
1 にんじん 50
2 トマト 100
3 きゅうり 80

PDOでのUPDATE文の書き方

UPDATE句を含め、PDOでSQLを実行する方法は大きく分けて2つあります。

  • query
  • prepare→execute

queryとprepareを使用したUPDATE文の実行方法をそれぞれで解説していきます。

query

queryは、ソースコードで書くSQLが既に決まっている場合に使用します。

条件指定の更新(WHERE句)

$sql = "UPDATE yasai_item
        SET
        price = 30
        WHERE
        name = 'にんじん'";
$sth = $pdo -> query($sql);

こちらは、nameが「にんじん」となっている行のpriceを「30」に変更する値下げのクエリです。

実行して、「にんじん」の行のpriceが「30」となっていればクエリ成功です。

id name price
1 にんじん 30
2 トマト 100
3 きゅうり 80

全行の更新

UPDATE文は、WHERE句で条件を指定しない限り、すべてのカラムに変更処理を加えます。

$sql = "UPDATE yasai_item
        SET
        price = 30";
$sth = $pdo -> query($sql);
id name price
1 にんじん 30
2 トマト 30
3 きゅうり 30

これはこれで使う場面はあるのですが、ほとんどの場合は条件指定をした上で更新することが多いです。

条件指定で更新をしたい場合は、WHEREの付け忘れには注意しましょう。
クエリを書くときは、SETではなくWHEREから書き始めたほうが良いくらいです。

変数にUPDATE文に組み込む場合の注意点

UPDATE文で変数を使用したい場合は、文字列連結でも対応できます。

$item = 'にんじん';
$price = 30;
$sql = "UPDATE yasai_item
        SET
        price = ".$price."
        WHERE
        name = '".$item."'";
$sth = $pdo -> query($sql);

ただし、この場合に文字列連結で組み込む変数は、外部のユーザーから取得した値を何の検証もせずに組み込むと、SQLインジェクション攻撃を受ける可能性があります。

//やってはいけない例 $_GETなどでユーザーから入力された値を文字列連結で組み込む
$item = $_GET['item'];
$price = $_GET['price'];
$sql = "UPDATE yasai_item
        SET
        price = ".$price."
        WHERE
        name = '".$item."'";
$sth = $pdo -> query($sql);

参考 PHPでSQLインジェクション攻撃の対策方法【PDO】

ユーザーの入力内容に応じて更新を行う場合は、prepareを使用してください。

prepare→execute

prepareは、SQL文を一度実行準備を行い、その後に変数を当てはめて実行できる機能です。

参考 PDOでprepareの使い方【PHP】

  • prepare()でクエリの実行準備
  • bindValue()でクエリ内の値を設定
  • execute()で更新の実行

という流れでUPDATEを行います。

実行準備の段階でUPDATE文と認識するため、SQLインジェクション攻撃のようにクエリを改ざんされることがありません。
そのため、セキュリティに強いprepareからクエリを実行する方が基本的にオススメです。

条件指定の更新(WHERE句)

$sql = "UPDATE yasai_item
        SET
        price = :price
        WHERE
        name = :name";
//実行準備
$sth = $pdo -> prepare($sql);
//クエリのパラメータに合わせて値を組み込む
$sth -> bindValue(':name', 'にんじん');
$sth -> bindValue(':price', 30);
//組み込み後のSQL文を実行
$sth -> execute();

コロン付きのパラメータで、のちに代入する値を指定しておきます。
その後、bindValueで値を設定後、executeでクエリが実行されます。

ソースコードの通り、SETで代入する値も、WHERE句の条件指定にも、コロン付きパラメータは使用できます。

全行の更新

こちらも同様に、WHERE句はない場合は全行の更新となります。

$sql = "UPDATE yasai_item
        SET
        price = :price";
//実行準備
$sth = $pdo -> prepare($sql);
//クエリのパラメータに合わせて値を組み込む
$sth -> bindValue(':price', 30);
//組み込み後のSQL文を実行
$sth -> execute();

更新された件数を取得するrowCount

UPDATEを行った結果、変更された行を取得したい場合はrowCount()を使用します。

参考 【PHP】PDOで件数を取得するrowCountの使い方

$sql = "UPDATE yasai_item
        SET
        price = 30";
$sth = $pdo -> query($sql);
$count = $sth -> rowCount();
echo $count; // ⇒ 3

rowCountは「更新対象の行数」ではなく「更新された行数」を返します。

例えば、下記のUPDATEを行った場合、返す行数は2となります。

$sql = "UPDATE yasai_item
        SET
        price = 50";
$sth = $pdo -> query($sql);
$count = $sth -> rowCount();
echo $count; // ⇒ 2

対象の行数は3件のはずですが、元々「にんじん」の行のpriceは50となっているので、変更する必要がなかったため、2件のみ変更されたと解釈します。

重複するデータがある場合は更新するON DUPLICATE KEY UPDATE

重複しているデータが既にある場合はUPDATE、ない場合はINSERT文を1つのクエリで行う「ON DUPLICATE KEY UPDATE」という機能もあります。

参考 【PHP】PDOで「ON DUPLICATE KEY UPDATE」の使い方

基本的にINSERT文に付与する形になります。

参考 PDOでINSERTの使い方【PHP】

今回のテーブルでは、「name」にUNIQUE制約を設けています。
なので、既に存在する「きゅうり」を挿入しようとした場合は、挿入は行わず「値段」を変更する、という処理を行ってみます。

$sql = "INSERT
        yasai_item
        (name, price)
        VALUES
        ('きゅうり', 70)
        ON DUPLICATE KEY UPDATE 
        price = VALUES(price)";
$sth = $pdo -> query($sql);

このクエリを実行すると、データを挿入されず、「きゅうり」の列の「price」が80⇒70に変更されます。

id name price
1 にんじん 50
2 トマト 100
3 きゅうり 70

以上、PDOでUPDATEの使い方、でした。

PHP