#データベース
![PDO説明.png](https://qiita-image-store.s3.amazonaws.com/0/95187/c6766d9b-6be4-7e0f-0b29-a3184d7d6f74.png)##ユーザー
データベースを作ったら、このデータベースに
アクセスして操作できるユーザーを作る。
MySQLをインストールしてまもないときは、
rootという管理者権限を持つユーザーが既にいる。
rootユーザーは全てのデータベースを操れるので危険。
なので、データベースを作ったら、
このデータベースだけを操作できるユーザーを作り、
PHPでプログラムを書くときでもそのユーザーで
データベースにアクセスする方が、
他のデータベースを不正利用されず安全
#SQLから
##コマンドプロンプトからMySQLへ接続
mysql -u root -p Enter
Password:password
mysql -h 192.168.1.30 -u ユーザー名 -p
##データベースでユーザー一覧を表示する
# mysql -u root -p
Enter password: ********
Welcome to the MySQL monitor.
mysql> select Host, User FROM mysql.user;
+-----------+------+
| Host | User |
+-----------+------+
| linux | |
| linux | root |
| localhost | |
| localhost | pma |
| localhost | root |
+-----------+------+
5 rows in set (0.02 sec)
##ユーザーの作成
mysql> grant all on test.* to 'testuser'@'localhost' identified by 'root';
Query OK, 0 rows affected (0.02 sec)
確認すると...
mysql> SELECT user,host FROM mysql.user;
+----------+-----------+
| user | host |
+----------+-----------+
| | linux |
| root | linux |
| | localhost |
| pma | localhost |
| root | localhost |
| testuser | localhost |
+----------+-----------+
testuserというユーザーがちゃんとありました
##作成したユーザーでMySQLにログイン
# mysql -u testuser -p
Enter password: ****
Welcome to the MySQL monitor.
##テーブル作成
使用例
mysql> use takahashi1
Database changed
mysql> create table words(id int auto_increment primary key,word varchar(100),se
nse varchar(250),memo varchar(250));
Query OK, 0 rows affected (0.09 sec)
mysql> show fields from words;
+-------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| word | varchar(100) | YES | | NULL | |
| sense | varchar(250) | YES | | NULL | |
| memo | varchar(250) | YES | | NULL | |
+-------+--------------+------+-----+---------+----------------+
mysql> insert into product values(null, 'バターピーナッツ',200);
Query OK, 1 row affected (0.12 sec)
mysql> select * from product;
+----+--------------------+-------+
| id | name | price |
+----+--------------------+-------+
| 1 | 松の実 | 700 |
| 2 | くるみ | 270 |
| 3 | ひまわりの種 | 210 |
| 4 | アーモンド | 220 |
| 5 | カシューナッツ | 250 |
| 6 | ジャイアントコーン | 180 |
| 7 | ピスタチオ | 310 |
| 8 | マカダミアナッツ | 600 |
| 9 | かぼちゃの種 | 180 |
| 10 | ピーナッツ | 150 |
| 11 | クコの実 | 400 |
| 13 | バターピーナッツ | 200 |
+----+--------------------+-------+
mysql> insert into honorifics values(null,'無視してください','ご放念ください','
謝礼のほうはご放念ください');
Query OK, 1 row affected (0.03 sec)
mysql> insert into honorifics values(null,'~がこのように申しております','~がこ
のように言っています',null);
Query OK, 1 row affected (0.03 sec)
mysql> show fields from honorifics;
+----------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| wrongHonorific | varchar(100) | YES | | NULL | |
| rightHonorific | varchar(100) | YES | | NULL | |
| example | varchar(250) | YES | | NULL | |
+----------------+--------------+------+-----+---------+----------------+
##テーブル一覧
SHOW TABLES FROM データベース名;
mysql> show tables from test;
+----------------+
| Tables_in_test |
+----------------+
| week |
+----------------+
##テーブルに登録されたデータ一覧表示
select * from テーブル名;
mysql> select * from product;
+----+--------------------+-------+
| id | name | price |
+----+--------------------+-------+
| 1 | 松の実 | 700 |
| 2 | くるみ | 270 |
| 3 | ひまわりの種 | 210 |
| 4 | アーモンド | 220 |
| 5 | カシューナッツ | 250 |
| 6 | ジャイアントコーン | 180 |
| 7 | ピスタチオ | 310 |
| 8 | マカダミアナッツ | 600 |
| 9 | かぼちゃの種 | 180 |
| 10 | ピーナッツ | 150 |
| 11 | クコの実 | 400 |
+----+--------------------+-------+
##テーブルのフィールド一覧表示
mysql> SHOW FIELDS FROM テーブル名;
mysql> show fields from product;
+-------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(200) | NO | | NULL | |
| price | int(11) | NO | | NULL | |
+-------+--------------+------+-----+---------+----------------+
mysql> select id from product;
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
| 6 |
| 7 |
| 8 |
| 9 |
| 10 |
| 11 |
+----+
mysql> alter table honorific add example varchar(250);
Query OK, 0 rows affected (0.15 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show fields from honorific;
+------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| wrongHonorific | varchar(100) | YES | | NULL | |
| correctHonorific | varchar(100) | NO | | NULL | |
| example | varchar(250) | YES | | NULL | |
+------------------+--------------+------+-----+---------+----------------+
##SQLで商品名で商品を検索
mysql> select * from テーブル名 where 列名='検索キーワード;
productテーブルのnameという列の中にカシューナッツがあるか検索する
mysql> select * from product where name='カシューナッツ';
+----+----------------+-------+
| id | name | price |
+----+----------------+-------+
| 5 | カシューナッツ | 250 |
+----+----------------+-------+
mysql> select * from product;
+----+--------------------------------------------------------+-------+
| id | name | price |
+----+--------------------------------------------------------+-------+
| 1 | 松の実 | 700 |
| 2 | くるみ | 270 |
| 3 | ひまわりの種 | 210 |
mysql> update product set name='高級松の実', price=900 where id=1;
Query OK, 1 row affected (0.09 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from product;
+----+--------------------------------------------------------+-------+
| id | name | price |
+----+--------------------------------------------------------+-------+
| 1 | 高級松の実 | 900 |
| 2 | くるみ | 270 |
| 3 | ひまわりの種 | 210 |
mysql> update product set price=800 where id=1;
Query OK, 1 row affected (0.03 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from product;
+----+--------------------------------------------------------+-------+
| id | name | price |
+----+--------------------------------------------------------+-------+
| 1 | 高級松の実 | 800 |
| 2 | くるみ | 270 |
| 3 | ひまわりの種 | 210 |
##SQLでテーブルのデータを削除
mysql> select * from product;
+----+--------------------+-------+
| id | name | price |
+----+--------------------+-------+
| 1 | 松の実 | 700 |
| 2 | くるみ | 270 |
| 3 | ひまわりの種 | 210 |
| 4 | アーモンド | 220 |
| 5 | カシューナッツ | 250 |
| 6 | ジャイアントコーン | 180 |
| 7 | ピスタチオ | 310 |
| 8 | マカダミアナッツ | 600 |
| 9 | かぼちゃの種 | 180 |
| 10 | ピーナッツ | 150 |
| 11 | クコの実 | 400 |
| 13 | バターピーナッツ | 200 |
| 14 | ローストピーナッツ | 220 |
| 15 | アーモンド | 320 |
+----+--------------------+-------+
14 rows in set (0.01 sec)
mysql> delete from product where name='アーモンド';
Query OK, 2 rows affected (0.06 sec)
mysql> select * from product;
+----+--------------------+-------+
| id | name | price |
+----+--------------------+-------+
| 1 | 松の実 | 700 |
| 2 | くるみ | 270 |
| 3 | ひまわりの種 | 210 |
| 5 | カシューナッツ | 250 |
| 6 | ジャイアントコーン | 180 |
| 7 | ピスタチオ | 310 |
| 8 | マカダミアナッツ | 600 |
| 9 | かぼちゃの種 | 180 |
| 10 | ピーナッツ | 150 |
| 11 | クコの実 | 400 |
| 13 | バターピーナッツ | 200 |
| 14 | ローストピーナッツ | 220 |
+----+--------------------+-------+
delete from テーブル名
delete from product
##キーワードを含まない商品名の検索
mysql> select * from product where name not like '%ナッツ%';
+----+--------------------+-------+
| id | name | price |
+----+--------------------+-------+
| 1 | 松の実 | 700 |
| 2 | くるみ | 270 |
| 3 | ひまわりの種 | 210 |
| 4 | アーモンド | 220 |
| 6 | ジャイアントコーン | 180 |
| 7 | ピスタチオ | 310 |
| 9 | かぼちゃの種 | 180 |
| 11 | クコの実 | 400 |
+----+--------------------+-------+
##like演算子による部分一致検索(ワイルドカード)
mysql> select * from product where name like '%ナッツ%' and name not like 'ピー
ナッツ%';
+----+------------------+-------+
| id | name | price |
+----+------------------+-------+
| 5 | カシューナッツ | 250 |
| 8 | マカダミアナッツ | 600 |
+----+------------------+-------+
mysql> select * from product where name like '%ナッツ';
+----+--------------------+-------+
| id | name | price |
+----+--------------------+-------+
| 5 | カシューナッツ | 250 |
| 8 | マカダミアナッツ | 600 |
| 10 | ピーナッツ | 150 |
| 13 | バターピーナッツ | 200 |
| 14 | ローストピーナッツ | 220 |
+----+--------------------+-------+
##PHPから部分一致で商品を検索する
like演算子
mysql> select * from product where name like '%ナッツ%';
+----+------------------+-------+
| id | name | price |
+----+------------------+-------+
| 5 | カシューナッツ | 250 |
| 8 | マカダミアナッツ | 600 |
| 10 | ピーナッツ | 150 |
+----+------------------+-------+
商品名を入力してください。
<form action="search-output2.php" method="post">
<input type="text" name="keyword">
<input type="submit" value="検索">
</form>
<table>
<tr>
<th>商品番号</th>
<th>商品名</th>
<th>商品価格</th>
</tr>
<?php
$pdo = new PDO ( 'mysql:host=localhost;dbname=shop;charset=utf8', 'staff', 'password' );
$sql = $pdo->prepare ( 'select * from product where name like ?' );
$sql->execute(['%'.$_REQUEST['keyword'].'%'])
;
foreach ( $sql->fetchAll () as $row ) {
echo '<tr>';
echo '<td>', $row ['id'], '</td>';
echo '<td>', $row ['name'], '</td>';
echo '<td>', $row ['price'], '</td>';
echo '</tr>';
echo "\n";
}
?>
</table>
##NOT NULL制約の削除
mysql> alter table honorifics modify column example varchar(200);
##NULL制約を付ける
mysql> alter table words modify column memo varchar(250) null;
##UNIQUE制約を付ける
行ごとに全て異なる値になり、他の行と同じ値を格納することができなくなる。
NULLは格納できる。NULLの値だけは複数のカラムで重複して格納することができる。
mysql>login varchar(100) not null unique,
参考サイト
##外部キー制約(foreign key)
mysql> create table purchase(id int not null primary key,customer_id int not nul
l,foreign key(customer_id) references customer(id));
「purchaseテーブルのcustomer_id列には、customerテーブルのid列に存在する値だけが格納できる」
foreign key=外部キー制約
さまざまな制約 | |
---|---|
foreign key | 外部キー制約を指定した列には、外部のテーブルにある指定した列に含まれる値だけが格納できるようになる |
unique | 行ごとに全て異なる値になり、他の行と同じ値を格納することができなくなる |
primary key | 行ごとに異なる値を割り当てる |
複合主キー | 複数の列を組み合わせて主キーにしたもの |
##複合主キー
複数項目でワンセットな主キー。
複数の項目で一意に識別できる主キーのこと。
##varchar
さまざまな型 | |
---|---|
char(4) | 固定長文字列。char(4)4文字ぴったりしか格納できない |
varchar(バイト数) | 可変長文字列。varchar(4)最大4バイトの文字列を格納できる |
#PHPから
#PHPからデータベースに接続
■PDO()コンストラクタ
PDO('mysql:host=localhost;dbname=データベース名;charset=utf8','接続するユーザー名','パスワード'
<?php
$pdo=new PDO('mysql:host=localhost;dbname=shop;charset=utf8',
'staff', 'password');
?>
<?php
try {
$sql = new PDO ( 'mysql:dbname=takahashi1; host=192.168.1.30;port=3306; charset=utf8', 'takahashi', 'takahashi' );
print '接続に成功しました。';
} catch ( PDOException $e ) {
print "接続エラー:{$e->getMessage()}";
}
$sql = null;
?>
###DBへ接続するファイルを外部化
selfphpフォルダーの中にあるDbManager.php
<?php
function getDb() {
// データベースへの接続を確認
$pdo = new PDO ( 'mysql:dbname=takahashi1; host=192.168.1.30;port=3306; charset=utf8', 'takahashi', 'takahashi' );
return $pdo;
}
?>
<?php
require_once 'selfphp/DbManager.php';
$pdo = getDb();
###mysqli()で接続
$db = new mysqli('192.168.1.30','takahashi','takahashi','takahashi1');
// $db = new mysqli( 'localhost', 'staff', 'password', 'shop' );
if ($db->connect_error) {
echo $db->connect_error;
exit ();
} else {
$db->set_charset ( "utf8" );
echo 'ok';
}
###クラスに記述した関数(メソッド)と変数(プロパティ)
クラス内に記述した変数と関数のみ名称が変わる | |
---|---|
プロパティ | クラスに属する変数 |
メソッド | クラスに属する関数 |
クラス内に記述したときの名称 | |
---|---|
変数 | プロパティ |
関数 | メソッド |
class クラス名 {
$プロパティ名
function メソッド名(引数) {
}
}
参考元サイト
###PDOクラスを使用
PDOクラスを使用するにはPDOのインスタンスを生成する
$pdo = new PDO(....);
$pdo←名前は自由
###コンストラクタ
-
コンストラクタ、_________________________________
コンストラクタ
・コンストラクタとはクラスからオブジェクトがnewによって作成される時に自動的に呼び出されるメソッドです。オブジェクト作成時に初期化処理が必要な場合など、コンストラクタ内に記述しておけば自動的に実行してくれます
■PDO(....)
$pdo=new PDO('mysql:host=localhost;dbname=shop;charset=utf8',
'staff', 'password');
?>
コンストラクタ。
コンストラクタの....の部分には
インスタンスの初期化に用いる引数を書く。
データベースに接続するために必要な引数を記述。
PDO(引数)の引数はDSNと呼ばれている。
▪️DSN
どのサーバーにあるどんなデータベースを使うのかを指定した文字列
###PHPからSQL文を実行(query)
$pdo->query('select * from product')
###query
PHPからSQL文を実行 | |
---|---|
SQL文を実行 | PDOの変数->query('SQL文') |
メソッドを呼び出す | 変数->メソッド |
queryメソッド(関数) | 引数に指定したSQL文をデータベースに対して実行する |
->(アロー演算子) | メソッドを呼び出す |
- メソッド呼び出し(例)
class CrepeShop {
public function buy($crepe) {
$message = '';
if ($crepe == 'チョコ') {
$message = $crepe.'は330円です';
} else if ($crepe == '生クリーム') {
$message = $crepe.'は270円です';
} else {
$message = 'クレープを選択して下さい';
}
return $message;
}
}
$customer = new CrepeShop ();
echo $customer->buy ( '生クリーム' );//生クリームは270円です
echo $customer->buy('チョコ');//チョコは330円です
###PHPで接続したデータベースから情報一覧を表示
<?php
$pdo = new PDO ( 'mysql:host=localhost;dbname=shop;charset=utf8', 'staff', 'password' );
foreach ( $pdo->query ( 'select * from product' ) as $row2 ) {
echo '<p>';
echo $row2 ['id'], ':';
echo $row2 ['name'], ':';
echo $row2 ['price'];
echo '</p>';
}
?>
<?php
$pdo=new PDO('mysql:host=localhost;dbname=shop;charset=utf8',
'staff', 'password');
foreach ($pdo->query('select * from product') as $row) {
echo "<p>$row[id]:$row[name]:$row[price]</p>";
}
?>
1:松の実:700
2:くるみ:270
3:ひまわりの種:210
4:アーモンド:220
5:カシューナッツ:250
6:ジャイアントコーン:180
7:ピスタチオ:310
8:マカダミアナッツ:600
9:かぼちゃの種:180
10:ピーナッツ:150
11:クコの実:400
foreach ( $pdo->query ( 'select * from product' ) as $row2 ) {
}
■列のデータを取り出す
配列['列名']
echo $row['id'];//1
-
<質問>
$pdo->query ( 'select * from product' ) は配列?
foreachは確か、
配列とオブジェクトをループして使うための制御構文と学びました。_________________________________
<解答>
配列では、無いのですが、
使い易くするために、特別に foreach の反復処理で使える様に作られています。
マニュアルを見ましょう。
foreach ( $pdo->query ( 'select * from product' ) as $row2 ) {
echo '<p>';
echo $row2 ['id'], ':';
echo $row2 ['name'], ':';
echo $row2 ['price'];
echo '</p>';
}
foreach ($pdo->query('select * from product') as $row) {
echo "<p>$row[id]:$row[name]:$row[price]</p>";
}
<table>
<tr>
<th>商品番号</th>
<th>商品名</th>
<th>価格</th>
</tr>
<?php
$pdo = new PDO ( 'mysql:host=localhost;dbname=shop;charset=utf8', 'staff', 'password' );
foreach ( $pdo->query ( 'select * from product' ) as $row ) {
echo '<tr>';
echo '<td>', $row ['id'], '</td>';
echo '<td>', $row ['name'], '</td>';
echo '<td>', $row ['price'], '</td>';
echo '</tr>';
echo "\n";
}
?>
</table>
###htmlspecialcharsでより安全に
htmlspecialchars関数でJavascriptのタグを無効化
htmlspecialchars('文字列',エスケープの種類,'文字コード')
エスケープの種類(方法) | 概要 |
---|---|
ENT_COMPAT | ダブルクォートは置き換えるが、シングルクォートは置き換えない |
ENT_QUOTES | シングルクォートとダブルクォートの両方を置き換える |
ENT_NOQUOTES | シングルクォートとダブルクォートの両方を置き換えない |
<table>
<tr>
<th>商品番号</th>
<th>商品名</th>
<th>価格</th>
</tr>
<?php
$pdo = new PDO ( 'mysql:host=localhost;dbname=shop;charset=utf8', 'staff', 'password' );
function h($str) {
return htmlspecialchars ( $str );
}
foreach ( $pdo->query ( 'select * from product' ) as $row ) {
echo '<tr>';
echo '<td>' . h ( $row ['id'] ), '</td>';
echo '<td>', h ( $row ['name'] ), '</td>';
echo '<td>', h ( $row ['price'] ), '</td>';
echo '</tr>';
echo "\n";
}
?>
</table>
<?php
function h($str) {
return nl2br ( htmlspecialchars ( $str, ENT_QUOTES, 'UTF-8' ), false );
}
?>
<p class="textstyle">
■お問い合わせ項目:</br><?php if (isset($_SESSION['object'])){ echo '<font color="black">'.implode("</br>", $_SESSION['object']).'</font>';}?></p>
<p class="textstyle">
■お問い合わせ内容:</br><?php if(isset($_SESSION['contactContent'])){echo h($_SESSION['contactContent']).'</font>';}?>
?>
function h($str) {
return htmlspecialchars ( $str, ENT_QUOTES | ENT_HTML5, 'UTF-8' );
}
function e($str, $charset = 'UTF-8') {
return htmlspecialchars ( $str, ENT_QUOTES | ENT_HTML5, $charset );
}
###htmlspecialcharsで対策していないと。。。
例
MySQLに商品のデータを追加
mysql> insert into product values(null, '',100);
<table>
<tr>
<th>商品番号</th>
<th>商品名</th>
<th>価格</th>
</tr>
<?php
$pdo = new PDO ( 'mysql:host=localhost;dbname=shop;charset=utf8', 'staff', 'password' );
foreach ( $pdo->query ( 'select * from product' ) as $row ) {
echo '<tr>';
echo '<td>' . $row ['id'], '</td>';
echo '<td>' . $row ['name'], '</td>';
echo '<td>' . $row ['price'], '</td>';
echo '</tr>';
echo "\n";
}
?>
</table>
###htmlspecialchars対策&PHPで入力値を確認してから商品を追加する
<p>商品を追加します。</p>
<form action="insert-output2.php" method="post">
商品名<input type="text" name="name">
価格<input type="text" name="price">
<input type="submit" value="追加">
</form>
<?php
$pdo = new PDO ( 'mysql:host=localhost;dbname=shop;charset=utf8', 'staff', 'password' );
$sql = $pdo->prepare ( 'insert into product values(null, ?, ?)' );
$err = array ();
if (empty ( $_REQUEST ['name'] )) {
$err ['name'] = '商品名を入力してください。';
}
if ((preg_match ( '/^[a-zA-Z]+$/', $_REQUEST ['name'] ) || preg_match ( "/^[一-龠]+$/u", $_REQUEST ['name'] )) && ! strlen ( $_REQUEST ['name'] ) == 0) {
$err ['name'] = '商品名はひらがな又はカタカナで入力してください。';
}
if (empty ( $_REQUEST ['price'] )) {
$err ['price'] = '価格を入力してください。';
} else if (! preg_match ( '/[0-9]+/', $_REQUEST ['price'] ) && ! strlen ( $_REQUEST ['price'] ) == 0) {
$err ['price'] = '商品価格は整数で入力してください。';
}
if (count ( $err ) >= 1) {
if (isset ( $err ['name'] )) {
echo $err ['name'].'</br>';
}
if (isset ( $err ['price'] )) {
echo $err ['price'];
}
}else
if ($sql->execute(
[htmlspecialchars($_REQUEST['name']), $_REQUEST['price']]
))
{
echo '追加に成功しました。';
} else {
echo '追加に失敗しました。';
}
?>
<p>
<button onclick="history.back()">戻る</button>
</p>
<?php
$pdo = new PDO ( 'mysql:host=localhost;dbname=shop;charset=utf8', 'staff', 'password' );
$sql = $pdo->prepare ( 'insert into product values(null, ?, ?)' );
$err = array ();
function h($str) {
return htmlspecialchars ( $str );
}
if (empty ( $_REQUEST ['name'] )) {
$err ['name'] = '商品名を入力してください。';
}
if ((preg_match ( '/^[a-zA-Z]+$/', $_REQUEST ['name'] ) || preg_match ( "/^[一-龠]+$/u", $_REQUEST ['name'] )) && ! strlen ( $_REQUEST ['name'] ) == 0) {
$err ['name'] = '商品名はひらがな又はカタカナで入力してください。';
}
if (empty ( $_REQUEST ['price'] )) {
$err ['price'] = '価格を入力してください。';
} else if (! preg_match ( '/[0-9]+/', $_REQUEST ['price'] ) && ! strlen ( $_REQUEST ['price'] ) == 0) {
$err ['price'] = '商品価格は整数で入力してください。';
}
if (count ( $err ) >= 1) {
if (isset ( $err ['name'] )) {
echo $err ['name'] . '</br>';
}
if (isset ( $err ['price'] )) {
echo $err ['price'];
}
}else
if ($sql->execute(
[h($_REQUEST['name']), $_REQUEST['price']]
))
{
echo '追加に成功しました。';
} else {
echo '追加に失敗しました。';
}
?>
<p>
<button onclick="history.back()">戻る</button>
</p>
###htmlentities()
この関数はhtmlspecialchars()と同じですが、 HTML エンティティと等価な意味を有する文字をHTMLエンティティに変換します。
商品名を入力してください。
<form action="search-output.php" method="post">
<input type="text" name="keyword">
<input type="submit" value="検索">
</form>
<?php require 'header.php'; ?>
<table>
<tr>
<th>商品番号</th>
<th>商品名</th>
<th>商品価格</th>
</tr>
<?php
$pdo = new PDO ( 'mysql:host=localhost;dbname=shop;charset=utf8', 'staff', 'password' );
// ?の部分には後から好きな値を設定することが出来る
$sql = $pdo->prepare ( 'select * from product where name=?' );
$sql->execute([$_REQUEST['keyword']])
;
foreach ( $sql->fetchAll () as $row ) {
echo '<tr>';
echo '<td>', $row ['id'], '</td>';
echo '<td>', $row ['name'], '</td>';
echo '<td>', $row ['price'], '</td>';
echo '</tr>';
echo "\n";
}
?>
</table>
<?php require 'footer.php'; ?>
PDOの変数->query('SQL文') | 引数に指定したSQL文をデータベースに対して実行する |
PDOの変数->prepare('SQL文') | SQL文を実行する準備をする |
変数->execute([値]) | SQL文の実行 |
foreach(PDOの変数->fetchAll() as 結果を代入する変数) | 結果を1行ずつ取得して、変数$rowに代入する |
###prepareメソッド
PDOの変数->prepare('SQL文') | SQL文を実行する準備をする |
prepareメソッド | |
PDOStatement::execute() メソッドによって実行される SQL文を準備する。 | |
SQL文は、文が実行されるときに実際の値に置き換えられる疑問符(?)やパラメーターマーク等を含むことができる。 | |
prepareメソッドの引数には、SQL文を文字列で指定する。
SQL文のなかに「?」を含めることができ、
「?」の部分には後から好きな値を設定することが出来る。
select * from product where name=?
$pdo->prepare('select * from product where name=?')
###executeメソッド
変数->execute([値]) | prepareメソッドに引数として渡したSQL文を実行する |
$sql->execute([$_REQUEST['keyword']]);
executeメソッドの引数には、
SQL文のなかの「?」部分に設定する値を配列にして渡す。
配列にするのは、1つのSQL文内に複数箇所の?を配置することができるから。
変数->execute([値])
・複数の?がある場合は、外側を[]で囲み、
複数の値を「,」で区切って
[値, 値, ...]のように並べる。
?が1個だけの場合には[値]のように外側を[]で囲むだけ。
$_REQUEST['keyword']
$sql->execute([$_REQUEST['keyword']]);
select * from product where name=?
select * from product where name=`カシューナッツ`
_________________________________________________________
####executeはqueryで取得可能
executeメソッドで実行した結果はfetchAllで
取得しなくてもいい場合がある。
結果セットのPDOStatement型データを返すので、
それを一行ずつ$rowに格納してforeach()ループで一行ずつ読み出しているので問題ありません。
一度に結果全行を読み出すのと、
結果一行ずつすべて読むのとどう違うかというと、
全行読み出すとき結果のレコード数が数千数万だったりすると、
結果を溜め込むまで一見処理が止まってしまいます。
(メモリ的リソースもきつくなります。)
一行ずつ読み出すと、順々にHTML出力ができて止まらず出力し続けられます。
(溜め込まないため軽く動かせるはず。)
(executeメソッドで実行した結果はqueryで取得できる)[https://teratail.com/questions/67076]
query | 結果一行ずつすべて読む |
fetchAll() | 結果データを全件まとめて配列で取得 |
--
###exec()メソッド
exec() | SQLステートメントを実行し、作用した行数を返す。PDOオブジェクトに対して実行可能な、PHPからSQLを実行するためのメソッド。 |
execute() | PDOStatementのインスタンスに対して実行可能な、prepareメソッドで用意したSQL文を実行するメソッド。 |
foreach(PDOの変数->fetchAll() as 結果を代入する変数) | SQL文をexecuteメソッドで実行した結果を取得する |
fetch() | 1件データを取得 |
fetchAll() | 結果データを全件まとめて配列で取得 |
mysql> select * from product;
+----+--------------------+-------+
| id | name | price |
+----+--------------------+-------+
| 1 | 松の実 | 700 |
| 2 | くるみ | 270 |
| 3 | ひまわりの種 | 210 |
| 4 | アーモンド | 220 |
| 5 | カシューナッツ | 250 |
| 6 | ジャイアントコーン | 180 |
| 7 | ピスタチオ | 310 |
| 8 | マカダミアナッツ | 600 |
| 9 | かぼちゃの種 | 180 |
| 10 | ピーナッツ | 150 |
| 11 | クコの実 | 400 |
| 13 | バターピーナッツ | 200 |
| 14 | ローストピーナッツ | 220 |
+----+--------------------+-------+
PDOの変数->prepare('SQL文') | SQL文を実行する準備をする |
変数->execute([値]) | SQL文の実行 |
foreach(PDOの変数->fetchAll() as 結果を代入する変数) | 結果を1行ずつ取得して、変数$rowに代入する |
<p>商品を追加します。</p>
<form action="insert-output.php" method="post">
商品名<input type="text" name="name">
価格<input type="text" name="price">
<input type="submit" value="追加">
</form>
<?php
$pdo=new PDO('mysql:host=localhost;dbname=shop;charset=utf8',
'staff', 'password');
$sql=$pdo->prepare('insert into product values(null, ?, ?)');
if ($sql->execute([$_REQUEST['name'], $_REQUEST['price']])) {
echo '追加に成功しました。';
} else {
echo '追加に失敗しました。';
}
?>
<?php
$pdo = new PDO ( 'mysql:host=localhost;dbname=shop;charset=utf8', 'staff', 'password' );
$sql = $pdo->prepare ( 'insert into product values(null, ?, ?)' );
if ($sql->execute ( array (
$_REQUEST ['name'],
$_REQUEST ['price']
) )) {
echo '追加に成功しました。';
} else {
echo '追加に失敗しました。';
}
?>
###type属性をhiddenにする
隠しデータを送信することができる。
ユーザーには見せる必要のない隠し情報をフォーム内に埋め込むことができる。 この情報は、ブラウザ上には表示されない。
hidden
echo '<input type="hidden" name="id" value="', $row['id'], '">';
###PHPから商品データを更新する
<?php require 'header.php';?>
<table>
<tr>
<th>商品番号</th>
<th>商品名</th>
<th>商品価格</th>
</tr>
<?php
$pdo = new PDO ( 'mysql:host=localhost;dbname=shop;charset=utf8', 'staff', 'password' );
foreach ( $pdo->query ( 'select * from product' ) as $row ) {
echo '<tr><form action="update-output.php" method="post">';
// type="hidden"にすることでフォームに商品番号を含めつつも編集できないようにしている
echo '<input type="hidden" name="id" value="', $row ['id'], '">';
echo '<td>', $row ['id'], '</td>';
echo '<td>';
echo '<input type="text" name="name" value="', $row ['name'], '">';
echo '</td>';
echo '<td>';
echo '<input type="text" name="price" value="', $row ['price'], '">';
echo '</td>';
echo '<td><input type="submit" value="更新"></td>';
echo '</form></tr>';
echo "\n";
}
?>
</table>
<?php require 'footer.php';?>
<?php require 'header.php';?>
<?php
$pdo = new PDO ( 'mysql:host=localhost;dbname=shop;charset=utf8', 'staff', 'password' );
$sql = $pdo->prepare ( 'update product set name=?, price=? where id=?' );
$err = array ();
function h($str) {
return htmlspecialchars ( $str );
}
if (empty ( $_REQUEST ['name'] )) {
$err ['name'] = '商品名を入力してください。';
}
if ((preg_match ( '/^[a-zA-Z]+$/', $_REQUEST ['name'] ) || preg_match ( "/^[一-龠]+$/u", $_REQUEST ['name'] ) || preg_match ( '/[0-9]+/', $_REQUEST ['name'] )) && ! strlen ( $_REQUEST ['name'] ) == 0) {
$err ['name'] = '商品名はひらがな又はカタカナで入力してください。';
}
if (empty ( $_REQUEST ['price'] )) {
$err ['price'] = '価格を入力してください。';
} else if (! preg_match ( '/[0-9]+/', $_REQUEST ['price'] ) && ! strlen ( $_REQUEST ['price'] ) == 0) {
$err ['price'] = '商品価格は整数で入力してください。';
}
if (count ( $err ) >= 1) {
if (isset ( $err ['name'] )) {
echo $err ['name'] . '</br>';
}
if (isset ( $err ['price'] )) {
echo $err ['price'];
}
}else
if($sql -> execute(
[h($_REQUEST['name']),
$_REQUEST['price'], $_REQUEST['id']]
))
{
echo '更新に成功しました。';
}else {
echo '更新に失敗しました。';
}
?>
<p>
<button onclick="history.back()">戻る</button>
</p>
<?php require 'footer.php';?>
<p>
<a href="test16-output.php?id=1&name=値">次に</a>
</p>
<?php
$id = $_GET ['id'];
$name = $_GET ['name'];
echo $id . "<br/>";
echo $name;
?>
1
値
<table>
<tr>
<th>商品番号</th>
<th>商品名</th>
<th>商品価格</th>
</tr>
<?php
$pdo = new PDO ( 'mysql:host=localhost;dbname=shop;charset=utf8', 'staff', 'password' );
foreach ( $pdo->query ( 'select * from product' ) as $row ) {
echo '<tr>';
echo '<td>', $row ['id'], '</td>';
echo '<td>', $row ['name'], '</td>';
echo '<td>', $row ['price'], '</td>';
echo '<td>';
echo '<a href="delete-output2.php?id=', $row ['id'], '">削除</a>';
echo '</td>';
echo '</tr>';
echo "\n";
}
?>
</table>
<?php
$pdo = new PDO ( 'mysql:host=localhost;dbname=shop;charset=utf8', 'staff', 'password' );
$sql = $pdo->prepare ( 'delete from product where id=?' );
if ($sql->execute([$_REQUEST['id']]))
{
echo '削除に成功しました。';
} else {
echo '削除に失敗しました。';
}
?>
<p>
<button onclick="history.back()">戻る</button>
</p>
###PHPから商品データを削除する②
<table>
<tr>
<th>商品番号</th>
<th>商品名</th>
<th>商品価格</th>
</tr>
<?php
$pdo = new PDO ( 'mysql:host=localhost;dbname=shop;charset=utf8', 'staff', 'password' );
foreach ( $pdo->query ( 'select * from product' ) as $row ) {
echo '<tr>';
echo '<td>', $row ['id'], '</td>';
echo '<td>', $row ['name'], '</td>';
echo '<td>', $row ['price'], '</td>';
echo '<td>';
echo '<form action="delete-output.php" method="post"><input type="hidden" name="id" value="'.$row['id'].'"><input type="submit" value="削除" name="submit"></form>';
echo '</td>';
echo '</tr>';
echo "\n";
}
?>
</table>
<?php
// var_dump ( $_POST );
// var_dump($_POST['id']);
$pdo = new PDO ( 'mysql:host=localhost;dbname=shop;charset=utf8', 'staff', 'password' );
$sql = $pdo->prepare ( 'delete from product where id=?' );
// is_numeric→変数が数値または数値文字列かどうか調べる
// is_string→文字列型かどうか調べる関数
// 条件?TRUEの場合の返却値:FALSEの場合の返却値;
$id = isset ( $_POST ['id'] ) ? $_POST ['id'] : '';
// $id = isset($_POST['id']) && is_string($_POST['id'])?$_POST['id']:'';
// array→配列を生成する。
if($sql->execute([$id])){
// if ($sql->execute ( array ($id) )) {
echo '削除に成功しました。';
} else {
echo '削除に失敗しました。';
}
// var_dump(array ($id));
?>
<p>
<button onclick="history.back()">戻る</button>
</p>
<?php
session_start();
unset($_SESSION['customer']);
$pdo=new PDO('mysql:host=localhost;dbname=shop;charset=utf8',
'staff', 'password');
$sql=$pdo->prepare('select * from customer where login=? and password=?');
$sql->execute([$_REQUEST['login'], $_REQUEST['password']]);
foreach ($sql->fetchAll() as $row) {
$_SESSION['customer']=[
'id'=>$row['id'], 'name'=>$row['name'],
'address'=>$row['address'], 'login'=>$row['login'],
'password'=>$row['password']];
}
if (isset($_SESSION['customer'])) {
echo 'いらっしゃいませ、', $_SESSION['customer']['name'], 'さん。';
} else {
echo 'ログイン名またはパスワードが違います。';
}
?>
<?php
session_start ();
unset ( $_SESSION ['customer'] );
$pdo = new PDO ( 'mysql:host=localhost;dbname=takahashi1;charset=utf8', 'takahashi', 'takahashi' );
$sql = $pdo->prepare ( 'select * from customer where login=? and password=?' );
$sql->execute ( array (
$_REQUEST ['login'],
$_REQUEST ['password']
) );
foreach ( $sql->fetchAll () as $row ) {
$_SESSION ['customer'] = array (
'id' => $row ['id'],
'name' => $row ['name'],
'address' => $row ['address'],
'login' => $row ['login'],
'password' => $row ['password']
);
}
if (isset ( $_SESSION ['customer'] )) {
echo 'いらっしゃいませ、', $_SESSION ['customer'] ['name'], 'さん。';
} else {
echo 'ログイン名またはパスワードが違います。';
}
?>
##PDO(PHP Data Objects)
PDOはクラスの一種。
様々なデータベース(DBMS)を簡単に利用できるようにする、PHPの拡張機能。※拡張→新しい部品などを取り付けて機能を追加する
PDOを使うことで、DBMSの違いを吸収し、
異なるDBMSに対して同じプログラムで
同じ処理をさせることが出来る。
MySQL以外に、Oracle、SQLiteなど様々なデータベース(DBMS)があり、DBMS、それぞれデータベースを使うときのプログラムの書き方が違うから
使うデータベースを変えるとPHPのプログラムを修正する手間がかかる。
これを回避するためにPHPとDBMSの間に抽象化レイヤを挟んでそれぞれさまざまなデータベースの違いを
このレイヤで吸収し、さまざま違うデータベースに同じプログラムで同じ処理をできるようにする
それがPDOの機能。
MySQLへの接続をする関数→mysql_connect関数
PostgreSQLへの接続をする関数→pg_connect関数
システムをMySQLからPostgreSQLに移行するときにプログラムを書き換えないといけない。この手間を防ぐのに抽象化レイヤ(PDO)が使われる。
抽象化レイヤ(PDO)を使えば、どんなデータベースでも
mysql_connect関数で接続できる
##パラメーター
媒介変数、補助変数、母数、引数、設定値などの意味を持つ英単語。
プログラミングでは、関数やメソッドなどが呼び出し元から渡された値を受け取るための変数のことをパラメータという。この意味では仮引数と訳されることもある。
##エミュレーション
特定のコンピューターやOS向けに開発されたプログラムを、異なる環境のコンピューターで使うこと。一般的には、OSなどが異なる環境では、プログラムを共用できない。プログラムを異なる環境で動かしたいときは、プログラムの一部やすべてを書き換えてつくり直す必要があり、これを移植という。エミュレーションでは、基本的にはプログラムを書き換えずに、エミュレーターというソフトウェアを介して、疑似的に別のコンピューターの環境を作り出すことで、プログラムを動作させる
##エミュレーター
機械を真似る機械。
ある機械部品やソフトウェアを動作させるのに、オリジナルのシステムを用意するのが難しい場合に、オリジナルと全く同じ動作をするより簡便なシステムを用意することがある。この装置をエミュレータと言う。
##bindParam
指定された変数名にパラメーターをバインド(関連付ける)する