PHPでトランザクションを久々に使用した。サンプルコード

2023.03.08

Logging

おはようございます。

先日、PHPでトランザクションを久々に使用した。サンプルコードは以下になります。トランザクションやロールバックとかいう言葉は聞いても実際に使用してみないとその役割りや良さはわからないものかなって思います。

$dsn = 'mysql:host=localhost;dbname=mydatabase';
$username = 'myusername';
$password = 'mypassword';

try {
    $dbh = new PDO($dsn, $username, $password);
    $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    // トランザクションを開始する
    $dbh->beginTransaction();

    // データベース操作1を実行する
    $stmt1 = $dbh->prepare('INSERT INTO users (name, email) VALUES (?, ?)');
    $stmt1->execute(array('John Doe', 'john.doe@example.com'));

    // データベース操作2を実行する
    $stmt2 = $dbh->prepare('UPDATE accounts SET balance = balance - 100 WHERE user_id = ?');
    $stmt2->execute(array(1));

    // データベース操作3を実行する(エラーが起きることをシミュレートする)
    $stmt3 = $dbh->prepare('INSERT INTO orders (user_id, total_amount) VALUES (?, ?)');
    $stmt3->execute(array(1, 'abc')); // 'total_amount'カラムに文字列を挿入しているため、エラーが発生する

    // コミットする
    $dbh->commit();

} catch (PDOException $e) {
    // エラーが発生した場合はロールバックする
    $dbh->rollBack();
    echo 'Transaction failed: ' . $e->getMessage();
}

タグ

array, beginTransaction, catch, commit, dbh, dbname, echo, execute, getMessage, host, john.doe@example.com, localhost, mydatabase, MYSQL, PDO, PDOException, prepare, rollBack, setAttribute, VALUES,

phpのPDOでバインドする時、こうすれば楽。

2020.02.28

Logging

phpのPDOでバインドする時、こうすれば楽ですよね(・(ェ)・)という記述です。前の職場ではsqliでDB接続していたのですが、バインドして作られていたかは忘れてしまいました。ちなみに前の職場のPDOに改修するのは面倒くさいだろうなと感じます。何がめんどくさいかと言えば、今まで導入していたもの全てに対応するというのは、超面倒くさいと思います。

余談:
前の職場を何故辞めたかのお話します。突発的に辞めたと思う人もいるかもしれませんが、基本的に突発的辞めることはないです。突発的に辞めたかのように見えて前々から考えてきっかけを理由に辞めました。具体的な理由に関してはここでは書きません。突発的に辞めたかのように見せかけて計画的です(・(ェ)・)


ソースコードは下記になります。

<?php
ini_set("display_errors",1);
class mysql {
    static $dbh = Null;
    static $host = "localhost";
    static $id = "あいーでぃー";
    static $pass= "パスワード";
    static $dbname = "test";
    static $sql = array(
        "id"=>array("data"=>PDO::PARAM_INT,"val"=>""),
        "name"=>array("data"=>PDO::PARAM_STR,"val"=>"")
    );
    static function connect()
    {
        /* 接続状況をチェックします */
        try {
            static::$dbh = new PDO('mysql:host='.static::$host.';dbname='.static::$dbname.';', static::$id, static::$pass);
            static::$dbh->query('SET NAMES utf8');
          } catch (Exception $e) {
            echo "Failed: " . $e->getMessage();
          }
    }
    static function insert_query(){
        //プリペアドステートメント
        $stmt = static::$dbh->prepare("insert into test1 (id,Name) values(:id,:name);");
        //バインド
        foreach(static::$sql as $key=>&$val){
            $stmt->bindParam(":$key",$val["val"],$val["data"]);
        }
        $stmt->execute();
        $stmt = null;
     }
     static function update_query(){
        //プリペアドステートメント
        $stmt = static::$dbh->prepare("update test1 set Name= :name where id = :id;");
        //バインド
        foreach(static::$sql as $key=>&$val){
            $stmt->bindParam(":$key",$val["val"],$val["data"]);
        }
        $stmt->execute();
        $stmt = null;
     }
     static function select_query(){
        //プリペアドステートメント
        $stmt = static::$dbh->prepare("select * from test1 where id = :id;");
        //バインド
        foreach(static::$sql as $key=>&$val){
            if($key==="id")$stmt->bindParam(":$key",$val["val"],$val["data"]);
        }
        $stmt->execute();
        while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
            printf ("%d (%s)<br>", $row["id"], $row["Name"]);
        }
        $stmt = null;
     }
    static function close(){
        static::$dbh = null;
    }
}
mysql::connect();
// for($i = 0 ;$i<=99;$i++){
//     mysql::$sql["id"]["val"] = $i;
//     mysql::$sql["name"]["val"] = "テスト$i";
//     mysql::insert_query();
// }
for($i = 0 ;$i<=99;$i++){
    mysql::$sql["id"]["val"] = $i;
    mysql::$sql["name"]["val"] = "テスト<font color='red'>$i</font>";
    mysql::update_query();
}
for($i = 0 ;$i<=99;$i++){
    mysql::$sql["id"]["val"] = $i;
    mysql::select_query();
}
mysql::close();

タグ

, class, db, dbh, display, errors, ini, lt, MYSQL, PDO, php, quot, set, sqli, static, お話, きっかけ, コード, ここ, こと, ソース, バインド, もの, 下記, , , 余談, 全て, , 前々, 対応, 導入, 接続, 改修, , 理由, 職場, 記述,

PHPでバインドするこれでSQLの脆弱性が!?

2019.02.23

Logging

上記の画像では脆弱性がある。
PHPでバインドするこれでSQLの脆弱性が解決してくれる?
こういう記述すると良さげ。
おまけでSQLデバッグ方法を書いとります

<?php
$sql =<<<SQL
select * from demo where id = :id and namae = :hoge;
SQL;
$dbh = new PDO('mysql:host=localhost;dbname=test', $user, $pass);
$id = 123;
$hoge = "hoge";
$sth = $dbh->prepare($sql);
$sth->bindValue(':id', $id, PDO::PARAM_INT);
$sth->bindValue(':hoge', $hoge, PDO::PARAM_STR);
$sth->execute();

タグ

$dbh-&gt, dbh, dbname, execute, hoge, host, localhost, lt, MYSQL, PARAM_INT, PARAM_STR, PDO, php, prepare, SQL, SQL select, sth, test,