忍者ブログ

おやっさんのWEBサイト制作への道

WEBサイト制作ど素人のおやっさんが、HTML、CSS、PHPなど学んでいく技術ブログです。

[PR]

×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

PHP012(アンケートフォーム04 setlocal(カテゴリ,'言語-地域'),fgetcsv(ファイルポインタ,1行の最大長),while文)

今度はCSVに書きだしたデータをブラウザで見るため
show_question.phpをchap4ディレクトリに作ります。


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<style type="text/css">
</style>
<title>アンケート</title>
</head>
<body>
<table border=1>
<tr bgcolor="#cccccc">
<td>購入日</td>
<td>平均購入額</td>
<td>評価</td>
<td>PHP</td>
<td>Perl</td>
<td>Java</td>
<td>C#</td>
<td>C++</td>
<td>Basic</td>
<td>職業</td>
</tr>
<?php
// ファイル名
$filename = 'uploads/question.csv';

// ローケル設定
setlocale(LC_ALL, 'ja_JP');

// readモードで開く
$handle = fopen($filename,'r');


// CSVデータを取り出す
while($data = fgetcsv($handle,1000)) {
// 一行分のデータを取り出す
list($pdate, $pprice, $star,$lang[0],$lang[1],$lang[2],$lang[3],$lang[4],$lang[5],$job) = $data;

// 一行分のデータを表示
//echo '<tr>';
//echo '<td>' . htmlspecialchars($pdate, ENT_QUOTES) . '</td>';
//echo '<td>' . htmlspecialchars($pprice, ENT_QUOTES) . '</td>';
//echo '<td>' . htmlspecialchars($star, ENT_QUOTES) . '</td>';
// 別パターン
echo '<tr><td>' . htmlspecialchars($pdate, ENT_QUOTES) . '</td><td>' . htmlspecialchars($pprice, ENT_QUOTES) . '</td><td>' . htmlspecialchars($star, ENT_QUOTES) . '</td>';
for ($i =0; $i < 6; $i++) {
if($lang[$i] == '') {
echo'<td align="center">-</td>';
} else {
echo'<td align="center">○</td>';
}
}
echo '<td>' . htmlspecialchars($job, ENT_QUOTES) . '</td>';
echo '<tr>';
}
// 閉じる
fclose($handle);
?>
</table>
</body>
</html>

setlocal(カテゴリ,'言語-地域')

日付、通貨、記号、単位等を指定した言語や地域に合わせる。とりあえずめんどくさいのでsetlocal(LC_ALL,'jp-JP')でいきましょう。LC_ALLは全部ってことです。後は日本的なって事で海外になったら違うのいきましょう。fgetcsv関数を使うときに必要です。


fgetcsv(ファイルポインタ,1行の最大長)

ファイルポインタから行を取得し、CSVフィールドを処理するだそうです。CSVファイルから1行取得するってことですかね?1行の最大長とは1行に書ける最大バイト数ですかね?UTF-8だと日本圏で1~4バイトで1文字らしいかな?この辺も難しいです。


while文

while(条件){条件を満たす場合はループします。}
配列やループ数が決まっているものはfor文、それ以外はwhile文でいきます。ここの場合、
while(fgetcsv($handle,1000)){
// 一行分のデータを取り出す
list($pdate, $pprice, $star,$lang[0],$lang[1],$lang[2],$lang[3],$lang[4],$lang[5],$job) = $data;
// 一行分のデータを表示
echo '<tr><td>' . htmlspecialchars($pdate, ENT_QUOTES) . '</td><td>' . htmlspecialchars($pprice, ENT_QUOTES) . '</td><td>' . htmlspecialchars($star, ENT_QUOTES) . '</td>';
for ($i =0; $i < 6; $i++) {
if($lang[$i] == '') {
echo '<td align="center">-</td>';
} else {
echo '<td align="center">○</td>';
}
}
echo '<td>' . htmlspecialchars($job, ENT_QUOTES) . '</td>';
echo '<tr>';
}
fget関数がCSVファイルからデータを取得できなくなるまでループします。


エラーが出なければ下のような画面ができます↓(※画像はクリックで拡大できます。)
CSVファイルデータをブラウザで表示

PR

PHP011(アンケートフォーム03 array(),fopen(ファイル名,モード),flock(ファイルポインタ,モード),fputcsv(ファイルポインタ,配列),fclose(ファイルポインタ))

write_question.phpを作りましょう。




<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<style type="text/css">
</style>
<title>アンケート</title>
</head>
<?php
// 購入日
$pdate = $_POST['pdate'];
// 平均購入額
$pprice = $_POST['pprice'];
// 評価
$star = $_POST['star'];
// 興味のある言語
for ($i =0; $i < 6; $i++) {
if (isset($_POST['lang'][$i])) {
$lang[$i] = $_POST['lang'][$i];
} else {
$lang[$i] = '';
}
}
$job = $_POST['job'];

// 日付チェック
// 全角から半角へ変換
$pdate = mb_convert_kana($pdate,'as','UTF-8');

// 「/」で分割
if (empty($pdate)) {
echo '年月日を入力してください。)<br />';
} elseif (preg_match("/([0-9]{4})[-\/]+([0-9]{1,2})[-\/]+([0-9]{1,2})/", $pdate)) {
list($year,$month,$day) = explode('/',$pdate);
} else {
echo htmlspecialchars($pdate, ENT_QUOTES) . '(年月日を「/」で区切って下さい。)<br />';
}
// 日付チェック
if (isset($year,$month,$day)) {
checkdate($month,$day,$year);
}
// 数値チェック
// 全角から半角変換
$pprice = mb_convert_kana($pprice,'as','UTF-8');
// 数値チェック
if (!is_numeric($pprice)) $pprice = '';

// 保存データ
$data = array($pdate,$pprice,$star,$lang[0],$lang[1],$lang[2],$lang[3],$lang[4],$lang[5],$job);

// 保存ファイルパス
$filename = 'uploads/question.csv';

// appendモードで開く
$handle = fopen($filename,'a');

// 排他的ロック
flock($handle, LOCK_EX);


// CSV書き込み
fputcsv($handle, $data);

// 排他的ロック解除
flock($handle, LOCK_UN);

// 閉じる
fclose($handle);
?>
<body>
<p>■アンケートを登録しました。</p>
<a href="uploads/question.csv"> CSVファイルのダウンロード</a>
</body>
</html>


まずchap4ディレクトリにuploadsディレクトリを作っておいてください。ここではCSVファイルを作ります。CSVファイルの特徴としては、データをカンマ区切り表す。エクセルで扱える。表に近い感覚で扱える。MIMEタイプが「text/csv」なのでメモ帳でも編集可能です。ECサイトの売り上げ・ユーザー情報出力ファイルなどに使用。などです。



array()

配列の一括指定ができる便利な関数です。
$data=[0 ] = $pdata;
$data=[1 ] = $pprice;
$data=[2] = $star;
$data = array(0 =>$pdata, 1=>$pprice, 2=> $star,・・・・・)的な感じです。
連想配列の場合は
$ary = array('naem '=>$usename, 'age'=>$age);みたいな感じです。
とばす場合は
$ary = array(3=> 1,2,3・・・・・);
$ary[3]・・・1
$ary[4]・・・2
$ary[5]・・・3的な感じです。
二次元配列は
$ary = array('tanaka' =>array('age'=>$age, 'tel'=>$tel), 'product' =>array('price'=> $price, num=> $num));
$ary['tanaka']['age']
$ary['tanaka']['tel']
$ary['product']['price']
$ary['product']['num']
的なややこしさです。


fopen(ファイル名,モード)

ファイルまたはURL?をオープンする関数です。
モードは'a'で追加書き込み、ファイルがない場合は新規作成です。
'r'で読み込み用にファイルを開くです。


flock(ファイルポインタ,モード)

ファイルをロックしたり。ロック解除したりもできます。ファイルポインタについてはいろいろ調べたのですが今一つ理解できません。モードは
LOCK_EX・・・排他的ロックです。(排他的ロックされていると、たぶんほかの人はアクセスできません。
LOCK_UN・・・ロック解除です。


fputcsv(ファイルポインタ,配列)

配列を一行分のデータとしてCSVの書式で書き込みます。


fclose(ファイルポインタ)

ファイルを閉じます。fopenのモードは問わないそうです。


CSVファイルに書き込み成功すると↓のような画面になります。
CSV書き込み完了画面
(※画像はクリックで拡大できます。画面はCSSで多少装飾してあるので、本当はもっとシンプルな画面です。)


PHP011(アンケートフォーム02 mb_convert_kana(①,②,③),list(),explode(区切り文字,対象文字列) ,checkdate(月,日,年),is_numeric(),isset(),empty(),preg_match())

確認画面を作りましょう。
check_question.phpを作ります。




<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<style type="text/css">
</style>
<title>アンケート</title>
</head>
<?php
// 購入日
$pdate = $_POST['pdate'];
// 平均購入額
$pprice = $_POST['pprice'];
// 評価
$star = $_POST['star'];
// 興味のある言語
for ($i =0; $i < 6; $i++) {
if (isset($_POST['lang'][$i])) {
$lang[$i] = $_POST['lang'][$i];
} else {
$lang[$i] = '';
}
}
// 職業
$job = $_POST['job'];
?>
<body>
<p>■アンケートの内容を確認してください。</p>
<p>この本の購入日を教えてください。<br />
<?php
// 全角から半角へ変換
$pdate = mb_convert_kana($pdate,'as','UTF-8');
// 「/」で分割
if (empty($pdate)) {
echo '年月日を入力してください。<br />';
} elseif (preg_match("/([0-9]{4})[-\/]+([0-9]{1,2})[-\/]+([0-9]{1,2})/", $pdate)) {
list($year,$month,$day) = explode('/',$pdate);
} else {
echo htmlspecialchars($pdate, ENT_QUOTES) . '(年月日を「/」で区切って下さい。)<br />';
}
// 日付チェック
if (isset($year,$month,$day)) {
checkdate($month,$day,$year);
} else {
echo htmlspecialchars($pdate, ENT_QUOTES) . '(日付に誤りがあります。)';
}
?></p>
<p>一ヶ月あたりの書籍の平均購入額を教えてください。<br />
<?php
// 全角から半角へ変換
$pprice = mb_convert_kana($pprice,'as','UTF-8');
// 数値チェック
if (is_numeric($pprice)) {
echo $pprice . '円';
} else {
echo htmlspecialchars($pprice, ENT_QUOTES) . '円 (数値ではありません。)' ;
}
?></p>
<p>本の評価を教えてください(5段階)<br />
<?php echo htmlspecialchars($star, ENT_QUOTES); ?></p>
<p>興味のある言語を教えてください。(複数選択可)<br />
<?php
for ($i = 0; $i < 6; $i++) {
// チェックされているもののみ表示
if (isset($lang[$i])) echo htmlspecialchars('[' . $lang[$i] . ']', ENT_QUOTES);

//別パターンB
//if ($lang[$i] != '') echo '[' . $lang[$i] . ']';
}
?></p>
<p>あなたの職種を教えてください。<br />
<?php echo htmlspecialchars($job, ENT_QUOTES); ?></p>
<form action="write_question.php" method="POST" />
<input type="hidden" name="pdate" value="<?php echo $pdate; ?>" />
<input type="hidden" name="pprice" value="<?php echo $pprice; ?>" />
<input type="hidden" name="star" value="<?php echo $star; ?>" />
<?php
for ($i = 0; $i < 6; $i++) {
if (isset($_POST['lang'][$i])) {
echo' } elseif (empty($_POST['lang'][$i])){
echo' }
}
?>
<input type="hidden" name="job" value="<?php echo $job; ?>" />
<input type="submit" value="アンケートを送信する" / >
</form>
</body>
</html>


mb_convert_kana(①,②,③)


全角かな、半角かな等に変換します。


①は対象文字列です。


②はオプション記号です。これは決まってます
a:全角英数を半角にします。
s:全角スペを半スペにします。
k:半角カナを全角にします。
とりあえず「as」で覚えちゃってもいいみたいです。


③は文字コードです。ここは、UTF-8でいきましょう。




list($year,$month,$day) = $ary


とりあえず、わかりやすいように例で書いてみました。listは割り当てです。$aryは配列でいっぱいあります。この場合だと3個です。それを変数$year,$month,$dayに割り当てて代入します。




explode(区切り文字,対象文字列)


文字列を文字列で分割する関数です。例えば
$ary = explode('/' 2012/10/28; 2)
なら、$ary[0]・・・[2012]、$ary[1]・・・[10/28]になります。最後の2で、/で文字列を2分割するって意味です。ややこしいですね。




checkdate(月,日,年)


正しい年月日かチェックします。過去、未来も可です。うるう年にも対応です。うるう年ってなんでしたっけ?順番は月,日,年です。これ面倒ですが決まってるみたいです。




is_numeric()


引数が数値かどうかをチェックします。整数、小数、16進数(0~9,a~f)、と指数(1e4=104らしいです。指数はよくわかりませんが天文学的な数字みたいな感じだと思います。)がいけます。数値ならtrue、数値でないならfalseで返します。




isset()


変数があるかどうかを調べます。正確には変数がセットされているかどうか?です。NULLではないかを調べます。NULLは何もないという意味らしいです。NULLの場合はfalseを返します。


empty()


変数が空かどうかを調べます。深くやるとまだ意味がありそうですが、とりあえずこれで自分を納得させます。NULLのとき、文字が空のとき、値が0の場合true、それ以外の場合はfalseです。




preg_match()


正規表現によるマッチングを行う。らしいです。色々記述があり正直わかりません。
なんとなくですが、ここですと
preg_match("/([0-9]{4})[-\/]+([0-9]{1,2})[-\/]+([0-9]{1,2})/", $pdate)
だと0-9の数字を4回繰り返し/で区切り、0-9の数字を2回繰り返し/で区切り、0-9の数字を2回繰り返し/で区切るってことです。もう少し詳しく調べてみます。




上のソースでやればエラーは出ないです。が多々おかしいと思うところもあります。本当は必須条件とかでちゃんと打ち込まないと先に進めなくするのが普通だと思いますが、とりあえず出るエラーを全部防ぎました。たぶんですけど。


htmlspecialchars()の使いどころは、echoのところらしいです。直前で入れることが好ましいらしいです。ようはブラウザ側で働く悪意のあるJSのプログラムを防げればいいらしいです。


アンケートフォームの確認画面です。画僧はクリックで拡大できます。確認画面はCSSで装飾されています。本当はもっとシンプルな画面です。↓


アンケート確認画面

PHP010(アンケートフォーム01 radioボタン,checkボタンのname属性,lebleタグ)

アンケートフォームを作ってみましょう。
chap4ディレクトリを作り
↓question.htmlを作りましょう。




<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<style type="text/css">
</style>
<title>アンケート</title>
</head>
<body>
<div id="contents">
<p>■アンケートにお答えください。</p>
<form action="check_question.php" method="POST">
<p><label>この本の購入日を教えてください。<br/>
<input type="text" name="pdate" value="2010/08/01"></label>
</p>
<p><label>一ヶ月あたりの書籍の平均購入額を教えてください。<br/>
<input type="text" name="pprice" value="5000">円</label>
</p>
<p>本書の評価を教えてください。(5段階)<br/>
<label><input type="radio" name="star" value="5" />5:とても良い</label>
<label><input type="radio" name="star" value="4" />4:良い</label>
<label><input type="radio" name="star" value="3" checked="checked" />3:ふつう</label>
<label><input type="radio" name="star" value="2" />2:悪い</label>
<label><input type="radio" name="star" value="1" />1:とても悪い</label>
</p>
<p>興味のある言語を教えてください。(複数選択可)<br/>
<label><input type="checkbox" name="lang[0]" value="PHP" />PHP</label>
<label><input type="checkbox" name="lang[1]" value="Perl" />Perl</label>
<label><input type="checkbox" name="lang[2]" value="Java" />Java</label>
<label><input type="checkbox" name="lang[3]" value="C#" />C#</label>
<label><input type="checkbox" name="lang[4]" value="C++" />C++</label>
<label><input type="checkbox" name="lang[5]" value="Basic" />Basic</label>
</p>
</p>
<p>あなたの職業を教えてください。<br/>
<select name="job">
<option value="プログラマー">プログラマー</option>
<option value="コンサルタント">コンサルタント</option>
<option value="デザイナー">デザイナー</option>
<option value="研究職">研究職</option>
<option value="学生">学生</option>
<option value="その他">その他</option>
</select>
</p>
<p><input type="submit" value="アンケートを確認する" />
</form>
</body>
</html>







アンケート


■アンケートにお答えください。







本書の評価を教えてください。(5段階)







興味のある言語を教えてください。(複数選択可)









あなたの職業を教えてください。









●radioボタンは一つしか選択できないです。


radioボタンはname属性が同じものは一つの項目としてみなされます。これ重要かも?


●checkボタンは複数選択できます。


つまりname属性が配列になります。これも重要かも?


labelタグ

ボタンだけでなくテキストもクリックできるようになるタグです。ユーザービリティ、アクセシビリティの面でつけて損はないです。クリッカブルとか言うらしいです。上のでテキストをクリックすると選ばれるで試し見てください。
例えば、この本の購入日を教えてください。をクリックりてみたり。
とても良いをクリックしてみたり。PHPをクリックりてみたりしてください。スマホ的なものに役に立つかな。




アンケート入力画面です(※画像はクリックで拡大できます。画像はCSSで装飾されています。実際の入力画面は、もっとシンプルです。↓


アンケート入力画面

PHP009(画像アップローダー04 scandir(ディレクトリのパス),count(配列),for文,pathinfo(ファイルのパス))

ここまでPHPを勉強してわかったことは、プログラムは上から下に実行されます。
あとイニシャライズ、まあ、代入です、をしたほうが良いかもです。
なんとなくですが、これがわかってればプログラムの意味も理解出来てきます。たぶんですけど。

では、一覧画面を作ります。chap3フォルダの中にshow_image.phpを作成します。


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<style type="text/css">
</style>
<title>画像一覧</title>
</head>
<body>
<?php
// 保存先のディレクトリ
$dir = 'uploads/';
$dir_s = 'uploads/s/';

// ディレクトリ内のファイルを取り出す
$files = scandir($dir_s);

// ファイル数を取り出す
$count = count($files);
?>
<p>■画像一覧
<br />
<table border="0">
<?php
// 列の位置
$col = 0;

// ファイルの取り出し
for ($i = 0; $i < $count; $i++) {
// ファイル情報を取り出す
$file = pathinfo($files[$i]);
// ディレクトリ名
$file_dir = $file['dirname'];
// ファイル名
$file_name = $file['basename'];
// ファイルの拡張子
$file_ext = $file['extension'];
// 拡張子なしのファイル名
$name = $file['filename'];

// 拡張子がjpg、gif、pngのファイルを表示する
if ($file_ext == 'jpg' || $file_ext == 'gif' || $file_ext == 'png') {
// 列の加算
$col++;
//先頭ならばTRタグ開始
if ($col == 1) echo '<tr valign="top">';

// TRタグ開始
echo '<td bgcolor="#eeeeee">';
// ファイル名の表示
echo $file_name;
echo '<br />';
// リンク、画像の表示
echo '<a href="'. $dir . $file_name . '" target="blank" /><img src="'. $dir_s . $file_name . '" /></a>';
// TDタグ終わり
echo '</td>';

// 5列目ならTRタグ終わり、列位置を0に戻す
if ($col == 5) {
echo '</tr>';
$col=0;
}

echo '<p>ディレクトリ名:' . $dir . $file_dir . '<br /></p>';
echo '<p>アップロード画像:' . $dir . $file_name . '<br /></p>';
echo '<p>サムネイル画像:' . $dir_s . $file_name. '<br /></p>';
echo '<p>拡張子なしのファイル名:' . $dir . $name. '<br /></p>';
}
}
// 列の残りを埋める
if ($col > 0) {
echo '</td colspan="' . (5 - $col) . '" bgcolor="#cccccc"></td></tr>';
$col=0;
}
?>
</table>
</p>
</body>
</html>



scandir(ディレクトリのパス)

・・・ディレクトリ内のファイル一覧取得します。

count(配列)

・・・配列の要素の数を取得です。
ここでは$filesの要素数を数えます。

例えば要素数8の配列なら
$ary[0]~[7]まで存在します。
この場合
count($ary)は8です。

for文

・・・繰り返し処理、ループ処理です。
for文の図
この教本の場合、①$iに0を代入して、②$countが$iより大きいとき③処理が行われます。処理が終わると$iに1が足され②からもう一度やります。
$countが$iより小さくなるまでループします。

pathinfo(ファイルのパス)

・・・ファイル情報を取り出す関数です。

$~['dirname']・・・ディレクトリ名です。
$~['basename']・・・ファイルパスです。
$~['extension']・・・拡張子です。
$~['filename']・・・拡張子なしのファイルパスです。


↑サムネイルが表示されるとこんな感じです。(※画像はクリックすると拡大できます。このサムネイル表示画面はCSSで装飾してあるので、実際はもっとシンプルな表示画面です。)

カレンダー

04 2024/05 06
S M T W T F S
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

フリーエリア

にほんブログ村 IT技術ブログ HTML/CSSへ にほんブログ村 IT技術ブログ PHPへ

最新コメント

[11/23 テスト]

プロフィール

HN:
おやっさん
性別:
非公開

バーコード

ブログ内検索

P R

忍者ツールズプロフィール

忍者ツールズプロフィールは終了しました

カウンター