PHP/データベースとの連動

出典: フリー教科書『ウィキブックス(Wikibooks)』
< PHP
ナビゲーションに移動 検索に移動

PHPのプログラム側から、データベースのMySQL(mariaDBでも可)にアクセスできる。

手法[編集]

XAMPP や phpmyadmin などのツールがなくても、標準状態の Linux での Apache, mySQL(mariaDB) とPHP だけでも 、下記のようにPHPをデータベースと連動できます。(2020年4月25日に Fedora 32 などで確認。)

Linux の場合[編集]

mysqli_connect の場合[編集]

まず、mysqli_connect という組み込み関数を使うが、しかし、初期設定では mysqli_connect がインストールされていないので、

sudo dnf install php-mysqlnd 

でインストールする(Fedora の場合)。

さて、 まず、PHP の先の起動よりも先に、 MySQL と Apache(httpd) をそれぞれ起動しておく必要がある。

$ systemctl start mariadb
$ systemctl start httpd

もし先にPHPを起動していたら、MySQLおよびApacheの起動後に、PHPをいったん終了してから、再度にPHPを起動しなおす(でないと、のちの mysqli_connect 関数による MySQL 接続時にエラーになる)。


なお、MySQLとApacheの詳しい操作の解説についてはwikibooks『CGI』および『MySQL』を参照のこと。


PHPには、コマンドラインから使える対話型シェルというのがあるので、まずこの対話型シェルでデータベース接続を試すのがラクである。

Linux側のコマンド端末で、

$ php -a

で、対話型シェルを起動できる。(なおWindows版も同様のコマンドで対話型シェルを起動できる。以降の説明ではLinuxの場合について説明する。なぜならWindowsで滅多にデータベースまで使わないので。)

起動後の表示は、

[ユーザー名@localhost ~]$ php -a
Interactive shell

php > 

のように「Interactive shell」と出る。

シェルを終了するには quit または exit で終了できる。(Windows版もLinux版も同様のコマンド。)


起動できる事が分かったら、いったん exit などでログアウトして sudo コマンドを使ってrootユーザーとしてPHPを起動しなおす。(でないと、あとで、mySQL側からアクセス拒否されるのが通常なので。なお、そのエラーの場合、おそらく PHP Warning: Uncaught Error: Call to undefined function mysqli_connect() in php shell code:1 というエラーメッセージが出ることになるだろう。)

$ sudo php -a

のように、単にsudoを先につければ、rootユーザーとしてPHPを起動できるので、それを実行しよう。

さて、sudo で起動できたら、次に

php > mysqli_connect('localhost',"root","","既存のデータベース名" );

の書式で、MySQLにPHP側からアクセスできる。(プログラマーで手で入力するのは PHP > 以降の部分。)

なお、第3引数はパスワードだが、MySQLの初期設定では通常、パスワードが無いので、その場合は空白で良い。

※ むかし、mysql「i」の 「i」がついてない関数があったが、これは古い関数で、2020年現在の mysqli_ 系(iつき)の関数とは互換性が無いのでエラーになる。(そもそも、もはやi無しの関数はPHPに未登録。)


なお、もし sudo のrootユーザーとしてPHPを起動していないと、上記の mysqli_connect をしてもアクセス権が無いという理由で MySQL から接続拒否されるので

PHP Warning:  mysqli_connect(): (HY000/1698): Access denied for user 'root'@'localhost' in php shell code on line 1

のようにエラーメッセージが出る。


さて、接続できることが分かったら、次のように、なんらかの変数($conの部分)を定義して、接続しなおす。今後の関数で、mysqli系の関数では、この変数を利用する必要があるので。(関数の利用する際、どの接続に対する関数であるかを、mysqliなどiつき関数では引数で指定する仕組みになっているので。)

$con = mysqli_connect('localhost',"root","","testmysql" );


クエリ(データベースへの命令送信)は、次のように送る。

mysqli_query($con,  'select * from testTable');

mysqli_query では第1引数で、どの接続かを指定する必要がある。第2引数は、送信したいクエリ内容で、引用符で くくる必要がある。(なお、iなしの古いバージョンの関数では、引数の順序が違っているので、混同しないように。)


PHPファイルで実行する場合[編集]

MySQLにアクセスするPHPファイルの場所は、ホームフォルダで良い。(わざわざドキュメントルート /var/www/html にコピーしなくてもいい)


コード例
<?php
	$con = mysqli_connect('localhost',"root","","testmysql" );
	$res = mysqli_query($con,  'select * from testTable');
	$data = mysqli_fetch_array($res);
	
	echo "番号:" . $data["gensobangou"] ."\n"  ;
	echo "元素名:" . $data["gensomei"] ."\n"  ;
	echo "記号:" . $data["gensokigou"] ."\n"  ;
	
?>


実行方法

先に、MySQL側で作っておく。本コード例のデータベースは wikibooks『MySQL』で作成したものを流用した。

起動方法では、コマンド端末で sudo ユーザーで起動することで実行する必要がある(root以外だとアクセス拒否されるので)。たとえばファイル名が「conPhp.php」なら

sudo php conPhp.php

のようにコマンド実行する必要がある。

もし sudo 以外で起動しても、アクセス拒否されてしまう。( PHP Warning: mysqli_connect(): (HY000/1698): Access denied for user 'root'@'localhost' in /home/sujiniku/conPhp.php on line 2 )

実行例
番号:1
元素名:Hydrogen
記号:H


2列目以降のデータを読みとりたいなら、

<?php
	$con = mysqli_connect('localhost',"root","","testmysql" );
	$res = mysqli_query($con,  'select * from testTable');
	
	
	$data = mysqli_fetch_array($res);
	
	echo "番号:" . $data["gensobangou"] ."\n"  ;
	echo "元素名:" . $data["gensomei"] ."\n"  ;
	echo "記号:" . $data["gensokigou"] ."\n"  ;
	
	$data = mysqli_fetch_array($res);
	
	echo "番号:" . $data["gensobangou"] ."\n"  ;
	echo "元素名:" . $data["gensomei"] ."\n"  ;
	echo "記号:" . $data["gensokigou"] ."\n"  ;
	
?>

のように、

$data = mysqli_fetch_array($res);

を繰り返す。

なお echo だけを繰り返しても、前と同じ列を読み取ってしまう(つまり、上述の周期表データの例では、水素Hだけ)。

実行結果
番号:1
元素名:Hydrogen
記号:H
番号:2
元素名:Helium
記号:

PDOの場合[編集]

データベースはMySQL以外のものもあるので、PHPでは、特定のデータベースに依存しない形式のPDOという接続方式もある。

コード例
<?php
	$con = new PDO('mysql:host=localhost;dbname=testmysql;charset=utf8',"root","" );
	$res = $con->query('select * from testTable');
	
	$data = $res->fetch(PDO::FETCH_ASSOC);
	
	echo "番号:" . $data["gensobangou"] ."\n"  ;
	echo "元素名:" . $data["gensomei"] ."\n"  ;
	echo "記号:" . $data["gensokigou"] ."\n"  ;
	
	$data = $res->fetch(PDO::FETCH_ASSOC);
	
	echo "番号:" . $data["gensobangou"] ."\n"  ;
	echo "元素名:" . $data["gensomei"] ."\n"  ;
	echo "記号:" . $data["gensokigou"] ."\n"  ;

?>


実行結果
番号:1
元素名:Hydrogen
記号:H
番号:2
元素名:Helium
記号:


解説

最初にPDOを宣言する際、演算子 new を忘れないようにしよう。この new 演算子が無いと、代入命令との区別ができないためか、エラーになる。

なお、このPDO の new 宣言では、メモリの確保を行っている[1]。そのためか、このnew宣言を先に行ってからでないと、コード中で後述のpdo関連の様々な関数命令を用いる事ができない。

なお、このPDOのnew宣言のように、(おおむねC++登場時および以降の)近代的な命令群や機能など用いるために、new演算子などを用いてメモリ確保する事や、その結果のメモリ確保された領域のことなどを「インスタンス」といいます。


PDO::FETCH_ASSOCのコロン2つの部分(::)はコマンド名の一部なので、変更してはならない。(アロー演算子 -> などに変更しても、認識しない。)

おおまかには fetch(PDO::FETCH_ASSOC) の PDO::FETCH_ASSOC が配列形式の指定。 fetch が変換の命令。

fetch() 命令は、一行ずつ、レコード(データベースの中身の部分)を取得する。


webブラウザからデータベースの読み書き[編集]

webブラウザはどうやっても、root権限にはなれない。しかし、mySQLの初期状態では、ユーザーがrootしか登録されていない。

なので、まずMySQLにユーザーの追加が必要なので、Linuxのログインユーザー名で、MySQLにユーザーを追加する。MySQL起動後に、MySQL端末内で(Gnome端末ではないので注意)

CREATE USER 'ユーザー名'@'localhost';

でMySQLにユーザー登録できる。


まだユーザーを作っただけでは、この新規ユーザーには権限がまったく無い。なので、権限の追加のため grant という命令で(指定ユーザーに権限を)追加する。

GRANT ALL ON *.* TO ユーザー名@localhost;

なお、この例では、すべての権限を与えている。(実務ではセキュリティなどのため、権限は限定的に与えることになる。 例では、今後の操作の簡略化のため、権限をすべて与えることにした。)


コード例
<html>
<head>
<title>サンプル</title>
</head>

<body>

<?php

	$con = mysqli_connect('localhost',"ユーザー名","","testmysql" );
	$res = mysqli_query($con,  'select * from testTable');
	
	
	$data = mysqli_fetch_array($res);
	
	print "番号:" . $data["gensobangou"] ."<br />"  ;
	echo "元素名:" . $data["gensomei"] ."<br />"  ;
	echo "記号:" . $data["gensokigou"] ."<br />"  ;
	
	$data = mysqli_fetch_array($res);
	
	echo "番号:" . $data["gensobangou"] ."<br />"  ;
	echo "元素名:" . $data["gensomei"] ."<br />"  ;
	echo "記号:" . $data["gensokigou"] ."<br />"  ;
	

?>	

</body>
</html>


この上記のコードを、/var/www/html に入れておく。拡張子は .php であることに注意。(コード中に html タグがあるので、ついつい拡張子を html にしてしまいがち)


ブラウザ接続時にwebブラウザの見れる形式に変換するため、あらかじめ Apache(httpd) を起動しておく。

systemctl start httpd

で起動できる。

MySQLサーバーも当然、起動する必要があるので、

systemctl start mariadb

でMySQLサーバーを起動。


そして、webブラウザで

http://localhost/上記コードのファイル名.php

にアクセスすればいい。


実行結果
番号:1
元素名:Hydrogen
記号:H
番号:2
元素名:Helium
記号:
(動作環境など: FireFox75 で2020年4月25日に動作を確認。OS はFedora 32 で同日。)


XAMPPの場合[編集]

主にWindows版の場合について、XAMPPでのMySQL連動について述べる。


まず、連動先のMySQLについては、XAMPPのフォルダ内にあるMySQLにあるデータベースであるという必要がある。

ともかく、何らかの方法で事前に XAMPP 内 MySQL にて、目的のデータベースを保管しておく必要がある(その方法については、mySQl側の説明を待て。ただし現時点(2020年4月26日)ではwikibooksでは未完成)。


さて、とにかくXAMPP内MySQLに目的のデータを保管できたら、あとは単に、上記のコードのphpファイルを、XAMPPのドキュメントルートのフォルダ (初期設定では C:\xampp\htdocs である)に(そのphpファイル)入れれば良い。


念のため、どのphpファイルを入れるのかというと、

<?php

	$con = mysqli_connect('localhost',"ユーザー名","","testmysql" );
	$res = mysqli_query($con,  'select * from testTable');
	
	
	$data = mysqli_fetch_array($res);
	
	print "番号:" . $data["gensobangou"] ."<br />"  ;
	echo "元素名:" . $data["gensomei"] ."<br />"  ;
	echo "記号:" . $data["gensokigou"] ."<br />"  ;
	
	$data = mysqli_fetch_array($res);
	
	echo "番号:" . $data["gensobangou"] ."<br />"  ;
	echo "元素名:" . $data["gensomei"] ."<br />"  ;
	echo "記号:" . $data["gensokigou"] ."<br />"  ;
	

?>	

</body>
</html>

のようなphpファイルであり、このファイルを C:\xampp\htdocs に入れるだけである。


そして、webブラウザで

http://localhost/上記コードのファイル名.php

にアクセスすれば、同様の結果になり、ブラウザを介してアクセスできる。(XAMPP経由の場合、わざわざ新規にデータベース側にアカウント登録の必要が無い)


SQLiteを使う場合[編集]

PHP5.4以降には、標準でSQLite(エスキューライト)という簡易データベースがPHPに付属している。

SQLiteの特徴としては、

サーバーではない。 ※ 一方、MySQLはサーバーなので、ネットワーク設定をすればインターネット越しにMySQLにアクセスする事も可能。
デーモンなどが常駐しない。 ※ どちらかというと、マイクロソフト Office の Access などに近い。
MySQLにはデータ型があった。しかしSQLiteにはデータ型が無い。

などの違いがある。

このため、MySQLにあったデータ型を調べる desc コマンドも、SQLiteには無い。



起動方法

コマンド端末で

$ sqlite3 データベース名

と入力する。

「3」の数字が必要である。(数字を外すと、「bash: sqlite: コマンドが見つかりませんでした...」「コマンド sqlite' を提供するためにパッケージ 'sqlite2' をインストールしますか? [N/y] n」と出てきてしまい、過去バージョンのインストールになってしまう。いまさら過去バージョンは不要。)

たとえば

$ sqlite3 sample.db

など(SQLite公式サイトがこういうデータベース名)のように入力すればいい。

SQLite3が2020年現在の最新バージョンである。もし「3」の代わりに「4」とか「5」とか入れても、コマンドとして認識しない。


とにかく、

[ユーザー名@localhost ~]$ sqlite3 sample.db
SQLite version 3.31.1 2020-01-27 19:55:54
Enter ".help" for usage hints.
sqlite> 

のように表示されるので、

sqlite> 

のあとにコマンドを入れる仕組みである。

終了方法

.exit というコマンドでSQLiteが終了する。ドット記号(.)が冒頭につくのに注意。ドットが無いと終了コマンドとして認識しない。

sqlite> .exit


使い方

sqlite> 

のように表示されれば、あとはSQLコマンドを認識するので、SQLコマンドをいれればいい。

しかし、SQLiteにはデータ型が存在しないなど、MySQLとは若干の違いがあるので、入力するコマンドが若干、異なる。


たとえば

sqlite> create table testTable( gensobangou int,gensomei text,gensokigou text );

のように、入力時にデータ型(int や text など)を書いてもエラーにならないが、しかし、SQLite内部ではデータ型はまったく保存されていない。

よっ、上記コマンドでは、単にテーブルのキー名をそれぞれ入力しているだけである。

sqlite> insert into testTable (gensobangou,gensomei,gensokigou) values(1, "Hydrogen", "H" );

MySQLと同様のコマンドで、キーに値を入力できる。


テーブルの内容を表示するのも、MySQLと同様のコマンドである。つまり、

sqlite> select * from testTable;

と入力すると

1|Hydrogen|H

のように表示する。(※ 2020年5月6日にFedora32で確認。)

なお MySQLと違って、上記コマンドではSQLiteではキー名(gensobangou,gensomei,gensokigou の部分 )を表示しない。

  1. ^ 松浦健一郎『確かな力が身につく PHP「超」入門』、SBクリエイティブ、、、2016年10月3日初版 第1刷 発行、194ページ