Posts 1. LAMPのインストール
Post
Cancel

1. LAMPのインストール

OS(CentOS7—XWindow付き)のインストール

MacにしろWindowsにしろ、そのOSに直接開発環境全てをインストールすることはできますが、別の環境が必要になったりすると面倒ですし(可能ですが)、これが増えてくると管理も大変になります。また、多くのサーバーがLinuxということもあり、やはり、VirtualBoxにLinuxをインストールする方が良さそうです。

ではLinuxのディストリビューションは何が良いか?Ubuntuがインストールが簡単で良いのですが、やはり使われている数とかを考えると無難なところでCentOSでしょうか。現在バージョン7が出ており、今回はこれを利用します。Macを例にしていますが、ほぼWindowsの場合でも同じです。

VirtualBoxのインストール

http://www.oracle.com/technetwork/server-storage/virtualbox/downloads/index.html?ssSourceSiteId=otnjp

に行って、最新のものをダウンロード、dmgファイルがダウンロードされるので、これをダブルクリックしてマウント。pkgファイルをダブるクリックして、インストールします。

CentOSのDVDイメージ(ISOファイル)のダウンロード

http://isoredirect.centos.org/centos/7/isos/x86_64/CentOS-7-x86_64-DVD-1503-01.iso

に行って、適当なミラーからダウンロード。ファイルサイズが大きいので、気長に待ちます。

CentOS7のインストール

準備

いよいよインストール開始ですが、まずはVirtualBoxの設定を行います。

  1. VirtualBoxの起動する。 VirtualBoxコントロール画面
  2. 新規をクリック。 新規をクリックするとウィザードが始まる。
  3. OS選択で以下のようにする 名前を適当に付けて(ここでは「CentOS7」)、タイプは「Linux」、バージョンはRedHatを選択します OS選択画面
  4. メモリーは、とりあえず1024M(後から増やせるので)にする。
  5. ハードドライブは「仮想ハードドライブを作成」を選択する。 ハードドライブ
  6. ハードドライブのファイルタイプは、デフォルトの一番上のVDIを選択する。 ハードドライブのタイプ
  7. 固定サイズを選択し、16Gにする。←そうしないと足らなくなる可能性があります。 フォーマットをするので、しばし待ちます。

これで、ウィザードが終わります。

次に、先ほどダウンロードしたCentOSのDVDイメージを起動させる必要があります。

起動ボタンをクリック

  1. 起動ボタンをクリックします。 ※マウスカーソルが、時々、ホストのMacに戻らなくなったら、落ち着いて、Commandキーを押すと大丈夫ですw
  2. すると、なんだか選べという画面が出るので、そこで先ほどダウンロードしたDVDイメージを、右の方にある緑の上矢印で選択して、startをクリックして次へ進みます(若干警告が出ますが無視w)。 ISOの選択
  3. 言語を選択する画面が出るので、日本語を選択します。 言語の選択
  4. インストールの概要画面で、ネット環境とインストールするものを選択します(下に警告が出てますが、これはHDDの容量が足らなかった、つまり、デフォルトの8Gだったときに出た警告で、今回のように16Gの場合は問題ありません)。 インストールの概要
    • ネットワークとホストをクリックして、イーサーネットをOnにします。 ネットワークとホスト
    • ソフトウェアの選択画面では、無駄も多いですが、何がどれだけ必要なのかわからない場合は一番下の「開発およびクリエイティブワークステーション」を選択し、右側のチェックマークは全てチェックしてしまいましょう(もちろん、GUIなど必要がないとか、Apacheなんて自分でコンパイルするというような人は別です—というかそういう人はこのページを見ていないでしょうが・・・w)。 言語の選択
  5. 「!」マークが消えたら(「インストール先」は最初!がついていますが、クリックして、戻ってくるだけで消えます)、インストールが開始されます。
  6. この間に、rootのパスワードと、ユーザーを作成しておきましょう(パスワードが弱いとか言われる場合がありますが、無視できますw)。ユーザーはログインの時にユーザー名とパスワードを利用しますので、覚えておきましょう。

これでインストールは完了されるはずです。

Guest Additionsのインストール

CentOSが立ち上がると、若干言語のこととか聞いてきますが、とりあえずOKし、使用を開始します。

  1. インストール中に登録したユーザーでログインします。
  2. 左上のメニューの「アプリケーション」→「端末」でターミナルを開きます。 端末
  3. 次にsuコマンドでrootになります(インストール中登録したパスワードを入れてください)。
  4. 「Command」押して、CentoOSからマウスを逃がします(これが面倒なので、現在Guest Additionsのインストールしています)。そして、VirtualBoxのメニューから 「devise」→(一番下の)Insert Guest Additions ISO imagesを選択します。 Guest Additions1
  5. そうすると、CentOSがDVDに気づいて、自動起動するかどうか聞いてくるので、OKすると勝手にインストールが始まります。 Guest Additions2
  6. Guest Addtionsのisoを選んだときと同じ「devise」で、 devise → Shared Clipboard → Bidirectional devise → Drag’n’Drop → Bidirectional

インストールが終わったらCentOSを再起動させると、マウスがCentOSに取られちゃうことはなくなるし、MacとCentOS間でコピー&ペーストができるようになります。

ネットに繋がっているか確認

まずは右上にコンピューターのアイコンがあるので、そこに「×」がないか確認します。私の場合×があったのですが、クリックして、有線をOnにするとつながるようになりました。

nslookコマンドを使って、www.google.comのIPアドレスを問い合わせて大丈夫かどうかを確認しましょう。さっきのターミナルで

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[chikkun@localhost ~]$ nslookup www.google.com
Server:		192.168.0.111
Address:	192.168.0.111#53

Non-authoritative answer:
Name:	www.google.com
Address: 74.125.203.106
Name:	www.google.com
Address: 74.125.203.147
Name:	www.google.com
Address: 74.125.203.99
Name:	www.google.com
Address: 74.125.203.103
Name:	www.google.com
Address: 74.125.203.104
Name:	www.google.com
Address: 74.125.203.105

[chikkun@localhost ~]$ 

と問い合わせると、↑のような回答が返されます。

PHPでHello World

とりあえず、ApacheとPHPはインストールされているはずなので、確認してみましょう。

インストールはされていますが、立ち上がってはいないので、端末の中で(rootになっていなければ、また、suでなってから)

1
2
3
[chikkun@localhost ~]$ su
パスワード:
[root@localhost chikkun] systemctl start httpd

で立ち上げます。

そして、CentOSのデスクトップの左上にある「アプリケーション」メニューからFirefoxを選択し、立ち上げます。

そして、URLのところに「localhost」を入力して、リロードすると「Testing 123..」とかいう、下のような画面が出ればApacheは動作しています。

Apache

次にPHPがしっかりApacheと連動しているかを確認します。

おきまりの「phpinfo();」だけのプログラムです。

rootになっているterminal(端末)上で、

1
[root@localhost chikkun] gedit&

を打ち込むと、エディタが立ち上がります。

rootじゃないと書き込み権限がないから、先ほどrootになってからgeditを立ち上げます。

ここに

1
2
3
    <?PHP
        phpinfo();
    ?>

と書き込んで、

1
/var/www/html/info.php

として、保存します。

そして、先ほどのFireFoxで、http://localhost/info.php と打ち込んで、次のような画面が出れば、PHPも大丈夫ですね。

phpinfo



OS(CentOS7—XWindowなし—最小インストール)のインストール

CentOSをデフォルトでインストールすると最小インストールとなります。これはXWindow等もない、シェルが立ち上がるだけの非常にシンプルなLinuxがインストールされます。

これを通常のデスクトップとして使うには厳しいですが、サーバーではXWindow等は必要ない上に、メモリーも食うし、通常はこれがデフォルであるのは、ある意味、正しい気がします。

そこで、最小インストールでPHPで「Hello World」を出力するところまでを記します。

ただ、最初にCentOSを立ち上げるところまでは同じなので、それ以降を記します(ただしHDDの容量は8Gで十分なので、デフォルトのままの「可変サイズ」でOKです)。

インストールの概要(ISOから初めて立ち上げたところから)

最初の言語の選択は「日本」にして、次のインストールの概要ではデフォルトの最小インストールでいきます。ただし、オプションのチェックマークは全て付けておきましょう(コンパイラーや後述するSSHとかが入るので)。

最小インストール

ネットワークの設定

ネットワークが使えないと困るので、とりあえず、インストール途中に出てくる次のような画面右上のトグルをOnにして、次の4つを設定します(今回はDHCPではありません)。

  1. アドレス→192.168.0.99 そのLAN内のものとぶつからないIPアドレス(通常、99とか101とかだったら大きな所じゃなきゃ大丈夫だと思う・・・)
  2. ネットマスク→255.255.255.0(とりあえず)
  3. ゲートウェイ→192.168.0.1(これは環境によるが、家庭の中ですと通常はルーターのアドレス)
  4. DNSサーバー→192.168.0.1(これも環境によるが、家庭の中ですとルーターのアドレス)

※ ルーターのIPアドレスが「192.168.1.1」だったりすると、同じネットワークにするために「192.168.1.99」とかにします。

ネットワークの設定

このままインストールが終わって、立ち上げ直すと次のようなターミナルが立ち上がります。

シェル

ネットワークの設定2

とりあえずネットに繋がるか試すためにpingしてみる(「ping 192.168.0.1」を実行)と、あれれ、つながっていません。

1
Destination Host Unreachable

とか出ています

そこで一度シャットダウンさせて(shutdown -h now)、VirtualBoxの設定画面のネットワークで

ネットワークの設定2

というように、ブリッジアダプターを選択します。

そして、再度立ち上げて再度pingをしてみると、次のようにつながりました。

pingが通らない

ふう、よかったw

一応外にも行けているか確認するために、wgetをインストールして、googleのhtmlを取ってきてみましょう。

1
2
3
4
[root@localhost root] yum -y install wget
...
[root@localhost root] wget www.google.co.jp
...

どうやら、index.htmlが作成されて、しっかり取ってきたようです。

ちょっぴり準備

開発環境ではあまりセキュリティ的に高くするのは何かと不便なので、SELinux等の設定を変えておきます。まずはエディタは、私的にはviがダメなので(使えない)、emacsをインストールします。

1
[root@localhost root] yum -y install emacs

※emacsは終わらせるのにも困るという話があるので、普通に編集したら最後に「C-x C-s」で保存し、「C-x C-c」(コントロールキーを押しながらx、続けてコントロールキーを押しながらcとかsです)すると、保存と終了ができます。

さて、このエディタを使ってSELinux設定を変えておきます。

  1. SELinux無効設定 何かと不便なSELinuxを向こうにします。
    1
    
    [root@localhost root] emacs /etc/sysconfig/selinux
    

    で、 —変更———————— SELINUX=enforcing ↓ SELINUX=disabled —————————— とします。

  2. firewalldの停止 firewallはサーバーには必須ですが、とりあえず、ここでは確認を容易にするために停止しておきましょう。
    1
    2
    3
    
       systemctl stop firewalld
       systemctl status firewalld
       systemctl disable firewalld
    

とりあえず、SELinuxの設定を反映させるのに、リブートしておきます。

LAMP

いよいよLAMPです。

L(Linux)は終わっているので、Apache、MySQL, PHPをインストールします。

まずは、リポジトリーを増やしておきます。

1
2
3
4
5
6
7
8
9
10
11
12
rpm -ivh http://pkgs.repoforge.org/rpmforge-release/rpmforge-release-0.5.3-1.el7.rf.x86_64.rpm
rpm --import http://dag.wieers.com/rpm/packages/RPM-GPG-KEY.dag.txt

rpm -ivh http://dl.fedoraproject.org/pub/epel/7/x86_64/e/epel-release-7-5.noarch.rpm

rpm --import http://dl.fedoraproject.org/pub/epel/RPM-GPG-KEY-EPEL-7

rpm -ivh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
rpm --import http://rpms.famillecollet.com/RPM-GPG-KEY-remi

rpm -ivh http://dev.mysql.com/get/mysql-community-release-el7-5.noarch.rpm

remiレポジトリーの設定を変えておきます。

1
2
3
4
5
6
7
8
9
10
11
emacs /etc/yum.repos.d/remi.repo

    ---変更------------------------
    [remi]
    name=Les RPM de remi pour Enterprise Linux 7 - $basearch
    #baseurl=http://rpms.famillecollet.com/enterprise/7/remi/$basearch/
    mirrorlist=http://rpms.famillecollet.com/enterprise/7/remi/mirror
    enabled=0
    ↓
    enabled=1
    ------------------------------

です。

MySQL

さてさて、まずはMySQL。

>yum -y install mysql mysql-server mysql-devel

これでインストールは終了。

とりあえず、my.cnfの[mysqld]セクションに「character-set-server=utf8」を書き込みます。

1
2
3
[mysqld]
#....
character-set-server=utf8

そして、

>systemctl enable mysqld systemctl start mysqld

で立ち上げます。

そして、mysql_secure_installation を実行します。

>mysql_secure_installation

最初はroot(mysql)のパスワードを聞いてきますが、最初は空文字なので、そのままリターンして、新しいパスワードを設置します。あとはデフォルトでリターンでとりあえずはOKでしょう。

PHP & Apache

最後はPHPとApacheです。

>yum -y install httpd httpd-devel # Apache yum -y php php-devel php-pdo php-mysql php-mbstring

インストールはこれで終了。

あとは自動起動の設定とと起動です。

>systemctl enable httpd systemctl start httpd

ここからはGUIバージョンと同じです。インストール時に使ったアドレス(IP—今回は192.168.0.99なのでhttp://192.168.0.99にアクセスすることになります)にアクセスして、Apacheの画面が出現すればOKです。これはもちろん、ホスト(Mac)のSafari等でアクセスするということです。

そして、同様にinfo.phpをドキュメントルート(/var/www/html/info.php)に「phpinfo();」を書き込んで、phpinfoの出力画面が出現すればOKです。

おまけ1—sshでログイン

terminalだけのインストールの場合Guest Additionsをインストールしても、OS間のコピペができません。マウスが奪われる件も解消されません。

これは以外に不便です。例えば、Google先生に聞いて教えてもらっても、結構長いコマンドをコピペできず、手作業で打ち込む必要があります(だから覚えるという意見もありそうですが)。

ただ、最小インストールでもオプションでセキュリティツールとかをチェックしたからかもしれませんが、sshd(サーバー)がすでにインストールされているようです(CentOSインストール最初のチェックマークをチェックしていればです)。そこで、自動実行と現在のデーモンの立ち上げを行います(CentOS側の作業)。

>systemctl enable sshd systemctl start sshd

これで、sshのクライアントで「Mac→CentOS」へsshでログインします。Macだと始めからインストールされています。もし、Windowsなら PoderosaとかPuttyとかをインストールしてから、ターミナルを開いて同様のことを行ってください。

Macのシェルを立ち上げて(その他→ターミナル)、

>ssh -l chikkun 192.168.0.99
1
2
The authenticity of host '192.168.0.99 (192.168.0.99)' can't be established.
RSA key fingerprint is xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx

とか聞かれますが、yesと打ち込んでリターン。ちなみにchikkunはインストール時に作成したユーザー名。後はパスワードを入力して、ログインが完了します。

これによって、コピペーができるし、マウスを奪われたりしなくなります。

つまり、VirtualBoxで立ち上がったシェルで作業するのではなく、sshでログインした方のシェル(つまりMacのターミナル)で、作業するとちょっと便利かも、と言う話です。

おまけ2—LAMPを使った、超単純な住所録アプリ(認証すらない版)

databaseの作成

とりあえずMySQLのrootのパスワードは作りましたが、ユーザーを作成していないので、作成します。

これからはMacのターミナルからCentOSへsshでログインしたシェルでの作業になります。

とりあえずrootでデータベースを作成します。

>mysql -u root -p

パスワードを聞いてくるのでMySQLのrootのパスワードを入力します。

そして、mysql上で次のようなコマンドを実行します(「– はコメント行です」)。

>-- データベースを作成 create database test_address; -- test_addressを選択 use test_address; -- table addressを作成 DROP TABLE IF EXISTS address; CREATE TABLE address ( id int NOT NULL AUTO_INCREMENT, name varchar(128), address varchar(128), phone varchar(128), fax varchar(128), zip varchar(128), PRIMARY KEY (id) ); -- MySQLのユーザー「chikkun」を作成し、パスワードを「hogehoge」とし、どんなデータベースにもアクセスできるように GRANT ALL PRIVILEGES ON *.* TO chikkun@localhost IDENTIFIED BY 'hogehoge' WITH GRANT OPTION;

Bootstrapのダウンロードと設置

全然必要ないのだけれど、あまりにもちゃちいフォームなのも何なので(scpコマンドの練習もかねて)、

scpとはコンピュータからコンピュータにネットを介してファイルをコピーするコマンドの1つです。今回ホストのMacからゲストのCentOSに(Mac内とはいえ、Virtual的には別のコンピュータなので)コピーするためです。
CentOSでsshdが立ち上がっている必要がありますが、デフォルトで立ち上がっているようです。

http://getbootstrap.com/getting-started/に行って、一番左のボタンでダウンロードします。

zipファイルを解凍すると、「css、fonts、js」の3つのディレクトリがあるので、これをCentOS7のApacheのドキュメントルート(/var/www/html)にscpコマンドを使ってコピーします。

今度はMacのターミナルで、カレントディレクトリーがBootstrapを解凍したところにcdして、作業します。

>cd ~/Donwloads/bootstrap-3.3.4-dist #私はここに解凍したのでここにcd scp -r css root@192.168.0.99:/var/www/html/ scp -r fonts root@192.168.0.99:/var/www/html/ scp -r js root@192.168.0.99:/var/www/html/

ちなみに「-r」はディレクトリーを再帰的にコピーしてねというオプションで、「root@192.168.0.99:/var/www/html/」はIPアドレスが192.168.0.99のコンピュータの/var/www/html/というディレクトリにrootというユーザーで、という意味になります。

rootでscpしているのは、/var/www/htmlというディレクトリへの書き込み権限がないからです。

index.phpの作成

さて、今はPHPを使ってスクラッチ的なプログラムを作っているので、htmlの内容とphpのプログラムが混在しています。いずれCakePHP等のフレームワークを使うとこの辺の分離が可能になりますが、それはもう少し後にしましょう。

というわけで見づらいですが、上と下にphpのプログラムがあります。

>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
<html lang="ja">
<head>
	<meta charset="utf-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<link href='css/bootstrap.min.css' rel='stylesheet'>
	<meta name="description" content="住所登録">
	<title>Testで住所</title>
</head>
<body>

<?php
try {
	$pdo = new PDO('mysql:host=localhost; dbname=test_address', 'chikkun', 'hogehoge', array(PDO::ATTR_EMULATE_PREPARES => false,
		PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',));
} catch (PDOException $e) {
	echo $e->getMessage();
	exit('データベース接続失敗。' . $e->getMessage());
}
if (isset($_POST['name']) && $_POST['name'] != '') {
	$x = htmlspecialchars($_POST['name']);
	$stmt = $pdo->prepare("INSERT INTO address(name, zip, address, phone, fax) VALUES (:name, :zip, :address, :phone, :fax)");
	$stmt->bindParam(':name', $_POST['name'], PDO::PARAM_STR);
	$stmt->bindValue(':zip', $_POST['zip'], PDO::PARAM_STR);
	$stmt->bindValue(':address', $_POST['address'], PDO::PARAM_STR);
	$stmt->bindValue(':phone', $_POST['phone'], PDO::PARAM_STR);
	$stmt->bindValue(':fax', $_POST['fax'], PDO::PARAM_STR);
	$stmt->execute();
	echo "<p>$x を登録しました。</p>";
}
?>
<form action="index.php" method="post">
	<div class="container">
		<div class="row">
			<div class="center-block>"
			<h2>住所管理システム(汗)</h2>
			<div class="form-horizontal">
				<div class="form-group">
					<div class="col-md-1 col-xs-1 right">
						<label for="address">氏名</label>
					</div>
					<div class="col-md-3 col-xs-3">
						<input type="text" id="name" name="name" class="form-control">
					</div>
				</div>
			</div>
			<div class="form-horizontal">
				<div class="form-group">
					<div class="col-md-1 col-xs-1 right">
						<label for="address">郵便番号</label>
					</div>
					<div class="col-md-3 col-xs-3">
						<input type="text" id="zip" name="zip" class="form-control">
					</div>
				</div>
			</div>
			<div class="form-horizontal">
				<div class="form-group">
					<div class="col-md-1 col-xs-1 right">
						<label for="address">住所</label>
					</div>
					<div class="col-md-3 col-xs-3">
						<input type="text" id="address" name="address" class="form-control">
					</div>
				</div>
			</div>
			<div class="form-horizontal">
				<div class="form-group">
					<div class="col-md-1 col-xs-1 right">
						<label for="address">電話番号</label>
					</div>
					<div class="col-md-3 col-xs-3">
						<input type="text" id="phone" name="phone" class="form-control">
					</div>
				</div>
			</div>
			<div class="form-horizontal">
				<div class="form-group">
					<div class="col-md-1 col-xs-1 right">
						<label for="address">FAX番号</label>
					</div>
					<div class="col-md-3 col-xs-3">
						<input type="text" id="fax" name="fax" class="form-control">
					</div>
				</div>
			</div>
		</div>
	</div>
	</div>
	<div class="col-md-2 col-md-offset-1 col-xs-2 col-xs-offset-1">
		<input type="submit" value="登録" class="btn btn-sm btn-primary">
	</div>
</form>
<div class="center-block">
	<div class="col-md-6 col-xs-6">
<?php
		$stmt = $pdo->query("SELECT * FROM address ORDER BY id DESC");
		$n = 0;
		while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
			$n++;
			if ($n == 1) {
				echo '<table class="table bordered striped" >';
				echo '<table class="table table-striped table-bordered" >';
				echo "<th>氏名</th><th>郵便番号</th><th>住所</th><th>電話番号</th><th>FAX番号</th>\n";
			}
			echo "<tr>\n";
			echo "<td>" . $row["name"] . "</td>\n";
			echo "<td>" . $row["zip"] . "</td>\n";
			echo "<td>" . $row["address"] . "</td>\n";
			echo "<td>" . $row["phone"] . "</td>\n";
			echo "<td>" . $row["fax"] . "</td>\n";
			echo "</tr>\n";
		}
		if ($n != 0) {
			echo "</table>\n";
		}
?>
	</div>
</div>
</body>
</html>

これで一応、登録して、下の方に登録されたレコードが表示されるようになります。

軽く説明

最初のphpのところ

>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
try {// A
	$pdo = new PDO('mysql:host=localhost; dbname=test_address', 'chikkun', 'hogehoge', array(PDO::ATTR_EMULATE_PREPARES => false,
		PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8',)); // B
} catch (PDOException $e) {
	echo $e->getMessage();
	exit('データベース接続失敗。' . $e->getMessage());
}
if (isset($_POST['name']) && $_POST['name'] != '') {// C
	$stmt = $pdo->prepare("INSERT INTO address(name, zip, address, phone, fax) VALUES (:name, :zip, :address, :phone, :fax)");// D
    
    $stmt->bindParam(':name', $_POST['name'], PDO::PARAM_STR); // E
	$stmt->bindValue(':zip', $_POST['zip'], PDO::PARAM_STR);
	$stmt->bindValue(':address', $_POST['address'], PDO::PARAM_STR);
	$stmt->bindValue(':phone', $_POST['phone'], PDO::PARAM_STR);
	$stmt->bindValue(':fax', $_POST['fax'], PDO::PARAM_STR);
	$stmt->execute(); // F
	echo "<p>$x を登録しました。</p>";
}
?>
  1. A(1行目)から始まるの「try〜catch」はtryブロック(「{」と「}」の間)でエラーが起こったら、catchブロックに飛んで、何らかの処理をするというもの。例外が出る可能性のあるところでは、頻繁にみかけるものです。

  2. Bの1行(3行~4行はプログラム的には1行)は長いけれど、PDO(データベースに接続するためのPHPのオブジェクト)をnew(インスタンス化)しています。引数にホストやデータベース名、ユーザーやパスワードを指定しています。マニュアルには下のようにあります。ここでデータベースサーバーに接続して、SQLを発行する準備ができるわけです。

    1
    2
    3
    4
    
    PDO PDO::__construct ( string dsn 
                           [, string username 
                           [, string password 
                           [, array driver_options]]] )
    
  3. C(9行目)のissetは、その変数に値がセットされているかどうかをチェックする関数(NULL以外がセットされていたらtrueになる)。なので、ここでは「フォームから受けとるnameというパラメータの値があった場合は」ということで、保存ボタンを押したかどうかの判断の基準にもなっています。つまり、名前が入力されていないと登録しません(厳密には関数ではありませんが、ここでは無視しましょう)。
  4. D(10行目)はステートメント(最終的にはSQL文になる)を作成しています。つまり、「INSERT INTO ….」というSQLを発行する準備をしているということになります。まだ、値をセットしていないので、ここではあくまでもSQL分のひな形を作っているという感じです。文字通りprepare(準備)しているわけです。
  5. E(12行目)からの5行は、4で作成したステートメントに実際の値をアサイン(代入)しているものです。

    1
    
    $stmt->bindParam(':name', $_POST['name'], PDO::PARAM_STR);
    

    ステートメント内の「:name」にポストでやってきた$_POST[‘name’]の値をアサインして、型はPDO::PARAM_STR(文字列)だよとステートメントに教えている感じです。 F(17行目)の

    1
    
    $stmt->execute();
    

で、実際のSQLを実行しています。これでフォームから受けとったデータを元にレコードを登録したことになります。

後半にあるPHPのコード

>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
		$stmt = $pdo->query("SELECT * FROM address ORDER BY id DESC");// A
		$n = 0;
		while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {// B
			$n++;
			if ($n == 1) {// C
				echo '<table class="table bordered striped" >';
				echo '<table class="table table-striped table-bordered" >';
				echo "<th>氏名</th><th>郵便番号</th><th>住所</th><th>電話番号</th><th>FAX番号</th>\n";
			}
			echo "<tr>\n";// D
			echo "<td>" . $row["name"] . "</td>\n";
			echo "<td>" . $row["zip"] . "</td>\n";
			echo "<td>" . $row["address"] . "</td>\n";
			echo "<td>" . $row["phone"] . "</td>\n";
			echo "<td>" . $row["fax"] . "</td>\n";
			echo "</tr>\n";
		}
		if ($n != 0) {// E
			echo "</table>\n";
		}
?>
  1. A(2行目)は前のステートメントとは違い、prepareじゃなくqueryを使っています。addressテーブルから全データを取得し、ソート的には登録の逆順にしています。これは準備せずに即実行するイメージで、データベースから登録されているデータを全て取ってきています。
  2. B(4行目)は取得したデータ分だけ繰り返されるwhile文です。「(PDO::FETCH_ASSOC)」はレコードを連想配列に格納してね、と頼んでいる部分です。つまり次の$row[“name”]というように取得したい、と主張しているわけです(ただの配列で取得したりもできます)。
  3. C(6行目)は最初のレコードの時tableタグを出力しています。
  4. D(11行目)のあとは出てきたレコードを順繰りに出力させて、trタグやtdタグで囲んでいます。
  5. E(19行目)ではレコードが見つかったときだけ、tableタグの閉じタグを出力しています。

課題としては

  1. 値が何も入れないでも、登録できちゃう(名前以外)。
  2. 電話番号や郵便番号に数字じゃないのも入れられちゃう。
  3. 現在128文字までしかテーブルに格納できないのに、128文字以上のものも受け付けちゃう。
  4. 名前とかにJavaScriptのタグなども、そのまま登録されちゃうので、攻撃を受ける可能性がある。
  5. リロードすると、さっき登録したのが再度登録できちゃう。
  6. 編集ができない。
  7. ログインさせないと勝手にみんなに登録されちゃう。

1〜4まではバリデート(値検証)で、5はリロード対策。6は当然できる必要があるけれど、登録ができたら、更新はそう難しくないでしょう。7は大きな課題かも。

上記の課題をクリアするためには、PHP基本—変数あたりから勉強していく必要があるでしょうw

シェア
#内容発言者

2モデル間の多:多関連

2.変数

坂井和郎