「PHP/Webアプリケーション向けの機能」の版間の差分

出典: フリー教科書『ウィキブックス(Wikibooks)』
< PHP
削除された内容 追加された内容
→‎match式: fedora 35 でapache上でphp8のmatche式の動作確認が取れたので、記述を更新。
→‎match式: default について追記
406 行 406 行
:※ Fedora 35 で apache上でほぼ標準設定のままで動作していることを確認。(2021年10月27日にFedora 35 beta のapache で確認済み。)
:※ Fedora 35 で apache上でほぼ標準設定のままで動作していることを確認。(2021年10月27日にFedora 35 beta のapache で確認済み。)


;実行結果
実行結果
<pre>
<pre>
qwer
qwer
420 行 420 行
match式では、下記のように、戻り値を変数(下記コードでは変数 $message )に入れることもできます。
match式では、下記のように、戻り値を変数(下記コードでは変数 $message )に入れることもできます。


コード例
<syntaxhighlight lang="PHP">
<syntaxhighlight lang="PHP">
<?php
<?php
437 行 438 行
:※ Fedora 35 で apache上でほぼ標準設定のままで動作していることを確認。(2021年10月27日にFedora 35 beta のapache で確認済み。)
:※ Fedora 35 で apache上でほぼ標準設定のままで動作していることを確認。(2021年10月27日にFedora 35 beta のapache で確認済み。)


;実行結果
実行結果
<pre>
<pre>
qwerffff
qwerffff
446 行 447 行


一方、switch式の引数の比較は、曖昧なイコール2個の等号<nowiki>==</nowiki>で比較判定されています。
一方、switch式の引数の比較は、曖昧なイコール2個の等号<nowiki>==</nowiki>で比較判定されています。



;default
match式における条件わけの引数の値を下記のように <code>default</code> で、どれにもヒットしなかった場合の結果を示せます。

コード例
<syntaxhighlight lang="PHP">
<?php
$x = 5;

match ($x) {
0 => print("aaaa" . "\n"),
1 => print("qwer" . "\n"),
default => print("ddd" . "\n") ,
2 => print("test" . "\n") ,
};
?>
</syntaxhighlight>


実行結果
<pre>
ddd
</pre>

上記コード例では動作原理の説明のために意図的に default を最後には書きませんでしたが、普通のプログラミングでは下記のように default は最後に書きます。

コード例
<syntaxhighlight lang="PHP">
<?php
$x = 5;

match ($x) {
0 => print("aaaa" . "\n"),
1 => print("qwer" . "\n"),
2 => print("test" . "\n") ,
default => print("ddd" . "\n") ,
};
?>
</syntaxhighlight>

実行結果は同様に<code>ddd </code> です。


== 参考文献 ==
== 参考文献 ==

2021年10月30日 (土) 13:02時点における版

原理

条件分岐とは何かについては、説明しません(中学校の技術家庭科や、高校の情報科目などで習っているハズです)。

もし実用的に、PHPで条件分岐をする際は、よくある例として、ウェブサイト画面になにかの入力欄があって、その入力値をもとに条件判定することになるでしょう。


今回は応用例として、なにかの会員制サイトのログイン画面を考えてみます。

HTMLフォーム画面は、原理的には、下記のようになるでしょう。

HTMLコード例
<form action="logincatchTest.php" method="post" >
ユーザー名: <input type="text" name="username1" id="box_user" ><br>
パスワード: <input type="text" name="password1" id="box_pass" ><br>

<input type="submit" value="ログイン" id="button1">
</form>

上記コードは、HTML側の画面です。

実行すると(あるいはサーバーにアップロードしてブラウザでアクセスすると)、下記のような画面になります。

ユーザー名:         
ログイン名:         
ログイン


ボタン「ログイン」を押すと、ページが「logincatchTest.php」の生成するhtmlページに切り替わる仕組みです。(ブラウザの受け取る 切り替え先ページ のソースコードは htmlページ です。 たとい拡張子に「.php」とついていても、中身はphpではなくhtmlです。)


さらに条件分岐をするためにPHPのコードが必要です。

プログラム例として、もしユーザー名とパスワードとが正しければ、「ログイン成功」と出るプログラムを考えてみましょう。

下記のようなPHPコードをサーバー(のドキュメントルートのフォルダ、apacheなら具体的には /var/www/html)にアップロードすることになります。


PHPのコード
<?php

if( $_POST['username1'] == "yamada" && $_POST['password1'] == "aikotoba" ){
	echo "ログイン成功。<br>" ; 
}

else {	
	echo "やりなおしてください。ログインに失敗しました。<br>" ; 
	echo $_POST['username1'],"と入力されました。<br>" ; 	
}

?>

のようなコードになります。

PHPで条件分岐を使うにはif文を使います。if文とは、「もし~~ならば、〇〇せよ」という命令を実行する文です。

いっぽう、else文は、「もし~~でなければ、〇〇せよ」という命令を実行する文です。

他の多くのプログラム言語でも、if文とelse文は同様の機能です。


説明の簡単化のため、あらかじめユーザー名とパスワードは登録されているとします。登録されているユーザー名は「yamada」、登録されているパスワード「aikotoba」(合言葉)とします。


さて、webブラウザで、上記の(PHPファイルでなく)htmlファイルのウェブページを見に行ってください。

ログイン成功。

と表示されている画面で、ブラウザのソースコード閲覧機能を使っても、


ログイン成功。<br>

としか表示されません。


ソースコードを見ても、if文は、どこにも書かれていません。(JavaScriptの文法には if文 がある。)

またPHPは、サーバーで公開しても、JavaScriptのコードには変換されないです。

このようにPHPは、サーバーで公開しても、コードを素のHTMLにしか変換しないです。


また、webブラウザで直接アドレス指定して、上記コード例の場合なら

http://localhost/logincatchTest.php

などに移動しても

やりなおしてください。ログインに失敗しました。
と入力されました。

とブラウザ画面に表示されるだけです。

また、そのwebページのソースコードをブラウザのソース閲覧機能で見ても、

やりなおしてください。ログインに失敗しました。<br>と入力されました。<br>

とhtmlソースコードが表示されるだけです。


このように、PHP側のプログラムは、一切、ブラウザ側には送られず、よってブラウザにはPHPのソースコードは表示されません。さらに、JavaScriptにも変換されてない事に注目してください。

ブラウザで表示されているソースコードは、素のhtmlタグに変換されたあとのhtmlソースコードです。

なので、パスワードのような機密情報を、冒頭のようなPHPのコードだけでも守ることができます。


実務との違い

ただし、実際の応用の際には、より慎重を期して、パスワードなどの機密情報のあるファイルは、ドキュメントルートよりも上側のフォルダに置くなどします。

そして、そのパスワードのファイルとの送受信をすることで、パスワードの成否の判定をします。


しかし本書では説明の単純化のため、冒頭のPHPコード例では、PHPコード内にパスワードの答えを含めました。


なお、一般にwebサイトにログインした場合には、ブラウザに「クッキー」といわれるログイン情報などを残す必要があります。これは setcookie()というPHPの組み込み関数、およびPHPのスーパーグローバル変数 $_COOKIE で可能です。

また、ブラウザにクッキー変数が存在しているかどうかは、isset()というPHP関数で調べられます。


その他、実務と手本のコードの相違点として、一般の会員制サイトでは、入力ボックスに何も入力されていない段階では、「ログイン」ボタンなどを押せないようになっていますが、その機能の実装はJavaScriptで出来ます。JavaScriptのif文や、onKeyUpプロパティなどを使えば、ボタンを押せない機能を実装できます。(詳しくはwikibooks『JavaScript/イベント処理』を参照してください。)


さらにMySQLなどのデータベース・ソフトウェアを使うことで、ユーザー名やらパスワード名などの会員情報は、MySQLなどに保管します。実務では、あまり、PHPのコード内やテキストファイルなどで直接にパスワードなどを保管することは無いです。

クッキーの入れ方

クッキーを使う前に、まずはメインページを作る必要があります。

wikibooksでも、メインページに、もしログアウトしている状態もしくは未登録の状態でアクセスすれば「ログインしていません」と右上あたりに表示されているのと同様です。

  • メイン画面の例

まず、私たちの自作するメインページは、おおむね下記のようなコードになるでしょう。

メイン画面のコード(PHP)
<?php
$kukiFlag = $_COOKIE['kukites1'] ;

if(isset($kukiFlag)) {
	echo "ログイン中。<br>" ;
}

else {	
	echo "ログインしていません。<br>" ; 
}

?>

<html>
    <body>
    <a href="loginTest.html">ログイン</a> <br>
        <br>
        <p>(※ ここにメインコンテンツの表示の予定。)</p>
    </body>
</html>


当然、最初にこのページを表示したとき、まだクッキーを作ってないので、「ログインしていません」と表示されます。

hrefタグは、文章や画像などにクリック時に別ページにリンクする機能をつけるためのプロパティです。HTMLのどの入門書にも hrefタグは解説が書いてあるので、本PHP教科書ではhrefの説明は省略します。


さて、上記メインページから、ログイン画面に映ります。

  • ログイン画面の例

ログイン画面のコードは、すでに前の節で作成したのと同じで構いません。下記にコードを再掲します。

ログイン画面のコード
<form action="logincatchTest.php" method="post" >
ユーザー名: <input type="text" name="username1" id="box_user" ><br>
パスワード: <input type="text" name="password1" id="box_pass" ><br>

<input type="submit" value="ログイン" id="button1">
</form>


ログイン画面では、まだクッキーは作成しないです。


クッキーを作成する時期は、ログインに成功したあとです。


  • ログイン成否の確認画面の例

さて、ログインの成否の確認画面が、下記のように変わります。

<form action="logincatchTest.php" method="post" >
<?php

if( $_POST['username1'] == "yamada" && $_POST['password1'] == "aikotoba" ){

	setcookie("kukites1", "123",time()+ 30 );  // 30秒の保存期間 

	echo "ログイン成功。<br>" ; 	
	
}

else {	
	echo "やりなおしてください。ログインに失敗しました。<br>" ; 
	echo $_POST['username1'],"と入力されました。<br>" ; 
	
}

?>

<html>
    <body>
        <br>
        <a href="kukiTesM.php">メインページに戻る</a> <br>
    </body>
</html>

setcookie()関数で、クッキーをブラウザに与えます。

書式は

setcookie(クッキー名, 値, time() + 時間 );  

です。


上記コードでは、安全のため、30秒の経過でクッキーが消失するようにしています。

つまり

setcookie(クッキー名, 値, time() + 保存の秒数 );

という書式です。

なので、もし

setcookie(クッキー名, 値, time() + 30 );

なら、30秒でクッキー消失します。


たとえば

setcookie(クッキー名, 値, time() + 60*60*24*2 );

なら、2日間、クッキーが残ります。ぴったり2日間経過した直後の瞬間に、クッキーが消えます。

30秒でクッキー消失します。

さて、上記コードでは、 またクッキーとは別に、ログイン成功したあとにメインページに戻る機能も必要なので、hrefタグでメインページに戻るリンク文も追加しています。

なお、上記コードでは実はログイン失敗しても「メインページに戻る」リンク文が表示されるのですが、説明の単純化のため、上記コードのままにします。(クッキー以外のif文が増えると、説明がややこしくなるので。)


  • 実験例

では、上記3個のページのコードすべてが完成したら、ローカルサーバーにアップロードしてみて、ブラウザからメインページにアクセスしてみてください。

そして、ログインしてください。ユーザー名「yamada」、パスワード「aikotoba」です。

ログイン成功したら、すぐに30秒以内にリンク文を押して、メインページに移動してください。

そして、メインページの表示中に、キーボードのファンクションキーのF5ボタンを押して、リロードしてください。

30秒以内なら、クッキーが保存中なので「ログイン中」とメインページで表示されます。


さて、F5ボタンを飽きるまで、何回か押して、なんどかリロードして、いろいろと試してください。


もし30秒経過後にリロードすると、もはやクッキーが消失しているので「ログインしていません」と表示されます。


  • 備考

実際のwebブラウザでは、PHPのコードで指定した値(上記コードの場合なら「123」)のほかにも、さまざまな情報がwebブラウザ側で自動的に保存される。アクセス日時、作成日時、有効期限などの情報や、諸設定に必要な情報が保存されている。

この事を確認するには、Firefoxの場合、通常版Firefoxでは確認が不可能であるので、開発者用の Firefox Developer Edition を使う必要がある。(通常版 Firefox では、クッキー名の一覧は見れるが、しかしクッキー内部を見ることができない。)

開発者用Frirefoxでの 三本アイコン > 「ウェブ開発」>「ストレージインスペクター」で、クッキーのブラウザに保管された状態での中身を見ることができる。 (まぎらわしいことに「インスペクター」というメニューも近くにあるが、それではなく、「ストレージインスペクター」を選ぶ必要がある。)

なお Linux の場合 インストールは不要で、単に Firefox 公式サイトからダウンロードしてきて解凍し、ファイル内にある実行ファイル「Firefox」をクリックすれば、開発版ブラウザが起動する。


※備考: クッキーのセキュリティ対策など

クッキーのデータはネットワーク経由で受け渡しされる。なので、念のために「盗聴」(データの覗き見)を第三者にされている事態も想定しておき、そのためクレジットカードの番号やパスワードなどといった機密情報については、けっしてクッキーでは受け渡しをしていはいけない。[1] [2]

よってクッキーでは、パスワードなどのある認証サイトのキーだけを受け渡しするようにするなどの注意が必要である。

また、もしもクッキーの内部に、ログインについてのYesまたはNo のような文字列を入れてその文字を読み取るようなログイン方式だと、不正ユーザーによって、文字列を書き換えされて不正ログインされる可能性があるので、別の方式にする必要がある[3]

単に、ログインのキーだけを渡すのが良いだろう。


なお、一般にブラウザのクッキーの保管の容量には4キロバイトまでと制限があり[4]、もし容量オーバーすると古いクッキーから順に削除されていく方式である。

このため、大きな情報はクッキーには納めてはいけないし、納められない[5]

アカウント設定などの情報は、クッキーには含めないでおくのが、実務的にもマナー的にも望ましいだろう。アカウント設定などはサーバー側でデータベースなどで保管しておこう。セキュリティ的にも、サーバー側で保管するのが安全である。


厳密な等価演算子===

if文などで等価を判定するさいのイコール演算子は、

PHPでは少なくとも2種類ある。


イコール記号2個の==と、

イコール記号3個の===である。


イコール記号2個では、型を区別しない

イコール記号3個では、型を区別する。


なお、イコール1個だけでは単なる代入命令であるので、等価演算子としては機能しない。

厳密でないイコール2個

イコール記号2個の==で評価した場合、

下記コード、

<?php

$a =1; // 

if($a==1) {
    print ("数字<br>") ;
}

if($a=="1") {
    print ("文字列<br>") ;
}

?>

を実行すると

数字
文字列

のように、両方の場合にヒットしてしまいます。

$a =1; を代わりに$a ="1"; と宣言しても同様に両方ヒットの結果になります。

このように、数値として定義したつもりの変数が文字列としても解釈されたりする仕様は、便利な場合もありますが、ときには予想外の動作を引きおこすので使いたく無い場合もあります。そこで、下記のように、イコール3個の厳密な判定を行う等価演算子が用意されています。

厳密なイコール3個

イコールの比較のさいの、型についての予想外の動作を防ぐための、より厳密な比較をできるイコール3個の演算子があります。

if文などでの比較の際、イコール記号3個の===で評価すると、数値型と文字列型とを区別して比較し、型も含めて同じ場合にだけ真になります。

<?php

$a = 1; 

if($a === 1) {
    print ("数字<br>") ;
}

if($a === "1") {
    print ("文字列<br>") ;
}

?>
実行結果
数字

このように、イコール3個で、型を厳密に区別して、等価かどうかを評価します。


  • 余談

余談ですが、PHPは変数に値を代入する際、じつは型の情報も保管しています。なので、上記のように厳密評価も必要に応じて行えるわけです。


match式

2020年11月リリースされたPHP8から条件分岐にmatch式(match expression)が加わりました。

match式は、下記のように、引数の数値に基づいて場合分けをするときに、使います。

コード例

<?php
    $x = 1;

    match ($x) {
        0 => print("aaaa" . "\n"),
        1 => print("qwer" . "\n"),
        2 => print("test" . "\n") ,
    };
?>
(※ PHP公式のソースコンパイル php-8.0.0 リリース版 で、2020年12月13日にLinux Fedora 33上で動作確認ずみ。)
※ Fedora コマンドライン上での動作確認。
※ Fedora 35 で apache上でほぼ標準設定のままで動作していることを確認。(2021年10月27日にFedora 35 beta のapache で確認済み。)

実行結果

qwer

なお、switch文との違いとして、match式ではbreakが不要です。

macth式の方が便利なので、今後はmatch式の用例が増えると思います。

なお、match「式」(expression)とは言いますが、数学の「式」(equation, formula)とは別物です。プログラミング用語の"expression"とは、単に、関数や変数や演算子などを合わせた表現にすぎません。


match式では、下記のように、戻り値を変数(下記コードでは変数 $message )に入れることもできます。

コード例

<?php
    $x = 1;

    $message = match ($x) {
        0 => "aaaa",
        1 => "qwerffff",
        2 => "test" ,
    };

    print($message . "\n");

?>
(※ PHP公式のソースコンパイル php-8.0.0 リリース版 で、2020年12月13日に動作確認ずみ。)
※ Fedora 35 で apache上でほぼ標準設定のままで動作していることを確認。(2021年10月27日にFedora 35 beta のapache で確認済み。)

実行結果

qwerffff


なお、match式の引数の比較は、厳密なイコール3個の等号===で比較判定されています。

一方、switch式の引数の比較は、曖昧なイコール2個の等号==で比較判定されています。


default

match式における条件わけの引数の値を下記のように default で、どれにもヒットしなかった場合の結果を示せます。

コード例

<?php
    $x = 5;

    match ($x) {
        0 => print("aaaa" . "\n"),
        1 => print("qwer" . "\n"),
        default => print("ddd" . "\n") ,  
        2 => print("test" . "\n") ,  
    };
?>


実行結果

ddd

上記コード例では動作原理の説明のために意図的に default を最後には書きませんでしたが、普通のプログラミングでは下記のように default は最後に書きます。

コード例

<?php
    $x = 5;

    match ($x) {
        0 => print("aaaa" . "\n"),
        1 => print("qwer" . "\n"),
        2 => print("test" . "\n") ,  
        default => print("ddd" . "\n") ,  
    };
?>

実行結果は同様にddd です。

参考文献

  1. ^ WINGSプロジェクト著『改訂新版 基礎PHP』、インプレスジャパン、2009年7月11日 第1版 第10刷発行、188ページ
  2. ^ 山田祥寛『PHP入門教室』、翔泳社、2012年9月13日 初版 第1刷発行、205ページ
  3. ^ 山田祥寛『PHP入門教室』、翔泳社、2012年9月13日 初版 第1刷発行、205ページ
  4. ^ 山田祥寛『PHP入門教室』、翔泳社、2012年9月13日 初版 第1刷発行、205ページ
  5. ^ 山田祥寛『PHP入門教室』、翔泳社、2012年9月13日 初版 第1刷発行、205ページ