Help us understand the problem. What is going on with this article?

PHPでデータベースに接続してみる

More than 3 years have passed since last update.

はじめに

前提として、Vagrantでローカル環境を構築しPHPとApacheをインストールしておきます。
インストールしていない場合、下記でインストールします。

$ sudo yum install httpd
$ sudo yum install php php-cli php-common php-gd php-in tl php-mbstring php-mysql php-pdo

テーブルの構造

下記のようなテーブルがあるという前提となります。

mysql> desc users;
+-------+--------------+------+-----+---------+----------------+
| Field | Type         | Null | Key | Default | Extra          |
+-------+--------------+------+-----+---------+----------------+
| id    | int(11)      | NO   | PRI | NULL    | auto_increment |
| name  | varchar(100) | YES  |     | NULL    |                |
| email | varchar(100) | YES  |     | NULL    |                |
+-------+--------------+------+-----+---------+----------------+

PDOでのデータベース接続

PDOとは

PDOは「PHP Data Objects」の略で、PHP標準(5.1.0以降)のデータベース接続クラスのことです。

PDOでデータベースに接続する

$db = new PDO('データベースの種類:host=接続先アドレス;dbname=データベース名', 'ユーザー名', 'パスワード');

エラーがでた場合はPDOException(PDO が発するエラー)を投げるようにする

エラーをスローするには、PDO->setAttribute()でエラーの属性を設定します。

//PDO::ATTR_ERRMODE エラーレポート 
//PDO::ERRMODE_EXCEPTION exceptionsを投げる
PDO->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION) 

接続してみる。

<?php
  define('DB_DATABASE','my_db');
  define('DB_USERNAME','my_user');
  define('DB_PASSWORD','password');
  define('PDO_DSN','mysql:host=localhost;dbname=' . DB_DATABASE);

  try{
    //DB接続
    $db = new PDO(PDO_DSN,DB_USERNAME,DB_PASSWORD);
    //エラーをスロー
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

  } catch(PDOException $e){
    echo $e->getMessage();
    exit;
  }
 ?>

データベースへの接続を切る

データベースへの接続を切るには、PDOクラスで作成したオブジェクトをnullで置き換えるだけです。

$db = null;

PHPからテーブルにレコードを入れてみる

レコードを追加するには、下記のPDOオブジェクトのメソッドを使用します。

  • exec()
  • query()
  • prepare()

exec関数

引数に指定したコマンド($command)を実行します。
また、コマンドの実行結果を返却しません。

exec ( string $command [, array &$output [, int &$return_var ]] );

実行

<?php
  define('DB_DATABASE','php_test');
  define('DB_USERNAME','user');
  define('DB_PASSWORD','Sato2323');
  define('PDO_DSN','mysql:dbhost=localhost;dbname=' . DB_DATABASE);

  try{
    //DB接続
    $db = new PDO(PDO_DSN,DB_USERNAME,DB_PASSWORD);
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    //テーブルにレコードを追加
    $db -> exec("insert into users (name,email) values ('sato','sato@hogehoge.com')");

  } catch(PDOException $e){
    echo $e->getMessage();
    exit;
  }
 ?>

実行結果

設定した値が挿入されているのが確認できる。

mysql> select * from users;
+----+------+-------------------+
| id | name | email             |
+----+------+-------------------+
|  1 | sato | sato@hogehoge.com |
+----+------+-------------------+

prepare関数

引数に指定したコマンド($command)に、異なるパラメータを用いて複数回実行するコマンドに適しています。
また、コマンドの実行結果を返却します。

prepare ( string $command [, array driver_options] );

実行

<?php
  define('DB_DATABASE','php_test');
  define('DB_USERNAME','user');
  define('DB_PASSWORD','Sato2323');
  define('PDO_DSN','mysql:dbhost=localhost;dbname=' . DB_DATABASE);

  try{
    //DB接続
    $db = new PDO(PDO_DSN,DB_USERNAME,DB_PASSWORD);
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $stmt = $db->prepare('insert into users (name,email) values(?,?)');
    $stmt->execute(array('sato','sato@hogehoge.com'));

  } catch(PDOException $e){
    echo $e->getMessage();
    exit;
  }
 ?>

$stmt->execute(array('sato','sato@hogehoge.com'));の箇所を、
$stmt->execute(['sato','sato@hogehoge.com']);と書いたら動かなかった。なぜ・・・。

追記:下記の書き方はPHP 5.3以前では動かないようです。ちなみに実行時のバージョンは5.3.3でした。

$stmt->execute(['sato','sato@hogehoge.com']);

実行結果

設定した値が挿入されているのが確認できる。

mysql> select * from users;
+----+------+-------------------+
| id | name | email             |
+----+------+-------------------+
|  1 | sato | sato@hogehoge.com |
+----+------+-------------------+

prepare関数のパラメーターに名前を指定する

prepare関数のパラメーターに名前を指定することができます。指定の仕方は下記になります。

名前無しのパラメーター

$stmt = $db->prepare('insert into users (name,email) values(?,?)');
$stmt->execute(array('sato','sato@hogehoge.com'));

名前付きのパラメーター

$stmt = $db->prepare('insert into users (name,email) values(:name,:email)');
$stmt->execute(array('name'=>'sato','email'=>'sato@hogehoge.com'));

execute()する際に、パラメーターの値をbindValueで設定する

例えば、satoという名前のユーザーに、複数のemailを設定したい場合などに、bindValue関数を使用すると便利らしい。。。

bindValue(パラメーター名もしくはindex番号,パラメータにバインドする値,データ型);
実行
<?php
  define('DB_DATABASE','php_test');
  define('DB_USERNAME','user');
  define('DB_PASSWORD','Sato2323');
  define('PDO_DSN','mysql:dbhost=localhost;dbname=' . DB_DATABASE);

  try{
    //DB接続
    $db = new PDO(PDO_DSN,DB_USERNAME,DB_PASSWORD);
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $stmt = $db->prepare('insert into users (name,email) values(?,?)');

    //名前付きパラメーターの場合
    //$stmt = $db->prepare('insert into users (name,email) values(:name,:email)');


    $name = 'sato';
    $stmt -> bindValue(1,$name,PDO::PARAM_STR);
    //名前付きパラメーターの場合
    //$stmt -> bindValue(':name',$name,PDO::PARAM_STR);

    $email = 'sato@hogehoge.com';
    $stmt -> bindValue(2,$email,PDO::PARAM_STR);
    //名前付きパラメーターの場合
    //$stmt -> bindValue(':email',$email,PDO::PARAM_STR);
    $stmt->execute();

    $email = 'sato2@hogehoge.com';
    $stmt -> bindValue(2,$email,PDO::PARAM_STR);
    $stmt->execute();

    $email = 'sato3@hogehoge.com';
    $stmt -> bindValue(2,$email,PDO::PARAM_STR);
    $stmt->execute();

  } catch(PDOException $e){
    echo $e->getMessage();
    exit;
  }
 ?>

実行結果

名前を固定化して値が挿入されているのが確認できる。

mysql> select * from users;
+----+------+--------------------+
| id | name | email              |
+----+------+--------------------+
| 10 | sato | sato@hogehoge.com  |
| 11 | sato | sato2@hogehoge.com |
| 12 | sato | sato3@hogehoge.com |
+----+------+--------------------+

execute()する際に、パラメーターの値をbindParamで設定する

bindValueは値そのものを設定するのに対して、bindParamは変数への参照を設定します。
bindParamが変数の値を参照するタイミングはexecute()が実行時です。

実行
<?php
  define('DB_DATABASE','php_test');
  define('DB_USERNAME','user');
  define('DB_PASSWORD','Sato2323');
  define('PDO_DSN','mysql:dbhost=localhost;dbname=' . DB_DATABASE);

  try{
    //DB接続
    $db = new PDO(PDO_DSN,DB_USERNAME,DB_PASSWORD);
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    $stmt = $db->prepare('insert into users (name,email) values(?,?)');

    $name = 'sato';
    $stmt -> bindValue(1,$name,PDO::PARAM_STR);
    $email = 'sato@hogehoge.com';
    $stmt -> bindParam(2,$email,PDO::PARAM_STR);
    $stmt->execute();
    $email = 'sato1@hogehoge.com';
    $stmt->execute();
    $email = 'sato2@hogehoge.com';
    $stmt->execute();

  } catch(PDOException $e){
    echo $e->getMessage();
    exit;
  }
 ?>


実行結果

変数を書き換えた値が、正しく反映されていることが確認できます。

mysql> select * from users;
+----+------+--------------------+
| id | name | email              |
+----+------+--------------------+
| 16 | sato | sato@hogehoge.com  |
| 17 | sato | sato1@hogehoge.com |
| 18 | sato | sato2@hogehoge.com |
+----+------+--------------------+

query関数

引数に指定したコマンド($command)に、異なるパラメータを用いて1回実行するコマンドに適しています。
また、コマンドの実行結果を返却します。

query ( string $command [, array driver_options] );
実行
<?php
  define('DB_DATABASE','php_test');
  define('DB_USERNAME','user');
  define('DB_PASSWORD','Sato2323');
  define('PDO_DSN','mysql:dbhost=localhost;dbname=' . DB_DATABASE);

  try{
    //DB接続
    $db = new PDO(PDO_DSN,DB_USERNAME,DB_PASSWORD);
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    //テーブルのレコードを抽出
    $stmt = $db->query('select * from users');
    //fetchAll(PDO::返却される配列の形式)でquery関数で返却された値を全件取得します
    $users = $stmt -> fetchAll(PDO::FETCH_ASSOC);

    foreach ($users as $user) {
      var_dump($user);
      echo
    }

  } catch(PDOException $e){
      echo 'user error';
    echo $e->getMessage();
    exit;
  }
 ?>

実行結果

画面上に下記のように表示され、レコードが取得出来ているのが確認できます。

array(3) {
  ["id"]=>string(2) "16"
  ["name"]=>string(4) "sato"
  ["email"]=>string(17) "sato@hogehoge.com"
}
array(3) {
  ["id"]=>string(2) "17"
  ["name"]=>string(4) "sato"
  ["email"]=>string(18) "sato1@hogehoge.com"
}
array(3) {
  ["id"]=>string(2) "18"
  ["name"]=>string(4) "sato"
  ["email"]=>string(18) "sato2@hogehoge.com"
}

おわり

データベースに接続して、値を設定したり、取得できたりしました。
この辺りはもっと勉強が必要そうです。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした