//tips
//php理解
Sessionをログイン機能に組み込んでいく。ログインしていない場合はログイン後のtop画面は表示させずにログイン画面に遷移するようにしている。
<?php
session_start();
if(isset($_SESSION['login'])==false){
print 'ログインされていません<br/>';
print'<a href="../staff_login.html">ログイン画面へ</a>';
exit();
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ログイン</title>
</head>
<body>
ショップ管理トップメニュー<br/>
<br/>
<a href="../staff/staff_list.php">スタッフ管理</a><br/>
<br/>
<a href="../product/pro_list.php">商品管理</a><br/>
</body>
</html>
ただ、ずっと同じセッションIDにすると危険なのでsession_regenerate_id(true);でセッションハイジャックされないようにidをこまめに変える。
<?php
session_start();
session_regenerate_id(true);
if(isset($_SESSION['login'])==false){
print 'ログインされていません<br/>';
print'<a href="../staff_login.html">ログイン画面へ</a>';
exit();
}else{
print $_SESSION['staff_name'];
print 'さんログイン中<br/>';
print'<br/>';
}
全てのphpスクリプトに上記のセッション確認・生成機能を追加する。
ログイン画面は作成できたのでログアウト画面も作成していく。
ログアウトはセッション変数を空にし、idをクッキーから削除、そして、セッションを破棄することで可能になる。
$_SESSION=array();でセッションを空にする。
setcookie(session_name(),'',time()-42000,’/‘);でパソコン側のセッションidをクッキーから削除。
session_destroy();でセッションを破棄してサーバーとの関係をなくす。
Setcookieより前に画面表示があってはならないというルールがあるのでhtmlより先に記載する。
<?php
session_start();
$_SESSION=array();
if(isset($_COOKIE[session_name()])==true){
setcookie(session_name(),'',time()-42000,'/');
}
session_destroy();
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ログアウト</title>
</head>
<body>
ログアウトしました<br/>
<br/>
<a href="../staff_login/staff_login.html">ログイン画面へ</a>
</body>
季節の野菜サイトを作成してみる。月を入力するとその時の旬の野菜が表示されるサイトを作成する。
まずは入力画面の作成。
<body>
<form method="POST" action="shun.php">
<input type="text" name="tsuki"><br/>
<input type="submit" value="OK">
</form>
</body>
そして旬の野菜の名前を配列に格納して表示させる。配列の0番は月がないので空欄で良い。月の順番に合わせて野菜も入れていけば対応可能。
<?php
$tsuki=$_POST['tsuki'];
$yasai[]='';
$yasai[]='ブロッコリー';
$yasai[]='カリフラワー';
$yasai[]='レタス';
$yasai[]='みつば';
$yasai[]='アスパラガス';
$yasai[]='セロリ';
$yasai[]='ナス';
$yasai[]='ピーマン';
$yasai[]='オクラ';
$yasai[]='さつまいも';
$yasai[]='大根';
$yasai[]='ほうれんそう';
print $tsuki;
print '月は';
print $yasai[$tsuki];
print 'が旬です';
?>
次は添字以外を指定する連想配列を使用してみる。
<body>
<form method="POST" action="hoshi.php">
<input type="text" name="mbango"><br/>
<input type="submit" value="OK">
</form>
</body>
添字に文字を使用する場合は先の配列の[]の中に文字を入れれば、その文字と値が関連ずけられて格納される。
<?php
$mbango=$_POST['mbango'];
$hoshi['M1']='カニ星雲';
$hoshi['M31']='アンドロメダ大星雲';
$hoshi['M42']='オリオン大星雲';
$hoshi['M45']='すばる';
$hoshi['M57']='ドーナツ星雲';
print 'あなたが選んだ星は、';
print $hoshi[$mbango];
?>
全ての星雲を表示させたい場合はforeachで配列の中身全てを抜き出す。
<?php
$mbango=$_POST['mbango'];
$hoshi['M1']='カニ星雲';
$hoshi['M31']='アンドロメダ大星雲';
$hoshi['M42']='オリオン大星雲';
$hoshi['M45']='すばる';
$hoshi['M57']='ドーナツ星雲';
foreach($hoshi as $key=>$val){
print $key.'は'.$val;
print'<br/>';
}
print 'あなたが選んだ星は、';
print $hoshi[$mbango];
?>
foreach($hoshi as $key=>$val)の$hoshiが配列名を表し、$keyが添字部分、$valが値の部分として、それぞれ抜き出せる。
次は学年を入れると校舎案内が表示される画面を作成する。
<body>
<form method="POST" action="gakunen.php">
あなたは何年生?<br/>
<input type="text" name="gakunen"><br/>
<input type="submit" value="OK">
</form>
</body>
If-elseで分けると深くなりすぎる場合にはswitchを使用する。
<?php
$gakunen=$_POST['gakunen'];
switch($gakunen){
case'1':
$kousha='あなたの校舎は南です';
break;
case'2':
$kousha='あなたの校舎は西です';
break;
case'3':
$kousha='あなたの校舎は東です';
break;
default:
$kousha='あなたの校舎は3年生と同じです';
break;
}
print '校舎:'.$kousya;
?>
今度は自作の関数を作成していく。
まずは西暦から和暦を取得するコードを作る。
関数は
Function 関数名($データを受け取る変数)
{処理の内容
return $変数;
}
<body>
<form method="POST" action="gengo.php">
西暦を入力してください<br/>
<input type="text" name="seireki"><br/>
<input type="submit" value="OK">
</form>
</body>
<?php
$seireki=$_POST['seireki'];
$wareki=gengo($seireki);
print $wareki;
function gengo($seireki){
if(1868<=$seireki&&$seireki<=1911){
$gengo='明治';
}
if(1912<=$seireki&&$seireki<=1925){
$gengo='大正';
}
if(1926<=$seireki&&$seireki<=1988){
$gengo='昭和';
}
if(1989<=$seireki){
$gengo='平成';
}
return $gengo;
}
?>
ただ、一般的には自作の関数は外部に集約しておくことが基本になっているので、作成した機能を別のファイルに保存し、その関数を呼び出す方法に変更する。
<?php
require_once('../common/common.php');
$seireki=$_POST['seireki'];
$wareki=gengo($seireki);
print $wareki;
?>
Requireがserialzedfieldと同じような役目を負っていることがわかる。
もう少し実践的なXSS(クロスサイトスクリプティング)にも対応できる関数を作成していく。
この関数を使用することでわざわざhtmlspecialcharsなどをいちいち書かなくても良くなる。
$_POSTを$beforeに入れてしまうことで$post=sanitize($_POST);のようにユーザの入力内容を一括で受け取り処理することができるようになる。
$postには対策済みのデータが入っているので必要な情報をそこから取り出していけば良い。
function sanitize($before){
foreach($before as $key=>$value){
$after[$key]=htmlspecialchars($value,ENT_QUOTES,'UTF-8');
}
return $after;
}
ここからショッピングカートの実装に入っていく。まずは商品リストの表示から作成。
URLに?をつけてパラメータとして商品コードを使用している。ここは商品コードなのでgetで取得している。
商品のリンクを押すとhttp://localhost/shop/shop_product.php?procode=1のようにURL表示された画面に飛ぶようになる。ただ、現段階では設定していないので中身はエラー表示となる。
<?php
session_start();
session_regenerate_id(true);
if(isset($_SESSION['member_login'])==false){
print 'ようこそゲスト様 ';
print'<a href="member_login.html">会員ログイン</a>';
print'<br/>';
}else{
print'ようこそ';
print $_SESSION['member_name'];
print'様 ';
print '<a href="member_logout.php">ログアウト</a><br/>';
print'<br/>';
}
?>
<body>
<?php
try{
$dsn='mysql:dbname=shop;host=localhost;charset=utf8';
$user='root';
$password='';
$dbh=new PDO($dsn,$user,$password);
$dbh->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
$sql='SELECT code,name,price FROM mst_product WHERE 1';
$stmt=$dbh->prepare($sql);
$stmt->execute();
$dbh=null;
print'商品一覧<br/></br/>';
while(true){
$rec=$stmt->fetch(PDO::FETCH_ASSOC);
if($rec==false)
{
break;
}
print'<a href="shop_product.php?procode='.$rec['code'].'">';
print $rec['name'].'---';
print $rec['price'].'円';
print '</a>';
print '<br/>';
}
}catch(Exception $e){
print'ただいま障害により大変ご迷惑をおかけしております';
exit();
}
?>
</body>
先の商品詳細の表示画面を作成していく。
<?php
session_start();
session_regenerate_id(true);
if(isset($_SESSION['memberlogin'])==false){
print 'ようこそゲスト様 ';
print'<a href="member_login.html">会員ログイン</a><br/>';
print '<br/>';
}else{
print'ようこそ';
print $_SESSION['member_name'];
print'様 ';
print '<a href="member_logout.php">ログアウト</a><br/>';
print'<br/>';
}
?>
<body>
<?php
try{
$pro_code=$_GET['procode'];
$dsn='mysql:dbname=shop;host=localhost;charset=utf8';
$user='root';
$password='';
$dbh=new PDO($dsn,$user,$password);
$dbh->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
$sql='SELECT name,price,gazou FROM mst_product WHERE code=?';
$stmt=$dbh->prepare($sql);
$data[]=$pro_code;
$stmt->execute($data);
$rec=$stmt->fetch(PDO::FETCH_ASSOC);
$pro_name=$rec['name'];
$pro_price=$rec['price'];
$pro_gazou_name=$rec['gazou'];
$dbh=null;
if($pro_gazou_name==''){
$disp_gazou='';
}else{
$disp_gazou='<img src="../product/gazou/'.$pro_gazou_name.'">';
}
print '<a href="shop_cartin.php?procode='.$pro_code.'">カートに入れる</a><br/><br/>';
}catch(Exception $e){
print'ただいま障害により大変ご迷惑をおかけしております';
exit();
}
?>
商品情報参照<br/>
<br/>
商品コード<br/>
<?php print $pro_code;?>
<br/>
商品名<br/>
<?php print $pro_name;?>
<br/>
価格<br/>
<?php print $pro_price;?>円
<br/>
<?php print $disp_gazou;?>
<br/>
<form>
<input type="button" onclick="history.back()" value="戻る">
</form>
</body>
最後にカートに入れるリンクを追加した。
ここからカートの中に入れられるように設定していく。