ひぐぺん工房トップへ おかげさまで28周年!

ひぐぺん工房(松浦健一郎・司ゆき) - HigPen Works
Follow @higpenworks
・今までの仕事 ・書籍 ・最近の業務 ・対応可能言語 ・お見積

kiwi 『確かな力が身につくPHP「超」入門 第2版』 Q&A

第1版のQ&Aはこちらから

以下の回答で問題が解決しなかった場合には、

こちらからご連絡ください。

補足

2023/01/17
Q.レンタルサーバにおけるMySQLの使用(6-3)
A.
レンタルサーバにおいてPHPとMySQLを利用する場合、各レンタルサーバの使用方法に沿って、本書のプログラムを変更する必要があります。例えば、データベースを識別する情報(p.205)における接続先のホスト(host)を、localhostからレンタルサーバが指定するホストに変更します。レンタルサーバによっては、データベースを読み書きする処理についても、変更の必要が生じる可能性があります。

お使いのレンタルサーバがMySQLの機能を提供しているかどうかや、PHPからの接続方法については、レンタルサーバのマニュアルを参照したり、そのレンタルサーバにおける設定やプログラムの例をWebで検索したりしてみてください。例えば「ロリポップ php mysql」や「さくら php mysql」のように、「レンタルサーバ名 php mysql」で検索するとよいかと思います。同じレンタルサーバでも、PHPやMySQLのバージョンによって使い方が変わる可能性がありますので、検索した例が使用するバージョンと一致しているかどうか、ご注意ください。

2023/03/29
Q.商品購入後の処理(Chapter7)
A.
本書では顧客が商品の購入を確定した後に、購入情報をデータベースに登録するまでのスクリプトを紹介しています。実際のショッピングサイトでは、次に販売者が商品の決済や発送の作業を行うかと思います。

大規模なショッピングサイトでは、決済や発送のシステムと連携する必要があるかもしれません。一方で、注文はWebで受け付けるけれども、決済や発送は手作業で行えるような規模のショッピングサイトならば、次のような実装方法もあります。以下の1と2を併用します。
  1. 顧客が購入を確定したら、管理者に購入情報をメールで送信する。
    メールが届いたら、管理者は決済や発送の作業を行います。
    可能ならば、顧客に対しても自動的にメールを送信し、購入を受け付けた旨を伝えると、安心していただけそうです。

  2. 購入情報はデータベースに登録されているので、管理者だけがログインできるページを作り、購入情報を閲覧・編集する。
    商品を発送したかどうかや、発送に用いた宅配便の伝票番号などは、購入情報と一括してデータベースに登録して管理するのが、作業の誤りや漏れを防止するためによさそうです。
    また、メールの送受信に失敗する場合に備えて、無理がない間隔(例えば1日に1回など)で管理者ページにもログインし、未処理の注文がないかどうかを確認すると、注文したのに届かない…といったトラブルを避けられそうです。
上記の1のみ、あるいは1と2を併用して実装していると思われるショッピングサイトは、実際に見かけることがあります。決済や発送のシステムと連携する必要がなく、データベースやプログラムの構成もシンプルなので、小規模なショッピングサイトを実現する場合には、手間やコストが少ない優れた方法の一つかと思います。会員登録やログインの機能を省いて、さらにシンプルにしたショッピングサイトも見かけます。

もし実際にショッピングサイトを構築する際には、セキュリティにご注意ください。顧客の名前・連絡先・クレジットカード番号といった重要な情報を、ショッピングサイトで入力してもらい、データベースに登録することになるかと思います。通信時の情報漏洩や、データベースへの不正アクセスが起きないよう、十分な対策をすることをおすすめします。

少なくとも、本書で紹介しているSQLインジェクション(p.227)への対策は必須です。また、本書で扱う範囲を外れますが、例えば通信路の安全確保(httpsを使用するなど)をしたり、ショッピングサイトに配置するファイルのパーミッションを適切に設定したり、決済が完了したらクレジットカード番号をデータベースから破棄したり(漏洩を防止するため)、管理者用パスワードを厳重に管理したり、PHPやデータベース管理システムのセキュリティアップデートを定期的に適用したり…といった対策も必要そうです。

2023/05/17
Q.購入日の登録と表示(Chapter7)
A.
購入日をデータベースに登録し、購入履歴に購入日を表示するためには、本書のサンプルを以下のように改造します。
  1. shop.sql(サンプルのchapter7フォルダ)を編集して、purchaseテーブル(p.267のFig「テーブル間の関係」を参照)に、購入日の列を追加します。購入日の列の型としては、文字列型(varchar)、日付型(date)、日時型(datetime)などの選択肢があります。日付型や日時型を使う場合は、Webで「mysql date」や「mysql datetime」などを検索し、使い方を調べてみてください。
  2. purchase-output.php(サンプルのchapter7フォルダ)を編集して、purchaseテーブルに登録する購入情報に、購入日の列を追加します。現在の日時を取得する方法は、本書の5-1(p.140)で解説しています。
  3. history.php(サンプルのchapter7フォルダ)を編集して、購入履歴を表示する際に、購入日の列も表示するようにします。

2023/05/17
Q.アップロードするファイル名の形式を確認する(5-8)
A.
p.182のNote「ファイル名の形式を確認する正規表現」を、p.180のファイルをサーバ上に保存するプログラム(upload-output.php)に適用するには、例えば以下のようにプログラムを変更します。

変更前:
$file='upload/'.basename($_FILES['file']['name']);

変更後:
$base=basename($_FILES['file']['name']);
$file='upload/'.$base;
if (!preg_match('/^[a-zA-Z0-9_]+\.(png|jpg|jpeg)$/', $base)) {
  echo '対応していないファイル形式です。';
} else

上記のプログラムは、ファイル名の末尾が.png、.jpg、.jpegの場合のみアップロードを実行し、それ以外の場合にはエラーメッセージを表示します。もし、日本語の文字を含むファイル名や、-(ハイフン)などの記号を含むファイル名にも対応したい場合には、正規表現を適宜書き換えてください。

上記のプログラムをダウンロードファイルに収録しておきましたので、お使いください。chapter5フォルダ以下のupload-input2.phpとupload-output2.phpです。

2023/05/17
Q.選択肢を出力する処理(4-4)
A.
以下のスクリプト(p.116)について補足します。

echo '<option value="', $i, '">', $i, '</option>';

echoの後に、複数の値を,(カンマ)で区切って並べると、値を連結して出力できます(p.71)。上記のスクリプトは、以下のような5個の値を、連結して出力します。
  1. 文字列 '<option value="'
  2. 変数値 $i
  3. 文字列 '">'
  4. 変数値 $i
  5. 文字列 '</option>'
例えば、変数$iの値が0の場合には、以下を連結して出力します。
  1. 文字列 '<option value="'
  2. 変数値 0
  3. 文字列 '">'
  4. 変数値 0
  5. 文字列 '</option>'
出力結果は以下の通りです。

<option value="0">0</option>

2023/06/07
Q.edit3.phpにおけるbreak文の意味(6-8)
A.
switch文の中でbreak文を実行すると、そのswitch文を抜け出します。具体的には、switch文の実行を終了し、switch文の次にある文に実行が移ります。

switch文のcase以下には、複数のbreak文を記述することもできます。例えばedit3.php(p.257)には、次のように複数のbreak文が書かれています。以下は'insert'の処理ですが、'update'の処理についても同様です。

case 'insert':
  if (empty($_REQUEST['name']) ||
    !preg_match('/^[0-9]+$/', $_REQUEST['price'])) break;
  $sql=$pdo->prepare('insert into product values(null,?,?)');
  $sql->execute(
    [htmlspecialchars($_REQUEST['name']), $_REQUEST['price']]);
  break;

紙面の都合により、掲載したプログラムは行の途中で折り返していますが、折り返す前のプログラムは以下の通りです。

case 'insert':
  if (empty($_REQUEST['name']) || !preg_match('/^[0-9]+$/', $_REQUEST['price'])) break;
  $sql=$pdo->prepare('insert into product values(null,?,?)');
  $sql->execute([htmlspecialchars($_REQUEST['name']), $_REQUEST['price']]);
  break;

上記のプログラムの意味は、以下の通りです。

'insert'の場合:
  もし、リクエストのnameが空文字列か、リクエストのpriceが数字の並び以外ならば、switch文を抜ける
  (そうでなければ、以下を実行する。)
  insert文を作成する。
  insert文にリクエストのnameとpriceを埋め込んで、実行する。
  switch文を抜ける

最初にリクエストのnameとpriceが適切な形式かどうかを確認し、適切でなければswitch文を抜けます。if文の{}を省略していることに注意してください。if文で実行する文が1個の場合、{}は省略できます。

if文の条件が不成立の場合、つまりnameとpriceが適切な形式の場合は、insert文を作成して実行します。そして、最後にswitch文を抜けます。通常、caseの末尾にはbreak文を書いて、次のcaseにそのまま進むことを防止します。

つまり、edit3.phpで書いた2個のbreak文は、それぞれ以下のような意味です。
(1) if文に付随するbreak文は、リクエストの形式が不適切なときに、switch文を抜ける働きをします。
(2) caseの末尾にあるbreak文は、次のcaseに進まずに、switch文を抜ける働きをします。

もし、(1)のbreak文を削除した場合は、以下のようなプログラムになります。

case 'insert':
  if (empty($_REQUEST['name']) || !preg_match('/^[0-9]+$/', $_REQUEST['price']))
  $sql=$pdo->prepare('insert into product values(null,?,?)');
  $sql->execute([htmlspecialchars($_REQUEST['name']), $_REQUEST['price']]);
  break;

上記のプログラムは、以下のようにif文の中に「$sql=…」という文が入る構造になります。

case 'insert':
  if (empty($_REQUEST['name']) || !preg_match('/^[0-9]+$/', $_REQUEST['price'])) $sql=$pdo->prepare('insert into product values(null,?,?)');
  $sql->execute([htmlspecialchars($_REQUEST['name']), $_REQUEST['price']]);
  break;

上記のプログラムの意味は、以下のようになります。このプログラムも文法的には正しいのですが、元のプログラムとは意味が変わってしまいます。

'insert'の場合:
  もし、リクエストのnameが空文字列か、リクエストのpriceが数字の並び以外ならば、insert文を作成する。
  insert文にリクエストのnameとpriceを埋め込んで、実行する。
  switch文を抜ける

上記のプログラムも実行はできます。例えば、nameを空文字列にする(入力する名前を空にする)と、エラーが発生せずに動作します。

2023/10/02
Q.phpMyAdminで「#1034 - 表 'db' の索引ファイル(key file)の内容が不正です。修復を試行してください。」というエラーが発生する(6-2)
A.
筆者の環境では上記のエラーは発生していないのですが、発生した場合は以下の方法で解決できるという情報があるので、お試しいただけましたら幸いです。
  1. phpMyAdminの画面左側にあるデータベースの一覧で、mysqlをクリックします。
  2. テーブルの一覧が表示されるので、「db」をチェックします。
  3. 画面下方にある「チェックしたものを:」で、「テーブルを修復する」を選択します。
  4. 「SQL は正常に実行されました。」と表示されたら成功です。
  5. 本書のSQLスクリプト(p.191のproduct.sqlなど)を再度実行します。

2024/04/06
Q.Apacheが正常に起動しない場合の対処(2-2)
A.
XAMPPコントロールパネルに「Port 80 in use by "Unable to open process" with PID 4!」と表示されて、Apacheが起動しない場合は、Windowsのスタートメニューで「Windowsの機能の有効化または無効化」を検索して開き、「インターネットインフォメーションサービス」を無効にしてください。

2024/04/06
Q.XAMPPが正常に終了しない場合の対処(2-2)
A.
XAMPPコントロールパネルの終了時に「Error: Cannot create file "C:\xampp\xampp-control.ini".」というダイアログが表示される場合は、Windowsのエクスプローラで「c:\xampp\xampp-contol.ini」のプロパティを開き、「セキュリティ」で「Everyone」に対する「書き込み」を許可してください。

2024/04/06
Q.入力文字列のチェック(7-3)
A.
customer-output.php(p.284)では、ログイン名やパスワードなどの形式はチェックしていません。正規表現(p.149、p.155)を利用すると、文字数や文字の種類などが適切かどうかを判定できます。

最終更新 2024/04/06
トップページへ
©ひぐぺん工房 禁無断転載
最新刊『Java[完全]入門』 
このサイトはリンクフリーです。
このサイトはChromeで動作検証しています。ブラウザにかかわらず表示に乱れがありましたらどうぞお知らせ下さい。メールを送る