MySQLBLOBデータ型を使用してUbuntu18.04でPHPを使用して画像を保存する方法
著者は、 Write for DOnations プログラムの一環として、 Girls WhoCodeを選択して寄付を受け取りました。
序章
バイナリラージオブジェクト(BLOB)は、画像、マルチメディア、PDFファイルなどのバイナリデータを格納できるMySQLデータ型です。
画像を関連データと同期させる必要がある緊密に結合されたデータベースを必要とするアプリケーション(たとえば、従業員ポータル、学生データベース、または財務アプリケーション)を作成する場合、学生のパスポートなどの画像を保存すると便利な場合があります。他の関連情報と一緒にMySQLデータベースの写真と署名。
これがMySQLBLOB
データ型の出番です。 このプログラミングアプローチにより、画像を保存するための個別のファイルシステムを作成する必要がなくなります。 このスキームはまた、データベースを一元化し、データがファイルシステムから分離されているため、データベースの移植性と安全性を高めます。 すべてのデータを含む単一のMySQLダンプファイルを作成できるため、バックアップの作成もよりシームレスになります。
データの取得はより高速であり、レコードを作成するときに、特に MySQLトランザクションを使用する場合に、データ検証ルールと参照整合性が維持されることを確認できます。
このチュートリアルでは、MySQL BLOB
データ型を使用して、Ubuntu18.04でPHPを使用して画像を保存します。
前提条件
このガイドに従うには、次のものが必要です。
- Ubuntu 18.04で初期サーバーセットアップを使用して構成されたUbuntu18.04サーバーと、
sudo
権限を持つ非rootユーザー。 - Apache、MySQL、およびPHPは、 Ubuntu 18.04 にLinux、Apache、MySQL、PHP(LAMP)スタックをインストールする方法に関するガイドに従ってセットアップします。 このチュートリアルでは、仮想ホストを作成する必要がないため、手順4をスキップできます。
ステップ1—データベースの作成
プロジェクトのサンプルデータベースを作成することから始めます。 これを行うには、サーバーにSSHで接続し、次のコマンドを実行して、rootとしてMySQLサーバーにログインします。
- sudo mysql -u root -p
MySQLデータベースのrootパスワードを入力し、ENTER
を押して続行します。
次に、次のコマンドを実行してデータベースを作成します。 このチュートリアルでは、test_company
という名前を付けます。
- CREATE DATABASE test_company;
データベースが作成されると、次の出力が表示されます。
OutputQuery OK, 1 row affected (0.01 sec)
次に、MySQLサーバーでtest_user
アカウントを作成し、PASSWORD
を強力なパスワードに置き換えることを忘れないでください。
- CREATE USER 'test_user'@'localhost' IDENTIFIED BY 'PASSWORD';
次の出力が表示されます。
OutputQuery OK, 0 rows affected (0.01 sec)
test_user
にtest_company
データベースに対する完全な権限を付与するには、次のコマンドを実行します。
- GRANT ALL PRIVILEGES ON test_company.* TO 'test_user'@'localhost';
次の出力が得られることを確認してください。
OutputQuery OK, 0 rows affected (0.01 sec)
最後に、MySQLが権限を再ロードするために、権限テーブルをフラッシュします。
- FLUSH PRIVILEGES;
次の出力が表示されていることを確認してください。
OutputQuery OK, 0 rows affected (0.01 sec)
test_company
データベースとtest_user
の準備ができたので、サンプル製品を保存するためのproducts
テーブルの作成に進みます。 後でこのテーブルを使用してレコードを挿入および取得し、MySQLBLOB
がどのように機能するかを示します。
MySQLサーバーからログアウトします。
- QUIT;
次に、作成したtest_user
の資格情報を使用して再度ログインします。
- mysql -u test_user -p
プロンプトが表示されたら、test_user
のパスワードを入力し、ENTER
を押して続行します。 次に、次のように入力して、test_company
データベースに切り替えます。
- USE test_company;
test_company
データベースを選択すると、MySQLは次のように表示します。
OutputDatabase changed
次に、以下を実行してproducts
テーブルを作成します。
- CREATE TABLE `products` (product_id BIGINT PRIMARY KEY AUTO_INCREMENT, product_name VARCHAR(50), price DOUBLE, product_image BLOB) ENGINE = InnoDB;
このコマンドは、products
という名前のテーブルを作成します。 テーブルには4つの列があります。
-
product_id
:この列は、BIGINT
データ型を使用して、最大2⁶³-1アイテムまでの多数の製品リストに対応します。 商品を一意に識別するために、列にPRIMARY KEY
のマークを付けました。 MySQLが挿入された列の新しい識別子の生成を処理するために、キーワードAUTO_INCREMENT
を使用しました。 -
product_name
:この列には製品の名前が表示されます。 このフィールドは通常、最大50
文字までの英数字を処理するため、VARCHAR
データ型を使用しました。50
の制限は、このチュートリアルの目的。 -
price
:デモンストレーションの目的で、products
テーブルには、製品の小売価格を格納するprice
列が含まれています。 一部の製品には変動値(23.69、45.36、102.99など)がある可能性があるため、DOUBLE
データ型を使用しました。 -
product_image
:この列は、BLOB
データ型を使用して、製品の画像の実際のバイナリデータを格納します。
テーブルにInnoDB
ストレージENGINE
を使用して、MySQLトランザクションを含む幅広い機能をサポートしました。 products
テーブルを作成するためにこれを実行すると、次の出力が表示されます。
OutputQuery OK, 0 rows affected (0.03 sec)
MySQLサーバーからログアウトします。
- QUIT;
次の出力が得られます
OutputBye
これで、products
テーブルに商品の画像を含むいくつかのレコードを保存する準備が整いました。次のステップで、いくつかの商品をテーブルに入力します。
ステップ2—データベースに接続してデータを取り込むためのPHPスクリプトを作成する
このステップでは、ステップ1で作成したMySQLデータベースに接続するPHPスクリプトを作成します。 スクリプトは3つのサンプル製品を準備し、それらをproducts
テーブルに挿入します。
PHPコードを作成するには、テキストエディタで新しいファイルを開きます。
- sudo nano /var/www/html/config.php
次に、ファイルに次の情報を入力し、PASSWORD
を手順1で作成したtest_user
パスワードに置き換えます。
<?php
define('DB_NAME', 'test_company');
define('DB_USER', 'test_user');
define('DB_PASSWORD', 'PASSWORD');
define('DB_HOST', 'localhost');
$pdo = new PDO("mysql:host=" . DB_HOST . "; dbname=" . DB_NAME, DB_USER, DB_PASSWORD);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
ファイルを保存して閉じます。
このファイルでは、4つのPHP定数を使用して、ステップ1で作成したMySQLデータベースに接続しました。
-
DB_NAME
:この定数は、test_company
データベースの名前を保持します。 -
DB_USER
:この変数はtest_user
ユーザー名を保持します。 -
DB_PASSWORD
:この定数は、test_user
アカウントのMySQLPASSWORD
を格納します。 -
DB_HOST
:これはデータベースが存在するサーバーを表します。 この場合、localhost
サーバーを使用しています。
ファイルの次の行は、PHP Data Object (PDO)を開始し、MySQLデータベースに接続します。
...
$pdo = new PDO("mysql:host=" . DB_HOST . "; dbname=" . DB_NAME, DB_USER, DB_PASSWORD);
...
ファイルの終わりに向かって、いくつかのPDO属性を設定しました。
ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION
:この属性は、デバッグ目的でログに記録できる例外をスローするようにPDOに指示します。ATTR_EMULATE_PREPARES, false
:このオプションは、MySQLデータベースエンジンにPDOの代わりに準備を行うように指示することでセキュリティを強化します。
次に作成する2つのPHPスクリプトに/var/www/html/config.php
ファイルを含めて、それぞれレコードを挿入および取得します。
まず、製品テーブルにレコードを挿入するための/var/www/html/insert_products.php
PHPスクリプトを作成します。
- sudo nano /var/www/html/insert_products.php
次に、次の情報を/var/www/html/insert_products.php
ファイルに追加します。
<?php
require_once 'config.php';
$products = [];
$products[] = [
'product_name' => 'VIRTUAL SERVERS',
'price' => 5,
'product_image' => file_get_contents("https://i.imgur.com/VEIKbp0.png")
];
$products[] = [
'product_name' => 'MANAGED KUBERNETES',
'price' => 30,
'product_image' => file_get_contents("https://i.imgur.com/cCc9Gw9.png")
];
$products[] = [
'product_name' => 'MySQL DATABASES',
'price' => 15,
'product_image' => file_get_contents("https://i.imgur.com/UYcHkKD.png" )
];
$sql = "INSERT INTO products(product_name, price, product_image) VALUES (:product_name, :price, :product_image)";
foreach ($products as $product) {
$stmt = $pdo->prepare($sql);
$stmt->execute($product);
}
echo "Records inserted successfully";
ファイルを保存して閉じます。
このファイルには、上部にconfig.php
ファイルが含まれています。 これは、データベース変数を定義してデータベースに接続するために作成した最初のファイルです。 このファイルはまた、PDOオブジェクトを開始し、それを$pdo
変数に格納します。
次に、データベースに挿入する製品のデータの配列を作成しました。 文字列と数値としてそれぞれ用意されているproduct_name
とprice
とは別に、スクリプトはPHPに組み込まれているfile_get_contents
関数を使用して、外部ソースから画像を読み取り、パスします。それらをproduct_image
列への文字列として。
次に、SQLステートメントを準備し、PHPforeach{...}
ステートメントを使用して各製品をデータベースに挿入しました。
/var/www/html/insert_products.php
ファイルを実行するには、次のURLを使用してブラウザウィンドウで実行します。 your-server-IP
をサーバーのパブリックIPアドレスに置き換えることを忘れないでください。
http://your-server-IP/insert_products.php
ファイルを実行すると、レコードがデータベースに挿入されたことを確認する成功メッセージがブラウザに表示されます。
これで、商品画像を含む3つのレコードがproducts
テーブルに正常に挿入されました。 次のステップでは、これらのレコードを取得してブラウザに表示するためのPHPスクリプトを作成します。
ステップ3—MySQLデータベースからの製品情報の表示
データベース内の製品の情報と画像を使用して、ブラウザーのHTMLテーブルに製品の情報を照会して表示する別のPHPスクリプトをコーディングします。
ファイルを作成するには、次のように入力します。
- sudo nano /var/www/html/display_products.php
次に、次の情報をファイルに入力します。
<html>
<title>Using BLOB and MySQL</title>
<body>
<?php
require_once 'config.php';
$sql = "SELECT * FROM products";
$stmt = $pdo->prepare($sql);
$stmt->execute();
?>
<table border = '1' align = 'center'> <caption>Products Database</caption>
<tr>
<th>Product Id</th>
<th>Product Name</th>
<th>Price</th>
<th>Product Image</th>
</tr>
<?php
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
echo '<tr>';
echo '<td>' . $row['product_id'] . '</td>';
echo '<td>' . $row['product_name'] . '</td>';
echo '<td>' . $row['price'] . '</td>';
echo '<td>' .
'<img src = "data:image/png;base64,' . base64_encode($row['product_image']) . '" width = "50px" height = "50px"/>'
. '</td>';
echo '</tr>';
}
?>
</table>
</body>
</html>
ファイルへの変更を保存して閉じます。
ここでも、データベースに接続するためにconfig.php
ファイルをインクルードしました。 次に、PDOを使用してSQLステートメントを準備して実行し、SELECT * FROM products
コマンドを使用してproducts
テーブルからすべてのアイテムを取得しました。
次に、HTMLテーブルを作成し、PHPwhile() {...}
ステートメントを使用して製品のデータを入力しました。 行$row = $stmt->fetch(PDO::FETCH_ASSOC)
はデータベースにクエリを実行し、結果を多次元配列として$row
変数に格納します。この変数は、$row['column_name']
構文を使用してHTMLテーブル列に表示されます。 。
product_image
列の画像は、<img src = "">
タグで囲まれています。 width
属性とheight
属性を使用して、HTMLテーブルの列に収まるサイズに画像のサイズを変更しました。
BLOB
データ型が保持するデータを画像に戻すために、組み込みのPHP base64_encode
関数と、
data:media_type;base64, base_64_encoded_data
この場合、image/png
はmedia_type
であり、product_image
列のBase64
でエンコードされた文字列はbase_64_encoded_data
です。
次に、次のアドレスを入力して、Webブラウザでdisplay_products.php
ファイルを実行します。
http://your-server-IP/display_products.php
ブラウザでdisplay_products.php
ファイルを実行すると、製品と関連画像のリストを含むHTMLテーブルが表示されます。
これにより、MySQLから画像を取得するためのPHPスクリプトが期待どおりに機能していることが確認されます。
結論
このガイドでは、MySQL BLOB
データ型を使用して、Ubuntu18.04でPHPを使用して画像を保存および表示しました。 また、ファイルシステムに画像を保存するのではなく、データベースに画像を保存することの基本的な利点も確認しました。 これらには、移植性、セキュリティ、およびバックアップの容易さが含まれます。 学生のポータルや従業員のデータベースなど、情報と関連する画像を一緒に保存する必要があるアプリケーションを構築している場合、このテクノロジーは非常に役立ちます。
MySQLでサポートされているデータ型の詳細については、MySQLデータ型ガイドに従ってください。 MySQLとPHPに関連するその他のコンテンツに興味がある場合は、次のチュートリアルを確認してください。