PHP:プロになるためのPHPプログラミング入門 9

公開:2026.05.27(水) 07:33

プロになるためのPHPプログラミング入門 8

以下書籍に付属するサンプルの実行環境を構築する。
プロになるためのPHPプログラミング入門」(ISBN 978-4-7741-4972-1)

環境は以下記事のものを使用
PHP:プロになるためのPHPプログラミング入門 サンプル環境構築

PHP:8.3.30
MySQL:8.0.46

1.6.4 セッション管理を行うアプリケーション (P.77)

サンプルを実行するも当然エラーになる。
http://localhost:8080/prophp_sample/ppa/p16sessa.php

Fatal error: Uncaught TypeError: PpPage::display(): Argument #2 ($elem) must be of type array, stdClass given, called in /var/www/prophp_sample/www/ppa/p16sessa.php on line 36 and defined in /var/www/prophp_sample/www/ppa/ppPage.php:26 Stack trace: #0 /var/www/prophp_sample/www/ppa/p16sessa.php(36): PpPage->display('p16sessa.html', Object(stdClass)) #1 {main} thrown in /var/www/prophp_sample/www/ppa/ppPage.php on line 26

※ 書籍では "p41sassq.php" となっているが "p16sessa.php" の誤りを思われる。

◆ リスト1-17 質問画面プログラム (/ppa/p16sessa.php)
displayメソッド第2引数にオブジェクトを渡しているので配列に変更する。
修正前:
$dobj = new stdClass();
$dobj->ans = $amsg[$ans];
$dobj->ok = $ans ? true : false;
$page = new PpPage;
$page->display('p16sessa.html', $dobj);

修正後:
$dobj = [
	'ans' => $amsg[$ans],
	'ok' => $ans? true: false,
];
$page = new PpPage;
$page->display('p16sessa.html', $dobj)

PHP:プロになるためのPHPプログラミング入門 8

公開:2026.05.27(水) 07:20

プロになるためのPHPプログラミング入門 8

以下書籍に付属するサンプルの実行環境を構築する。
プロになるためのPHPプログラミング入門」(ISBN 978-4-7741-4972-1)

環境は以下記事のものを使用
PHP:プロになるためのPHPプログラミング入門 サンプル環境構築

PHP:8.3.30
MySQL:8.0.46

1.5.6 HTML_Template_Flexyの制御構文

◆ {foreach:value, value}
◆ {foreach:variable, key, value}
Twigとさほど変わらない
{% for record in records %} {% endfor %}
{% for key, value in records %} {% endfor %}

◆ {if:variable}
◆ {if:method()}
Twigではif:method()は使えないが、さほど変わらない
{% if variable %}{% endif %}

サンプルの実行

◆ リスト 1-13 プログラムファイル (/ppa/f15flexyif.php)
実行したところエラーが発生した。
Fatal error: Uncaught TypeError: PpPage::display(): Argument #2 ($elem) must be of type array, stdClass given, called in /var/www/prophp_sample/www/ppa/p15flexyif.php on line 13 and defined in /var/www/prophp_sample/www/ppa/ppPage.php:26 Stack trace: #0 /var/www/prophp_sample/www/ppa/p15flexyif.php(13): PpPage->display('p15flexyif.html', Object(stdClass)) #1 {main} thrown in /var/www/prophp_sample/www/ppa/ppPage.php on line 26

これは \$page->displayの第2引数に $obj (stdClassクラス) を渡しているため。
現在、第2引数は配列のみ指定可能。
なので全体的に配列に変更する。

<?php
//!	HTML_Template_Flexyのサンプル	if制御構文で表示を制御する
require_once 'ppPage.php';
&page = new PpPage;
// &dobj = new stdClass();
&obj = array();
// &dobj->member = false;
&obj['member'] = false;

//	0: 非会員	1: 会員
&kaiin = 1;
if(&kaiin === 1){
	// &dobj->member = true;
	&obj['member'] = true;
}
&page->display('p15flexyif.html', &obj);

テンプレートのif文もTwigの書式に修正

修正前:
{if:member}
<h2>会員さまへのスペシャル情報</h2>
<p id="kaiin">
会員さまだけに、いちはやくお知らせする新商品情報です。
ご案内は<a href="#">こちら</a>からどうぞ。</p>
{end:}

修正後:
{% if member %}
<h2>会員さまへのスペシャル情報</h2>
<p id="kaiin">
会員さまだけに、いちはやくお知らせする新商品情報です。
ご案内は<a href="#">こちら</a>からどうぞ。</p>
{% endif %}

参考 (サンプル全体)

◆ リスト1-12 テンプレートファイル (p15flexyif.html) (P.70)
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<style TYPE="text/css">
<!--
h2 {  margin-bottom:0; padding:5px; width:400px; color:#FFFFFF;
background-color:#267333; border-left: 12px solid #990026;
}
#kaiin {  margin-top:0; padding:10px; width:400px; color: #000000;
background-color: #DCF0DF; border: 1px solid #267333;
}
-->
</style>
</head>
<body>
{% if member %}
<h2>会員さまへのスペシャル情報</h2>
<p id="kaiin">
会員さまだけに、いちはやくお知らせする新商品情報です。
ご案内は<a href="#">こちら</a>からどうぞ。</p>
{% endif %}
<h3>当店の人気商品</h3>
<ul>
<li>もりもりうどん</li>
<li>シャッキリドリンク</li>
<li>パパイア大福</li>
</ul>
</body>
</html>

◆ リスト1-13 プログラムファイル (/ppa/f15flexyif.php) (P.71)
<?php
//!	HTML_Template_Flexyのサンプル	if制御構文で表示を制御する
require_once 'ppPage.php';
$page = new PpPage;
$obj = array();
$obj['member'] = false;

//	0: 非会員	1: 会員
$kaiin = 1;
if($kaiin === 1){
	$obj['member'] = true;
}
$page->display('p15flexyif.html', $obj);


PHP:プロになるためのPHPプログラミング入門 サンプル環境構築 7

公開:2026.05.23(土) 08:43

プロになるためのPHPプログラミング入門 サンプル環境構築

以下書籍に付属するサンプルの実行環境を構築する。
プロになるための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接続パスワードの変更
~/docker/php/prophp_sample/www/ppa/p15flexydb.php (15行目)
初期パスワードは "GGGGGGGGGG" になっているのでユーザ情報テーブルに登録したパスワードを設定する。
PHP:プロになるためのPHPプログラミング入門 サンプル環境構築 4

2. とりあえずの動作確認
とりあえず http://localhost:8080/prophp_sample/ppa/p15flexydb.php に接続したところエラーが表示された。

Connect Error: 0

3. PDO MySQLドライバーのインストール
PDO MySQLドライバーが必要かもしれないのでインストールを実施。
PHPコンテナに接続し以下コマンドを実行する。
apt-get install php-mysql

4. エラー 2002
エラー発生
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
エラー発生
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 では、ある意味何でもできるっぽい。
p15flexydb.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 %}
プロパティの変更:
例:{r.zipcode:hs} → {{ r.zipcode }}

実行結果:

参考 (ソース全体)

◆ p15flexydb.html
<!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,
	]
);


その他の記事