//tips
//ecサイト/php理解
セレクトボックスの中身を文字列にしたい場合は、
<p>秘密の質問を選択してください</p>
<form action=“select-foreach-output.php” method=“post”>
<select name=“question”>
<?php
$question=[
‘最初に見た映画の名前は?’,
‘最初に飼ったペットの名前は?’
‘卒業した小学校の名前は?’
];
foreach($question as $ item)
{
echo ‘<option value=“‘,$item,’”>’ ,$item,’</option>’;
}
?>
</select>
<p>質問の回答</p>
<p><input type=“text” name=“answer”></p>
<p><input type=“submit” value=“確定”></p>
</form>
echo ‘<option value=“‘,$item,’”>’ ,$item,’</option>’;とechoの後のクゥオートが複雑になっているが、
ベースになっているのは
・<option value=“0”>0</option>などのvalueを囲むもの
・echoのecho’あいう’,$i,’えお’;といった変数以外を囲むもの
となっている。
ここでは配列を使用して選択肢をまとめ、foreachで一つずつ取り出している。配列の値を取り出すのはforeachが便利。
これを送信した後の結果表示を下記のように書くことができる。
<?php
echo ‘<p>質問は「’,$_REQUEST[‘question’],’」</p>’;
echo ‘<p>回答は「’,$_REQUEST[‘answer’],’」</p>’;
?>
この配列に格納するものを店舗名:店舗コードとしたい場合には
$store=[
‘新宿’=>100,‘秋葉原’=>101,・・・
];
foreach($store as $key=>$value)
{
echo ‘<option value=“‘,$value,’”>’ ,$key,’</option>’;
}
とすることができる。
Phpにはキーと値を格納する機能があり、キーA=>値Aとすることで簡単に格納できる。一瞬ラムダ式かと思ってしまったが異なるものだった。
複数のチェックボックスを作成するためには
<p>ご興味のある商品ジャンルを全て選んでください。</p>
<form action=“checks-out.php” method=“post”>
<?php
$genre=[‘カメラ’,‘パソコン’,‘時計’]
foreach($genre as $item){
echo ‘<p>’;
echo ‘<input type=“checkbox” name=“genre[]” value=“‘”,$item,’”>’;
echo $item;
echo ‘</p>’;
}
?>
チェックボックスの場合はname属性を配列にする場合もあるので気をつける。こうすることでgenre[]で値を配列で取得することができるようになる。つまり、genreに対してカメラ、時計などの複数のチェックを取得できるようになる。
リクエストパラメータの方はgenre[]ではなくgenreとして認識されるので、$_REQUEST[‘genre’]で取得できる。
次は関数も交えたスクリプトを確認する。
複数の画像の中からランダムに一つを選んで実行する場合は、下記のように画像を数字で管理しておき、数字部分をランダムにすることで、ランダムな画像を取得させることができる。
<?php
echo ‘<img src=“item’,rand(0,2),’.png”>’;
?>
入力された文字列をチェックする場合には正規表現を使用する必要があり、preg_match(パターン,入力文字列)というパターンマッチングを行う。
引数に指定したパターンに入力文字列がマッチすると、preg_match関数は「1」を返す。マッチしなかった場合には「0」を返す。
<?php
$postcode=$_REQUEST[‘postcode’];
if(preg_match(‘/^[0-9]{7}$/‘,$postcode)){
echo’郵便番号’,$postcode,’を確認しました。’;
}else{
echo $postcode,’は適切な郵便番号ではありません’;
}
?>
一見不可解に見える‘/^[0-9]{7}$/‘というパターンは、
^:行頭
[0-9]:0から9までの数字
{7}:直前の文字が7文字続く
$:行末
というふうに意味が当てられており、連結させると、0から9までの数字が7文字続くことを示している。
これを‘/と/‘によって囲み文字列としている。これらの表現は慣れる必要がある。
ちなみに、ハイフンありの場合は、
if(preg_match(‘/^[0-9]{3}-[0-9]{4}$/‘,$postcode)){
となる。
入力したパスワードを正規表現で判定する場合には、
<?php
$password=$_REQUEST[‘password’]
if(preg_match(‘/(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])[a-zA-Z0-9]{8,} /’)),$password){
echo’パスワード「’,$password,’」を確認しました’;
}
?>
呪文のように思える/(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])[a-zA-Z0-9]{8,} /’も分解できる。
(?=.*[a-z]):英語小文字を含む
(?=.*[A-Z]):英語大文字を含む
(?=.*[0-9]):数字を含む
[a-zA-Z0-9];英語小文字、大文字、数字のいずれか1文字
{8,} :直前の文字が8文字以上続く。
これを読み解くと、8文字以上で英語小文字大文字数字を最低1文字含むパスワードとなる。
基本的には1つの文字の条件を定め、後続の文字にその条件を受け継がせている流れ。
入力されたフリガナを取得し、半角から全角に直し表示するスクリプトを確認する。
<?php
echo ‘フリガナは「’,mb_convert_kana($_REQUEST[‘furigana’]),’」です’’
?>
mb_convert_kana関数を使用する。mbとはマルチバイト文字列関数を表し、日本語の文字など、複数のバイトを使って表現する文字列に対して、いろいろな機能を提供する関数。
文字列だけではなく下記のようにオプションも設定することができる。
mb_convert_kana($_REQUEST[‘count’],’n’);
Nは全角数字を半角に変換する。
さらにif(preg_match(‘/[0-9]+/’,$count))
入力される$countの中身が
[0-9]:0から9までの数字1文字
で
+:直前の文字が1文字以上続く場合は以後に続く処理がなされる。
次は入力されたテキストをサーバに保存し、読み込んで一覧表示する処理を作成する。
まずはテキストの入力と送信を下記のように行う。
<p>投稿するメッセージを入力してください</p>
<form action=“board-output.php” method=“post”>
<input type=“text” name=“message”>
<input type=“submit” value=“投稿”>
</form>
メッセージの保存にはJSONを使用。phpスクリプトと同じフォルダにあるboard.txtというテキストファイルに保存している。テキストファイルはメッセージ文字をUTF-8で表現したものが格納される。つまり、入力した日本語から変換されている。
file_exists(ファイル名)でファイルが存在する場合にファイルの読み込みを行なっており、読み込みはfile_get_contents関数を使用する。
読み込むファイルはjson形式で保存されているため、phpで扱えるものに変換するためにjson_decode(文字列)を使用し、phpの文字列や配列に変換している。
その変換したものを$boardに格納して利用できるようにしている。
この配列に新たに追加を行うために$board[]=$_REQUEST[‘message’];として
Messageの内容を追加している。
配列 []= 新規要素 とすることで簡単に追加することができる。他の言語の代入と混同しないようにする。
この追加したものを保存するためにjson_encode(値)でjsonの形にし、file_put_contentsで$fileに書き込んでいる。
最後は$boardの項目を順にメッセージとして表示させている。<hr>は水平線を描く。
<?php
$file=‘board.txt’;
if(file_exists($file)){
$board=json_decode(file_get_contents($file));
}
$board[]=$_REQUEST[‘message’];
file_put_contents($file,json_encode($board));
foreach($board as $message){
echo ‘<p>’,$message,’</p><hr>’;
}
?>
ここでやっていることはjsに似ているのでうまく関連付けて覚えていく。
サーバにファイルをアップロードする方法も確認する。
ファイルをアップロードするには<form>タグのenctype属性にmultipart/form-dataを指定した上でinputタグにtype=“file”としたものを加えることでアップロード用のいつも見かける「ファイルを選択」選択されていませんといったものが表示される。
<p>アップロードするファイルを指定してください</p>
<form action=“upload-output.php” method=“post” enctype=“multipart/form-data”>
<p><input type=“file” name=“file”></p>
<p><input type=“submit” value=“アップロード”></p>
</form>
Enctypeとはデータの種類を表現する方法やデータを変換する方法を定めた規格のことでmultipart/form-dataはhttpでファイルをアップロードする際に用いられるもの。httpでは主にフォームへの入力とアップロードするファイルをまとめるために使う。
アップロードはできたのでそれをサーバに保存していく。
Formタグからアップロードされたファイルは一時的なファイルに保存され、$_FILESによってtype=fileにつけられた名前を引数にとり、その後に[‘tmp_name’]を指定することでファイル名が取得できる。tmp_nameは保存処理前に仮につけられた名前でスクリプトが終了するとこの名前に保存されているものは消える。
$_FILES[‘file’][‘tmp_name’]
ここで取得したファイル名がアップロードしたものと違いないか調べるためにis_upload_file(ファイル名)を使用し、アップロードされたものである場合はtrueを返す。
アップロードされたファイルを保存するためにサーバ上にフォルダを作成。file_exists関数を用いて、保存先のフォルダがすでに存在するかを調べる。
Uploadフォルダが存在しない場合mkdir関数でフォルダを作成する。これはターミナルのコマンドと一緒のよう。
アップロードされたファイル名は$_FILES[‘file’][‘name’]で取得できるが、ファイル名に不正なフォルダ名などが含まれる場合を考慮して、basename関数を使用してファイル名だけを取り出す。
basename(パス)
これにより末尾のファイル名を取り出すことができる。
このファイル名の前にuploadというフォルダ名を加えることで、uploadフォルダ下に格納することができる。
‘upload/’.basename($_FILES[‘file’][‘name’]
この際に.ドットを用いることで文字列同士を連結させることができる。
アップロードされた一時的なファイルを保存先のファイルに移動するにはmove_uploaded_file関数を使う。
move_uploaded_file(一時的なファイル,保存先のファイル)
move_uploaded_files($_FILES[‘file’][‘tmp_name’],$file)
成功時にはtrueを返すのでその際にechoで文言などを表示させるようにしている。
<?php
if(is_upload_file($_FILES[‘file’][‘tmp_name’])){
if(!file_exists(‘upload’)){
mkdir(‘upload’);
}
$file=‘upload/’.basename($_FILES[‘file’][‘name’]);
if(move_uploaded_files($_FILES[‘file’][‘tmp_name’],$file)){
echo $file,’のアップロードに成功しました’;
echo ‘<p><img src=“‘,$file,’”></p>’;
}else{
echo’アップロードに失敗しました’;
}
}else{
echo’ファイルを選択してください’
}
?>
Phpの記述様式がjsよりのものからターミナル寄りのものへどんどん変化してきた。
ここからさらにphp特有のものへ踏み込んで理解していく。