プロになるためのPHPプログラミング入門 サンプル環境構築
以下書籍に付属するサンプルの実行環境を構築する。
「プロになるためのPHPプログラミング入門」(ISBN 978-4-7741-4972-1)
環境は以下記事のものを使用
「PHP:プロになるためのPHPプログラミング入門 サンプル環境構築」
PHP:8.3.30
MySQL:8.0.46
「プロになるためのPHPプログラミング入門」(ISBN 978-4-7741-4972-1)
環境は以下記事のものを使用
「PHP:プロになるためのPHPプログラミング入門 サンプル環境構築」
PHP:8.3.30
MySQL:8.0.46
1.5.5 HTML_Template_Flexyとデータベースを組み合わせる (P.64)
検証対象:
・リスト 1-10 p15flexydb.html (P.66)
・リスト 1-11 ppa/p15flexydb.php (P.67)
1. MySQL接続パスワードの変更
2. とりあえずの動作確認
3. PDO MySQLドライバーのインストール
4. エラー 2002
5. エラー 1045
6. エラー 1044
6. とりあえずDB接続はOK
7. PHPソース修正
実行結果:
・リスト 1-10 p15flexydb.html (P.66)
・リスト 1-11 ppa/p15flexydb.php (P.67)
1. MySQL接続パスワードの変更
~/docker/php/prophp_sample/www/ppa/p15flexydb.php (15行目)
2. とりあえずの動作確認
3. PDO MySQLドライバーのインストール
PDO MySQLドライバーが必要かもしれないのでインストールを実施。
PHPコンテナに接続し以下コマンドを実行する。
PHPコンテナに接続し以下コマンドを実行する。
apt-get install php-mysql
4. エラー 2002
エラー発生
データベース接続先が "localhost# になっていた。
今回の環境では PHP と MySQL は別コンテナで、MySQLのコンテナ名は compose.yamlの設定では "db" としていたので "db" へ変更する。
Connect Error: 2002
データベース接続先が "localhost# になっていた。
今回の環境では PHP と MySQL は別コンテナで、MySQLのコンテナ名は compose.yamlの設定では "db" としていたので "db" へ変更する。
$dbh = new PDO('mysql:dbname=ppdb;host=db;charset=utf8mb4',
'ppguest', // DB接続ユーザ
'passwordpassword'); // DB接続パスワード
5. エラー 1045
エラー発生
権限が無いためエラーになっている。
ppguestユーザーで接続しようとしているが、過去記事「PHP:プロになるためのPHPプログラミング入門 サンプル環境構築 4」でユーザーを作成した際 'ppguest'@'localhost' で作成していたので localhost からのアクセスしかできない。
今回は学習用なので、とりあえずすべてOKのユーザーを作成して対応。
権限も付与
Connect Error: 1045
権限が無いためエラーになっている。
ppguestユーザーで接続しようとしているが、過去記事「PHP:プロになるためのPHPプログラミング入門 サンプル環境構築 4」でユーザーを作成した際 'ppguest'@'localhost' で作成していたので localhost からのアクセスしかできない。
今回は学習用なので、とりあえずすべてOKのユーザーを作成して対応。
mysql> create user 'ppguest'@'%' identified by 'xxxx';
Query OK, 0 rows affected (0.01 sec)
権限も付与
mysql> GRANT SELECT ON ppdb.* to 'ppguest'@'%';
Query OK, 0 rows affected (0.01 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.01 sec)
6. エラー 1044
エラー発生
Connect Error: 1044
6. とりあえずDB接続はOK
とりあえず ppPageのエラーに変わったので DB接続はOKと思われる。
Fatal error: Uncaught TypeError: PpPage::display(): Argument #2 ($elem) must be of type array, CcData given, called in /var/www/prophp_sample/www/ppa/p15flexydb.php on line 50 and defined in /var/www/prophp_sample/www/ppa/ppPage.php:26 Stack trace: #0 /var/www/prophp_sample/www/ppa/p15flexydb.php(50): PpPage->display('p15flexydb.html', Object(CcData)) #1 {main} thrown in /var/www/prophp_sample/www/ppa/ppPage.php on line 26
7. PHPソース修正
オリジナルでは CcDataクラスのオブジェクトを PpPageクラスのdisplayメソッド第2引数に渡し、
dispalyメソッドでは HTML_Template_Flexy の outputObject に直接オブジェクトを渡している。
HTML_Template_Flexy では、ある意味何でもできるっぽい。
これを Twig 対応とするには、
・ CcDataクラスの $records プロパティを PpPage.displayメソッドの第2引数に渡す
・ PpPage.displayメソッドでは Twigのrenderメソッドの第2引数に渡す
・テンプレートの修正
dispalyメソッドでは HTML_Template_Flexy の outputObject に直接オブジェクトを渡している。
HTML_Template_Flexy では、ある意味何でもできるっぽい。
p15flexydb.php
ppPage.php
:$page = new PpPage; // 表示クラス
$cdata = new CcData; // DAOクラス
$cdata->getData(); // DBからデータを取得
$page->display('p15flexydb.html', $cdata);
:
ppPage.php
//! コンパイルして表示する
//! @param string $tmpl テンプレートファイル名
//! @param object $dobj 出力データ
//! @param array $elem HTML要素出力データ
public function display($tmpl, $dobj = false, array $elem = array()) {
$this->flexy->compile($tmpl);
$this->flexy->outputObject($dobj, $elem);
}
これを Twig 対応とするには、
・ CcDataクラスの $records プロパティを PpPage.displayメソッドの第2引数に渡す
$page->display('p15flexydb.html',
[
'records' => $cdata->records,
]
);
・ PpPage.displayメソッドでは Twigのrenderメソッドの第2引数に渡す
・テンプレートの修正
foreachの書式を変更:
{foreach:records,r} → {% for r in records %}
{end:} → {% endfor %}
プロパティの変更:{end:} → {% endfor %}
例:{r.zipcode:hs} → {{ r.zipcode }}
実行結果:
参考 (ソース全体)
◆ p15flexydb.html
◆ p15flexydb.php
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>郵便番号検索</title>
</head>
<body>
<table>
<tr><th>郵便番号</th><th>都道府県名</th><th>市区町村名</th><th>町域名</th></tr>
{% for r in records %}
<tr>
<td>{{ r.zipcode }}</td>
<td>{{ r.pref }}</td>
<td>{{ r.city }}</td>
<td>{{ r.town }}</td>
</tr>
{% endfor %}
</table>
</body>
</html>
◆ p15flexydb.php
<?php
//! HTML_Template_Flexyのサンプル データベース処理との組合せ
require_once 'ppPage.php';
//------------------------------//
//! DAOクラス
class CcData {
public &records = array(); //!< 検索したレコードの配列
//! データ取得
public function getData() {
try {
// MySQLに接続 PHP5.3.6以降でcharsetを指定可 MySQL5.5未満ではcharset=utf8を指定
&dbh = new PDO('mysql:dbname=ppdb;host=db;charset=utf8mb4',
'ppguest', // DB接続ユーザ
'passwordpassword'); // DB接続パスワード
} catch (PDOException &e) {
die('Connect Error: ' . &e->getCode());
}
&dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
&dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
try {
&sql = 'SELECT zipcode, pref, city, town FROM zipcodes';
&sql .= ' WHERE zipcode >= ? AND zipcode <= ?';
&sql .= ' ORDER BY zipcode ASC LIMIT 100';
// 郵便番号の検索範囲
&mincd = '2070000';
&maxcd = '2090000';
&sth = &dbh->prepare(&sql);
&sth->bindParam(1, &mincd, PDO::PARAM_STR);
&sth->bindParam(2, &maxcd, PDO::PARAM_STR);
&sth->execute();
while (&row = &sth->fetchObject()) {
&this->records[] = &row;
}
&sth->closeCursor();
} catch (Exception &e) {
die('Access Error: ' .&e->getCode());
}
}
}
//------------------------------//
&page = new PpPage; // 表示クラス
&cdata = new CcData; // DAOクラス
&cdata->getData(); // DBからデータを取得
&page->display('p15flexydb.html',
[
'records' => &cdata->records,
]
);
