【PHPの基礎知識②】PHPの基本ルール
基本構文
開始終了タグ
どこからPHPコードが始まり、どこで終了するかを記述することで、開始終了タグに挟まれた部分がPHPコードとして実行されます。よく使われる開始と終了の合図は <?php と ?> ですが、これを含めていくつかのパターンがあります。
- 1行記述の書式<?php [PHPコード] ?>
- 複数行記述の書式<?php
[PHPコード]
?> - SCRIPTタグ<script language="php">
[PHPコード]
</script> - ASP形式のタグ<% [PHPコード] %>
- 短縮型のタグ<? [PHPコード] ?>
短縮形のタグは記述が単純で便利ですが、推奨されていません。設定ファイルで短縮形のタグの使用を許可しておく必要があったり、XMLタグと混同される可能性があるからです。したがって、「<?php」と「?>」でスクリプトを囲むことが良いでしょう。
echo(文字列を出力する)
- 文字列を出力する使用例echo "こんにちは";
echo 'こんにちは';
単純に文字列を出力するだけなら、「"」「'」どちらでも結果は同じです。
- 変数値を出力する使用例echo $test;
コメント
//コメント
#コメント
/*
コメント
*/
データ型
PHPとデータ型
<PHPでサポートされるデータ型>
- 論理値(boolean)
- 整数(integer)
- 浮動小数点型(float,double)
- 文字列型(string)
- 配列(array)
- オブジェクト(object)
- リソース(resouce)
- Null
PHPで使用するデータは、明示的にデータ型を定義せずに使用できます。それぞれのデータ型は実行時にPHPによって決定されます。
- データ型は自動で決定される$int = 100; ・・・①
$str = $int . "円"; ・・・②①でセットした変数$intのデータ型は整数型(integer)ですが、②では「円」と文字列として統合され、変数$strのデータ型は文字列型(string)となります。
データ型を明示的にに指定したいときは、キャスト(データ型の変換)するか、settype関数によって指定します。キャストするときは、「(int)$val」のように、変換するデータ型を指定します。
論理型( boolean )
論理型は、PHP4で導入された型で、TRUEまたはFALSEの値を持ち、真か偽かを表すときに使われます。FALSE以外にも、次のような値が論理型に変換されたときはFALSEとみなされます。
<FALSEとみなされる値>
- ゼロ(0, 0.0, "0")
- 空の配列、変数、オブジェクト
- Null
使用例
- 変数にTRUEを格納する$boolean = TRUE;
- 関数の戻り値がTRUEか調べるif (file_exists("aaa.txt") == TRUE) { ・・・
論理型を使うには、TRUEまたはFALSEを返す関数の戻り値を調べて、条件応じて処理を分岐するものがあります。この例では、ファイルが存在するかどうかを調べています。(if文のページでも記述しますが、このif文の「==TRUE」は省略することができます。)
- 変数が真か調べるif ($notexist == TRUE) { ・・・
変数を真か偽か調べると、変数値が論理値ではない場合、前述のように変数値がbooleanに変換されて判断されます。空の変数もFALSEとみなされますので、変数に値がセットされているか否かで処理を分岐するときに使えます。
数値型( integer / float )
数値型には、整数型と浮動小数点型があります。整数(integer)は「1,2,3・・・」と続く正の数、「-1,-2,-3・・・」といった負の数と0からなる数値です。計算結果だけではなく、ループのカウンタ、表示するページ番号など用途は多岐にわたります。
浮動小数点型(float)は、数値の各桁(仮数部)と小数点の位置(指数部)で表現される数値で、整数より大きな数値を扱うことができます。どこまでのサイズを扱えるかはプラットフォームに依存します。
使用例
- 整数を指定する$int = 20;
- 8進数を指定する$int = 020;
最初の例は10進数ですが、8進数や16進数も指定可能です。8進数を指定するには、数値の先頭に「0」を付けます。この例は8進数の20=10進数の16です。
- 16進数を指定する$int = 0x20;
数値を16進数で指定するには、数値の先頭に「0x」を付けます。この例は16進数の20=10進数の32です。
- 変数にfloat型の数値をセットする$float = 1.5;
- 整数をオーバーフローさせる$float = 10000 * 10000 * 10000;
指定値や計算結果が整数の範囲を超える場合、その変数はfloat型とみなされます。
文字列型( string )
文字列型は、シングルクォーテーション(')やダブルクォーテーション(")によって指定される文字です。文字列を囲むための「"」自体を出力したい場合、エンマークを使い「\"」とエスケープする方法があります。
使用例
- 変数に文字列をセットする$str = "あいうえお";
文字列はダブルクォーテーションまたはシングルクォーテーションで囲んで指定します。変数を「”」で囲んで指定すると、変数名ではなく、値が文字列としてセットされます。つまり。「"あいう$test"」は「"あいう123"」のような値として扱われます。
- 文字列を結合する$str = "あいう"."ABC";
- 文字列の結合は、ドット(.)を使います。プラス記号(+)は使えません。
この例の $str の値は「あいうABC」となります。 - ヒアドキュメントで文字列を指定する$str = <<<ABC
ここから
ここまでが
文字列です
ABC;ヒアドキュメントは、指定した範囲をそのまま文字列として使うことができます。開始合図は「<<<」+任意のIDで、指定したIDが現れる行までがヒアドキュメントとしてみなされます。終了合図となる行は指定ID+セミコロン(;)で構成します。指定IDで始まることが必要で、ソースコードのインデントによって空白やタブで始まっていないか注意が必要です。この例では、「<<<ABC」と「ABC;」に挟まれた部分が文字列として扱われます。
またヒアドキュメント内の変数は、ダブルクォーテーションで囲んだ変数と同様に、値が文字列として扱われます。
数値文字列 ( string )
数値文字列とは値が数値で、型は文字列型である数値を指します。例えば、次の変数$val1は数値です。変数$val2も値は同じですが、ダブルクォーテーションで囲まれた文字列であり、データ型は「string」です。
<数値型と数値文字列型>
- 数値型$val1 = 123;
- 数値文字列型$val2 = "123";
また、フォームに入力された数値も数値文字列として扱われるので、入力された値を数値かどうかチェックするときは注意が必要です。PHPは数値が文字列で指定されいていても、処理の内容によって自動で数値に変換して対応してくれます。ただ、2つの値の比較や、入力値の数値チェックなどを行っているときは、対象となる値が数値なのか数値文字列なのかを明確にしておく必要があるでしょう。
if(is_int($num)){
echo "数値です。";
}
if(is_numeric($num)){
echo "数値文字列です。"
}
例えば上のコードで「数値文字列です」は出力されますが、「数値です」は出力されません。従って、フォーム入力値のように文字列で格納されている数値を検証する場合は、is_numeric関数を使う必要があります。
配列 ( array )
配列は、複数の値を格納することができる領域です。配列はインデックスと、対応する値から構成されます。インデックスは整数または文字列で指定し、インデックスを指定せずに値のみを格納して配列を作成した場合は、0から始まる整数が連番でセットされます。
使用例
- 空の配列を作成する$array = array();
- 配列に値を格納する$array["server"] = "localhost";
空の配列を作成して、配列に値を格納しています。PHPではデータ型の定義は必要ないので、array()で空の配列を定義しなくとも値を格納できます。
- 値を指定して配列を作成する$array = array("1月","2月","3月");
arrayに続けていくつかの値を指定すると、複数の値を持つ配列が作成されます。この例ではインデックスを指定していないので、0からの順番がインデックスとしてセットされます。
インデックス 値 0番 1月 1番 2月 2番 3月 - インデックスと値を指定して配列を作成する$array = array("JAN" => "1月", "FEB" => "2月", "MAR" => "3月");
インデックスと対応する値に指定するときは「インデックス => 値」のように指定します。この例では、「JAN」「FEB」「MAR」というインデックスを持ち、値がそれぞれ「1月」「2月」「3月」の配列が作成されます。
配列にどのような値が格納されているか出力したいときは、print_r関数やvar_dump関数を使います。print_r関数はインデックスと値を出力、var_dump関数は配列の構造を含めて出力します。
- 配列の要素を出力するprint_r($array);< 出力結果 >Array(
[JAN] => 1月
[FEB] => 2月
[MAR] => 3月
) - 配列の構造を出力するvar_dump(array);
< 出力結果 >
array(3) {
["JAN"] =>
string(3) "1月"
["FEB"] =>
string(3) "2月"
["MAR"] =>
string(3) "3月"
}
オブジェクト( object )
オブジェクトはクラスにアクセスするためのインスタンス(実体)です。多くの場合、new演算子によって作成されます。
使用例
- オブジェクトを作成する$sample = new Sample;
Sampleクラスを使用するために、new演算子でsampleオブジェクトを作成しています。
- オブジェクトのメソッドを実行する$sample -> test();
オブジェクトのプロパティやメソッドを使用するにはセパレータ「ー>」を使ってこれらの要素を指定します。この例では「sample」と「test」を「->」で結合してsampleオブジェクトのtestメソッドを実行しています。クラス定義からオブジェクトの作成、メソッドの実行までの流れをコードでまとめると次のようになります。
- クラスを定義するClass Sample {
private $var = "abc";
function test(){
echo $this->var;
}
}
$sample = new Sample;
$sample -> test() ・・・「abc」を出力
リソース ( resouce )
リソースはPHP4で導入された型で、データベース接続などの外部リソースへの参照を保持しています。リソースを操作する関数によって作成、使用、破棄されます。
使用例
- リソースを作成する(データベース接続)$conn = mysql_connect( $server, $user, $pass);
- リソースを操作する(データベースを選択)mysql_select_db( $dbname, $conn);
- リソースを破棄する(データベースへの接続解除)mysql_close($conn);
NULL
Null型のデータは、PHP4で導入された型でNull値を持つデータです。変数が値を持たない、またはNullがセットされたり、unset関数によって破棄されたときにNullとみなされます。
使用例
- 変数にNullをセットする$test = NULL;
変数にNULLをセットすると、その変数は値をもたないとみなされます。
- 変数がNullか調べるには、is_null関数を使いますif (is_null($test)) {・・・}
このようにis_null関数を使います。
変数
変数は値を格納することができる領域で、ドルマーク($)に続けて任意の変数名をつけた形式で定義されます。変数名は任意の文字またはアンダースコア(_)で始まり、文字、数字、アンダースコアが続く形式の文字列で構成されます。数字で始まる「1st」のような変数名はエラーになります。
大文字と小文字は区別されますので注意が必要です。
$abcと$ABCは別の変数とみなされます。
使用例
- 変数を定義する$test = "abc";
- アンダースコアで始まる変数を定義する$_test = 123;
- 変数への参照を設定する$test = "あいうえお";
$ref = &$test; →参照
$copy = $test; →コピー
$test = "変更";
echo $ref; →出力結果「変更」
echo $copy; →出力結果「あいうえお」
変数名
変数にはわかりやすい名前をつけておくと、ソースが読みやすく、保守性も向上します。プロジェクトによっては変数名の付け方のルール(ネーミングルール)が決められていることがあります。特にルールがない場合でも、すぐに用途がわかる名前を英単語でつけておくか、共通して使われる名前を使うとソースが読みやすくなります。
共通して使われるという点で、ほとんど共通と言って良いのは、ループカウンタには $i が使われるということです。
- ループカウンタに $i を使うfor ( $i = 1; $i <=5; $i++) { ・・・ }
$iを含めて多くのソフトでよく使われる変数名と、その主な用途は次の通りです。
$i | ループカウンタ |
$fp | ファイルポインタ |
$name | ユーザー名、フォント名など |
$key | 配列のインデックス、検索キーワードなど |
$id | ユーザーID、IDフィールドなど |
$value | 配列の値、設定値など |
$title | HTMLタイトル、タイトルフィールドなど |
$result | SQLコマンドの実行結果 |
$data | 1レコード、1行のデータなど |
$str | 文字列 |
変数のスコープ
変数には有効な範囲(スコープ)があり、スクリプト全体で有効な「グローバルスコープ」と一部で有効な「ローカルスコープ」があります。次の例でグローバル変数$gとローカル変数$lの違いを見てみましょう。
- ローカル変数$lにアクセスできない$g = "グローバル";
function f1() {
$l = "ローカル";
}
f1();
echo $g; →出力される
echo $l; →出力されない
この例では変数$gはグローバルスコープですが、変数$lは関数f1内でのみ有効なローカル変数となります。よって関数の外で実行した「echo $g」は動作しますが、「echo $l」はローカル変数$lを出力できません。出力するには次のようにグローバル宣言が必要です。
- 変数$lのグローバル宣言$g = "グローバル";
function f1() {
global $l;
$l = "ローカル";
}
f1();
echo $g; →出力される
echo $l; →出力されない
f1関数内で定義した変数$lをfグローバルスコープにするには、globalを使って宣言します。これによって関数の外でも変数$lにアクセス可能になります。
- グローバル変数$gにアクセスできない$g = "グローバル";
function f1() {
echo $g; →出力されない
}
f1();また、関数内では特に指定がなければローカル変数にアクセスします。この例は関数f1内で「echo $g;」と出力しようとしていますが、上記のルールに従い何も出力されません。$gを出力したい場合は以下のように記述します。
- 関数内でグローバル宣言$g = "グローバル";
function f1() {
global $g;
echo $g; →出力される
}
f1();関数内でグローバル宣言することによって、グローバルスコープの変数を参照するようになります。
- $GLOBALSの参照
次のように、スーパーグローバル変数の$GLOBALSを参照して、グローバル変数にアクセスすることもできます。$GLOBALSにはすべてグローバル変数が格納されており、変数名をインデックスに指定して値を取得、設定できます。$g = "グローバル";
function f1() {
echo $GLOBALS ["g"]; →出力される
}
f1();
スーパーグローバル変数
PHPではバージョン4.1.0以降、スーパーグローバルまたはオートグローバルと呼ばれる特別な変数が追加されました。それぞれの用途は次の通りです。
- スーパーグローバル変数
$_SERVER サーバーの属性値 $_GET GET送信されたデータ $_POST POST送信されたデータ $_COOKIE クッキー $_FILES アップロードされたファイル $_ENV 環境変数 $_REQUEST ユーザーから送信されたデータ $_SESSION セッションデータ
これらのスーパーグローバル変数を含めて、グローバル変数は$GLOBALSの要素として参照できます。「print_r($_GLOBALS);」を実行すると、どのような要素が含まれているかを見ることができます。
$_REQUESTは、$_GET・$_POST・$_COOKIEの内容を含むもので一見使い勝手がよさそうに見えますが、$_GETや$_POSTのほうが圧倒的に使われています。この理由は次の2つが考えられます。
まず、$_REQUEST["param"]がGET、POST、COOKIEのどれを指しているのか曖昧であることです。既定値では、GETが優先されますが、サーバーの設定(php.iniのvariables_order)によっては、優先順を変えたり、無効にすることができます。よって別サーバーに移植して誤動作を生じないとも限りません。
2つ目の理由は、既定値で運用することを想定すると悪意のあるGET送信を受ける可能性がある点です。$_REQUEST["param"]が、フォームのテキストボックスに入力されてPOST送信されるフォームからのデータを想定していても、悪意のあるユーザーによって「param」という名前のパラメータを使って「abc.php?param=...」といったコードで想定範囲外のデータを送信される可能性があります。
よって、GET、POSTどちらを受け取るか明確になっている$_GETや$_POSTがフォームデータを扱う時は多く使われているのではないでしょうか。
PHP4.1より前のバージョンでは、スーパーグローバル変数ではなく、次のような変数が定義されています。
<スーパーグローバル変数に類似する定義済の変数>
- $HTTP_SERVER_VARS
- $HTTP_GET_VARS
- $HTTP_POST_VARS
- $HTTP_COOKIE_VARS
- $HTTP_POST_FILES
- $HTTP_ENV_VARS
- $HTTP_SESSION_VARS
これらの変数はPHP4.1以降のバージョンでも使用可能ですが、推奨されていません。また、php.iniのテンプレートファイルphp.ini-recommendedでは、PHP5で新たに追加された設定ディレクティブregster_long_arraysがOffとなっており、これらの変数が無効になっています。
可変変数
可変変数とは、変数名を動的に取得する変数です。
使用例
- 可変変数を使用する$str = "abc";
$$str = "123";
echo $abc; →「123」を出力この例では、「$$str」が可変変数です。変数$strには「abc」がセットされています。「$$str」は「$」+「$str」つまり、「$」+「abc」=「$abc」となります。よって、変数$abcに「123」がセットされ出力されます。
register_globals
register_globalsをonとした場合、この機能により、HTMLフォームから投稿される変数と同時に、あらゆる種類の変数がスクリプトに注入されることになります。これは、PHPにおいては変数の初期化が不要であるということにも関係し、安全でないコードを書くことが極めて容易になるということを意味します。
register_globalsはPHP4.2からは既定値がOffとなりました。これにより「PHPをバージョンアップしたらアプリケーションが正常動作しなくなった」という現象があちこちで報告されました。すでに日が経っているので、最近はこれが原因での誤動作は耳にしなくなりました。
PHP5.4からは完全に廃止されました。つまり今後はこの設定がOffであることが大前提となります。
register_globalsだけではなく、PHPのバージョンアップによって設定値が変更になり、アプリケーションの誤動作を引き起こすリスクがあります。自分のWebアプリケーションはもちろん、受託開発する場合など、十分な注意とクライアントへの事前説明が必要です。PHP5でいくつか設定変更されていますので、バージョンアップの前後は充分検証しましょう。
定数
定数は値を定義しておくもので、システムの可読性や保守性を高める点では変数と同じです。異なる点は定数は先頭のドルマークが必要なく、define関数によって定義して、値を変更できないという点です。大文字小文字共に使え、区別される点も変数と同じですが、慣習上は大文字で定義されます。7文字前後での命名が多い変数名と比べて長めで、より意味のわかる名前が付けられていることが多いです。よって、使用可能であっても、変数名に見られた1文字の名前のような、1文字の定数はほとんど見られません。
定数の使用は必須ではありませんが、100を超えることも珍しくなく、1000を超える定数が定義されることもあります。各ページに現れるリテラル文字やリテラル数値を可能な限り定数に置き換えることで、メンテナンスが大変楽になります。この際、ファイルの先頭にまとめたり、定義用のファイルにまとめて定義するなど、管理方法にも気を付ける必要があります。
使用例
- 定数を使用するdefine("ADMIN",1);
if ($row["user_class"] == ADMIN ) { ・・・ }定数はdefine関数で定義して使います。この例では定数ADMINとして管理者を示すユーザー区分「1」を定義しておき「ユーザーが管理者であれば・・・(user_classフィールドの値が1であれば・・・)」という条件分岐で使用しています。定数を使わず if ($row["user_class"]==1)のように「1」を直接記述すると、何を示す「1」なのかわかりづらく、修正時に作業忘れの原因にもなります。
定義済の定数
- 定義済定数の例
__FILE__ ファイルのパス __LINE__ 現在の行番号 __FUNCTION__ 関数名 __CLASS__ クラス名 __METHOD__ メソッド名 PHP_VERSION PHPのバージョン PHP_OS OS M_PI 円周率 M_SQRT2 2の平方根
使用例
- カスタムエラー関数を呼び出すerr($err_message, __FILE__, __LINE__);
定義済み定数の中で__FILE__(ファイルパス)と__LINE__(行番号)は、2つを組み合わせてカスタムエラーメッセージを表示する関数に渡すパラメータとしてよく使われます。(「__」の部分はアンダースコア2つです。)
- PHP4.2.0以降ならば処理するif (PHP_VERSION >= "4.2.0") {・・・}
PHPのバージョンが格納された定数PHP_VERSIONは、PHPのバージョンを調べて処理を分岐する時に使われます。異なるバージョンで実行されることを想定するときには有効です。
- OSがWindowsならば処理するif (stristr(PHP_OS, "WIN")) {・・・}
サーバーのOSが格納された定数PHP_OSは、PHP_VERSIONと同様に処理の分岐に使われます。