PHP の基礎知識
更新日:2022年06月03日
作成日:2015年12月14日
PHP の記述
「<?php」と「?>」で囲む
PHP は HTML の中に埋め込むことができます。PHP では、<?php の後に PHP のコードを記述して、最後に ?> で閉じます。
<body> タグの中に記述しなければならないといった制約はありません。
<?php if (isset($_SERVER['HTTP_USER_AGENT']) && (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== false)) header('X-UA-Compatible: IE=edge'); ?> <!doctype html> <html> <head> <meta charset="<?php bloginfo( 'charset' ); ?>" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title><?php wp_title('|', true, 'right'); bloginfo('name');?></title> <link href="<?php echo get_template_directory_uri(); ?>/bs/css/bootstrap.min.css" rel="stylesheet" media="screen"> <link href="//netdna.bootstrapcdn.com/font-awesome/3.2.1/css/font-awesome.min.css" rel="stylesheet"> <?php if(is_page('contact')) { if ( function_exists( 'wpcf7_enqueue_scripts' ) ) { wpcf7_enqueue_scripts(); wpcf7_enqueue_styles(); } } ?> <?php wp_head(); ?> </head> <body <?php body_class(); ?>> <div id="container" class="clearfix"> <div id="header"> <h1><a href="https://www.webdesignleaves.com/" title="Home"><?php bloginfo('title'); ?></a></h1> ......
短縮形のタグ
「<?php」と「?>」で囲む代わりに、「<?」と「?>」で囲む短縮形のタグもありますが、現在はこの短縮形のタグの使用は推奨されていません。
また、短縮形のタグを使用するには、php.ini の short_open_tag=On が有効になっている必要があります。
「echo の短縮形」も参照。
終了タグの省略
ファイル全体が純粋な PHP コードである場合(PHPのコードのみからなるファイルで終了タグ「?>」で終わる場合)は、ファイルの最後の終了タグは省略する方が良いとされています。 終了タグの後に余分な空白や改行があるとそれがブラウザに出力されてしまい、予期せぬ挙動を引き起こす場合(レイアウトが微妙にずれたり、エラーの原因になる等)があるからです。 余分な空白や改行のせいで PHP が出力バッファリングを開始し、その時点の内容を意図せず出力してしまうことになります。
行の終わりは必ずセミコロンを付ける
PHP では各行の終わりにセミコロン「;」を記述します。これにより PHP 本体に行の終わりを認識させます。
<?php echo "セミコロンは必ず記述します"; ?>
コメント
コメントとは、コード(スクリプト)の動作には関係のないメモのようなものです。
コードの要所要所にコメントを残すことで、そのコードの概要を把握しやすくなり、メインテナンス上とても重要です。
コメントの書き方には以下の2種類があります。
- 単一行のコメント → //
- 複数行のコメント → /*~*/
<?php //単一行のコメントです。 ?> <?php /* 複数行のコメントです。 複数行のコメントです。 */ ?>
半角スペースと改行
基本的に、半角スペースや改行はコード内では意味を持たないため、好きな位置に入れることができます。
半角スペースの使い方や改行の方法などはルールを決めてプログラミングをすることがあります。以下は Zend Technologies 社が定めたコーディング規約です。
PHP のファイル名(拡張子)
PHP の拡張子は必ず「.php」としてファイル名の後につける必要があります。
例:sample.php
また、ファイル名は原則として半角英数字を使います。
ファイル名は、Windows やMac OS X では、大文字・小文字は区別されませんが、UNIX 系 OS では区別されるので注意が必要です。
拡張子 .html で PHP を実行する方法
すでに拡張子 .html で作成済みのページで PHP を実行するには、ファイルの拡張子を .php に変更するか、.htaccess ファイルに以下のいずれかを記述することにより、PHP を実行することができます。
どれを記述するかは使用しているサーバーやそのバージョンによって変わってくるため、ドキュメントやサポートで確認します。
※そのサーバーに適さない記述をすると、例えば、リンク(a 要素)をクリックするとページに移動しないで、ダウンロードされたりしてしまうので注意が必要です。
AddHandler application/x-httpd-php .html
AddHandler application/x-httpd-php5 .html
AddHandler application/x-httpd-php70 .html //PHP7.0
AddHandler application/x-httpd-php71 .html //PHP7.1
AddHandler application/x-httpd-php72 .html //PHP7.2
AddType application/x-httpd-php .html //XAMPP や MAMP
AddType application/x-httpd-lsphp .html //ConoHa(2021年5月時点)
AddHandler fcgid-script .html //Xserver(2021年5月時点)
拡張子 .htm にも対応するには、拡張子を追加します。
AddHandler application/x-httpd-php .html .htm /*または*/ AddHandler application/x-httpd-php5 .html .htm /*または*/ AddHandler application/x-httpd-php70 .html .htm /*または*/ AddType application/x-httpd-php .html .htm
特定のファイルのみに適用するには以下のように記述します。
「yourpage.html」の部分に実際のファイル名を指定します。
<Files yourpage.html> AddHandler application/x-httpd-php .html </Files>
ドキュメントルート
ドキュメントルートとは、URL での絶対パスのトップのフォルダーを指します。XAMPP の場合は、ドキュメントルートは以下のフォルダになっています。
C:\xampp\htdocs (Windows の場合)
XAMPP の場合ドキュメントルートの URL は以下になります。
http://localhost/
別の言い方をすると、ドキュメントルートとは、Web サーバ上に公開するためのルートディレクトリになります。
「Hello World!」プログラムの作成
PHP で「Hello World!」を表示させてみます。
<body> タグと </body> タグの間に、PHP の開始タグと終了タグを記述します。
PHP で Web ブラウザに文字を表示するには、echo 文を使用します。
<!doctype html> <html lang="ja"> <head> <meta charset="utf-8"> <title>Hello World/PHP</title> </head> <body> <?php echo "Hello World!"; ?> </body> </html>
この例では、XAMPP のドキュメントルートに「samples」というフォルダーを作成してその中に上記のファイルに hello.php という名前を付けて保存します。
C:\xampp\htdocs\samples\hello.php
保存した「hello.php」を実行するには、ブラウザのアドレスに以下の URL を入力します。
http://localhost/samples/hello.php
PHP マニュアル
PHP 開発者用に書かれた PHP の公式の解説マニュアルが「PHP マニュアル」です。これは、PHP の公式サイトで公開されています。
以下の URL でアクセスすることができます。
オンライン用 PHP マニュアル: http://php.net/manual/ja/
あらかじめ調べたいキーワードがわかっている場合は、以下のように直接 URL にキーワードを記述することができます。但しこの場合表示されるマニュアルは英語なので、言語のプルダウンから Japanese を選択することで日本語のマニュアルを表示できます。
echo: http://php.net/echo
関数の構文表記については、「関数」の項を参照してください。
文字列の出力(echo, print)
文字列の出力には、echo または print を使用します。
echo
echo は実際には関数ではありません (言語構造です)。このため、使用する際に括弧は必要ありません。
複数のパラメータを指定して echo をコールしたい場合、括弧の中にパラメータを記述してはいけません。
<?php echo "Hello World"; echo "<br>"; echo 'This ', 'string ', 'was ', 'made ', 'with multiple parameters.', "<br>"; // echo 命令の中で変数を使用することが可能です $foo = "foobar"; echo "foo is $foo"; ?>
This string was made with multiple parameters.
foo is foobar
echo の短縮形
通常、echo は以下のように記述します。
<?php echo $foo; ?>
echo の短縮形を使うと以下のように記述することができます。
<?= $foo ?>
HTML 文書内で PHP の変数を表示させる場合などに便利です。
<tr> <td><?= $title ?></td> <td><?= $name ?></td> <td><?= $email ?></td> <td><?= $content ?></td> </tr>
この方法は、PHP 5.4.0 以降では常に(php.ini の short_open_tag が OFF や無効の場合でも)使えます。
参考:「 HTML からの脱出」
print は実際には関数ではありません (言語構造です)。このため、引数を括弧で括る必要はありません。
<?php print "Hello World"; print "<br>"; print "escaping characters is done \"Like this\".<br>"; // echo 命令の中で変数を使用することが可能です $bar = "barbaz"; print "foo is not $bar"; ?>
escaping characters is done "Like this".
foo is not barbaz
echo と print の違い
- echo は引数を複数指定できる。
- echo は関数のコンテキスト中では使用することができない。
- print は戻り値を返す。(但し、常に1が返るのであまり意味がない)
echo は関数のように動作しないので、以下のコードは正しくありません。
($some_var) ? echo 'true' : echo 'false';
以下のように命令を変更すれば、動作します。
echo $some_var ? 'true': 'false';
print を使った、次の例は動作します。print も言語構造ですが、関数のように動作します。
($some_var) ? print 'true' : print 'false';
echo/print で真偽値を出力
echo や print で真偽値の値(true と false)を出力すると、true の場合は 1 が、false の場合は空文字が出力されます。
<p>echo false :<?php echo false; ?></p> <p>echo true :<?php echo true; ?></p> <p>print false :<?php print false; ?></p> <p>print true :<?php print true; ?></p>
以下が出力結果です。
<p>echo false :</p> <p>echo true :1</p> <p>print false :</p> <p>print true :1</p>
クォーテーション " と '
変数を使用する場合
文字列を出力するときは、echo でも print でもダブルクォート「"」またはシングルクォート「'」で文字列を囲みます。
文字列を直接記述する場合は、どちらでも結果は同じですが、変数を使用する場合は結果が異なるので注意が必要です。
<?php $moji = "abcde"; echo "$moji <br>"; echo '$moji <br>'; print "$moji <br>"; print '$moji <br>'; ?>
$moji
abcde
$moji
ダブルクォート内では、変数がその中の値で展開されます。
また、文字列の変数の前後に日本語などがあったり、変数と文字列の間に空白がないと、変数の展開に失敗する場合があります。そのような場合は変数を波括弧 { } で囲むことで変数名を正しく認識させることができます。
<?php $moji = "abcde"; echo "{$moji}日本語"; ?>
または、文字列結合演算子を使って以下のように記述することもできます。
<?php $moji = "abcde"; echo $moji .'日本語'; ?>
特殊文字を扱う場合
もう1つの違いは、改行、タブなどを表す特殊文字(エスケープシーケンス)が使えるかどうかです。
ダブルクォートの中では、改行を表す「\n」やタブを表す「\t」等が使用できますが、シングルクォートの中では、文字としてそのまま出力されます。
HTML での表示では、改行「\n」は無視されるので、ソースで確認するか、以下のように <pre> タグで出力すると確認できます。
<pre> <?php echo "abcde\nfghi"; echo "<br>"; echo 'abcde\nfghi'; ?> </pre>
abcde fghi
abcde\nfghi
シングルクォートやダブルクォートを表示
シングルクォートやダブルクォート自体を表示する場合、シングルクォートの中にシングルクォートをそのまま記述するとエラーになります。同様にダブルクォートの中にダブルクォートをそのまま記述するとエラーになります。
<?php echo '''; //エラーになる。 //Parse error: syntax error, unexpected ''; ' ... ?>
シングルクォートを表示したい場合は、ダブルクォートの中に記述するか、「\」でエスケープします。
同様にダブルクォートを表示したい場合は、シングルクォートの中に記述するか、「\」でエスケープします。
<?php echo "'"; echo "<br>"; echo '\''; echo "<br>"; echo '"'; echo "<br>"; echo "\""; ?>
'
"
"
変数
変数とは、値(データ)を入れておく箱(入れ物)のようなものです。一度値を箱に入れておけば、その箱が存在する間はその値が保持されます。また、箱の中の値を入れ換える(変更する)ことも取り出すこともできます。
変数の扱い方は、プログラミング言語によって様々です。Java や C# のような言語では、変数の利用に先立って変数名とデータの型を宣言する必要がありますが、PHP では変数の宣言を必要としません。
PHP では、スクリプト内で変数が始めて使用されたタイミングで、自動的に変数のための領域がメモリ上に確保されます。
<?php $sample = "sample text"; print $sample; ?>
上記の例では、$sample という名前の変数が確保されて、その中に「sample text」という文字列がセットされています。
変数の命名規則
PHP の変数の命名規則は以下のようになっています。
- 変数名は、$ で始まること
- 変数名の2文字目は英字かアンダースコアであること(数字はNG)
- 変数名の3文字目以降は、英数字、アンダースコアのいずれかであること
- 変数名の大文字・小文字は区別される
変数のデータ型
PHP では、変数が中身に応じて自動的に型を変えてくれるので、データ型をあまり意識する必要はありませんが、厳密な演算や比較を行う場合は、データ型を念頭においてコードを書く必要があります。
PHP には以下のようなデータ型があります。
型名 | 説明 |
---|---|
整数型 / integer | 「1」「3」「-125」「307」などの小数点をもたない整数。10進数だけでなく、16進数、8進数、2進数(PHP 5.4以降)を扱うこともできる。 |
浮動少数点型 / float(double) | 「1.09」「0.65」「-5.29685」などの少数以下の数値がある数値。 |
文字列型 / string | 「あいうえお」「abcde」「漢字」などの文字列 |
論理型 / boolean | 「TRUE」もしくは「FALSE」。真偽の値を表します。この値は大文字小文字を区別しない。 |
型名 | 説明 |
---|---|
オブジェクト型 / object | オブジェクトを扱うデータ型。 |
配列型 / array | 配列を扱うデータ型。PHPにおける配列(array)には、連想配列や多次元配列も含まれる。 |
型名 | 説明 |
---|---|
ヌル型 / null | 「NULL」 この値は大文字・小文字を区別しない。ヌル型は値に「何もない」事を表す特殊な型。NULL型であるとみなすのは、定数「NULL」を代入した変数、値を代入していない変数、unset()関数で破棄した変数。 |
リソース型 / resource | ファイルや、データベースなど、外部リソースへのリファレンスを扱うデータ型。 |
スカラー型
単一の値を取る型をスカラー型と言い、以下の4種類があります。
- 論理値 (boolean)
- 整数 (integer)
- 浮動小数点数(float, double)
- 文字列 (string)
これらの型の数字や文字列といった一つの値を持ったものをスカラー値と言います。
型キャスト
PHP は、変数定義時に明示的な型定義を必要と(または、サポート) しません。ある変数の型は、その変数が使用される文により定義されます。 これは、ある文字列を変数 var に代入した場合には、 var は文字列になることを意味しています。 ある整数値を var に代入した場合には、 その変数は整数になります。(PHPマニュアル:型の相互変換 より)
値の厳密な比較や演算を行う場合や小数点数を整数に変換したい場合等では、「型キャスト」を利用することで、変数に対してデータ型を強制的に割り当てることができます。
以下は、小数点数を整数に変換する例です。
<?php $data = 12.78; print (int)$data; ?>
使用可能なキャストは以下の通りです。
- (int), (integer) - 整数へのキャスト
- (bool), (boolean) - 論理値へのキャスト
- (float), (double), (real) - float へのキャスト
- (string) - 文字列へのキャスト
- (array) - 配列へのキャスト
- (object) - オブジェクトへのキャスト
- (unset) - NULL へのキャスト (PHP 5)
可変変数 $$
変数名を変数によって決めることができる変数のことを、可変変数と言います。
可変変数では、$ マークを2つ続けることによって、変数名を別の変数値で動的に決定することができます。
以下の例は、変数 $a に 'hello' という値がセットされているので、可変変数 $$a は $hello と同じ意味になります。
<?php $a = 'hello'; $hello = 'world'; print $$a; ?>
以下は、foreach 構文を使って連想配列の値を、そのキーの名前を変数名とする変数に格納する例です。
<?php $data = array('php' => 'PHP Hypertext Preprocessor', 'html' => 'Hyper Text Markup Language', 'ajax' => 'Asynchronous JavaScript And XML', 'css' => 'Cascading Style Sheet'); foreach($data as $key => $val){ $$key = $val; //可変変数 } echo $php . "<br>"; echo $ajax . "<br>"; echo $data['php'] . "<br>"; //echo $php . "<br>";と同じ echo $data['ajax'] . "<br>"; //echo $ajax . "<br>";と同じ ?>
Asynchronous JavaScript And XML
PHP Hypertext Preprocessor
Asynchronous JavaScript And XML
動的に変数名を生成 ${ }
可変変数は前述の方法($$)以外に、${ } と記述する方法があります。
例えば以下のように記述すると、単なる文字列として解釈されるため「$foo」と言う文字列が出力されます。
<?php $foo = 'test'; echo '$'. 'foo'; //$foo と言う文字列が出力される ?>
変数名の $ 以外の部分を文字列を使って動的に生成する場合は、以下のように記述することができます。
<?php $foo = 'test'; echo ${'foo'}; //test と出力される(echo $foo; と同じ) /* または以下でも同じ結果になります */ $foo = 'test'; $key = 'foo'; echo ${ $key }; ?>
以下は、前項同様に foreach 構文 を使って連想配列 の値を、そのキーの名前を変数名とする変数に格納する例です。
<?php $data = array('php' => 'PHP Hypertext Preprocessor', 'html' => 'Hyper Text Markup Language', 'ajax' => 'Asynchronous JavaScript And XML', 'css' => 'Cascading Style Sheet'); foreach($data as $key => $val){ ${$key} = $val; //変数名($ キー名) = 値 として変数を登録 } foreach($data as $key => $val){ echo ${$key} .'<br>'; //変数名($ キー名)を指定して値を出力 } ?>
Hyper Text Markup Language
Asynchronous JavaScript And XML
Cascading Style Sheet
スーパーグローバル変数
PHP には、内部的に生成される変数として「スーパーグローバル変数」があります。これは主にクライアントからサーバーに送信されたデータを管理するための変数で、HTML フォームから送信されたデータやクッキーなどの情報を取得することができます。
以下は、PHP で利用できる主なスーパーグローバル変数です。
変数名 | 説明 |
---|---|
$_POST | POST 形式で HTML フォームから渡された情報 |
$_GET | クエリ情報「?キー名=値」(GET 形式)で渡された情報 |
$_FILES | アップロードされたファイルに関する情報 |
$_SERVER | サーバ環境変数に関する情報 |
$_ENV | 環境変数に関する情報 |
$_COOKIE | クッキー経由で渡された情報 |
$_SESSEION | セッション経由で渡された情報 |
$_REQUEST | $_POST、$_GET、$_FILES、$_COOKIE の値をまとめて管理 |
$GLOBALS | グローバル変数にアクセス(グローバル変数への参照) |
$_REQUEST は、$_POST、$_GET、$_FILES、$_COOKIE の値をまとめて扱えるため便利なように見えますが、「同名のキーがあった場合、片方のキーが上書きされてしまう」、「どこからのデータかが曖昧になりやすい」等の理由から、原則として使用しないほうが良いとされています。
以下は、$_SERVER の内容を表示する例です。
<?php foreach($_SERVER as $key => $value) { echo "<strong>$key: </strong> $value <br>"; } ?>
CONTEXT_DOCUMENT_ROOT: /home/xxxxx/public_html/webdesignleaves.com
CONTEXT_PREFIX:
DOCUMENT_ROOT: /home/xxxxxx/public_html/webdesignleaves.com
GATEWAY_INTERFACE: CGI/1.1
HTTP_ACCEPT: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
HTTP_ACCEPT_ENCODING: gzip, deflate
HTTP_ACCEPT_LANGUAGE: ja,en-US;q=0.7,en;q=0.3
HTTP_CONNECTION: keep-alive
HTTP_COOKIE: _ga=GA1.2.1016787119.1402434254; visited=visited; _gat=1
HTTP_HOST: www.webdesignleaves.com
HTTP_REFERER: https://www.webdesignleaves.com/pr/
HTTP_USER_AGENT: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:41.0) Gecko/20100101 Firefox/41.0
PATH: /bin:/usr/bin
PHP_AUTH_PW: xxxxxx
PHP_AUTH_USER: xxxxxx
QUERY_STRING:
REDIRECT_STATUS: 200
REMOTE_ADDR: xxx.xxx.xxx.xxx
REMOTE_PORT: xxxxxx
REMOTE_USER: xxxx
REQUEST_METHOD: GET
REQUEST_SCHEME: http
REQUEST_URI: /pr/php/php_basic_01.php
SCRIPT_FILENAME: /home/xxxxxxpublic_html/webdesignleaves.com/pr/php/php_basic_01.php
SCRIPT_NAME: /pr/php/php_basic_01.php
SERVER_ADDR: xxxx.xxxx.xxx.228
SERVER_ADMIN: xxxx@webdesignleaves.xxxxxx.com
SERVER_NAME: www.webdesignleaves.com
SERVER_PORT: 80
SERVER_PROTOCOL: HTTP/1.1
SERVER_SIGNATURE:
SERVER_SOFTWARE: Apache
UNIQUE_ID: xxxxxxxxxxxxxxxxxxxxxxxx
PHP_SELF: /pr/php/php_basic_01.php
REQUEST_TIME: 1444948237
argv: Array
argc: 0
$_SERVER
$_SERVER(環境変数)にはヘッダ、パス、プロトコル、IP などの情報が格納されています。この変数からそのページの URL やホスト名などを取得することができます。以下は、ローカル環境(http://localhost/)での例です。
アクセスされているページの URL を取得
以下で取得できるのは、http や https などのプロトコル名やサーバーのドメイン名(ホスト名:この例では localhost)を除いた URL になります。
<?php echo $_SERVER["REQUEST_URI"]; ?>
/pr/php/php_basic_01.php
アクセスされているページのホスト名を取得
<?php echo $_SERVER["HTTP_HOST"]; ?>
www.webdesignleaves.com
同じような値を取得できる環境変数に $_SERVER["SERVER_NAME"] がありますが、$_SERVER["SERVER_NAME"] で取得できる値(名前)はサーバーの設定により異なります。
$_SERVER["HTTP_HOST"] は HTTP でアクセスしたときのホスト名(メイン名:ポート番号※指定されていれば)、つまり Request Header の Host: で指定した値になります。
アクセスされているページのプロトコル名を取得
$_SERVER["HTTPS"]は、プロトコルが HTTPS でない場合は定義されていないため「空」になっているので、empty() を使って調べてその結果により三項演算子を使ってプロトコル名を返すようにしています。
<?php echo (empty($_SERVER["HTTPS"]) ? "http://" : "https://"); ?>
https://
$_SERVER['HTTPS'] が取得出来ない場合
サーバー変数 $_SERVER['HTTPS'] が取得出来ないサーバーもあります。
現在使用しているサーバーもその例で、このサーバーの場合は、$_SERVER['HTTP_X_FORWARDED_PROTO'] の値を確認するように以下を記述してプロトコルを判定する必要があります。
if(isset($_SERVER['HTTP_X_FORWARDED_PROTO']) and $_SERVER['HTTP_X_FORWARDED_PROTO'] === "https") { $_SERVER['HTTPS'] = 'on'; }
クエリ文字を取得
クエリ文字とはクライアントからサーバにパラメータを渡すのに使われる表記法で、URL の末尾に「?」マークを付け、続けて「名前=値」の形式で記述される文字列のことです。
<?php echo $_SERVER['QUERY_STRING']; ?>
URL の組み立て
前述の変数を組み合わせると完全な URL を取得できます。以下はクエリ文字も含めての URL になります。
<?php echo (empty($_SERVER['HTTPS']) ? 'http://' : 'https://').$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']; ?>
https://www.webdesignleaves.com/pr/php/php_basic_01.php
$_SERVER['HTTPS'] が取得できないサーバーでは、以下のように記述するとうまくいくかも知れません(サーバーや環境に依存)。
<?php if(isset($_SERVER['HTTP_X_FORWARDED_PROTO']) and $_SERVER['HTTP_X_FORWARDED_PROTO'] === "https") { $_SERVER['HTTPS'] = 'on'; } echo (empty($_SERVER['HTTPS']) ? 'http://' : 'https://').$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']; ?>
$_SERVER["REQUEST_URI"] の代わりに $_SERVER['SCRIPT_NAME'] を使用すると、クエリ文字の付かない URL を取得できます。
<?php echo (empty($_SERVER['HTTPS']) ? 'http://' : 'https://').$_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME']; ?>
https://www.webdesignleaves.com/pr/php/php_basic_01.php
$_SERVER['DOCUMENT_ROOT']
ドキュメントルート(ドメイン直下)のパスを返してくれます。サーバーのコンフィグレーションファイル(httpd.conf)で定義されています。
<?php echo $_SERVER['DOCUMENT_ROOT']; ?>
/home/username/public_html/webdesignleaves.com
ファイルの読み込みなどの場合、$_SERVER['DOCUMENT_ROOT'] はドキュメントルートのパスを返してくれるので、インクルードしたいファイルのドキュメントルートからのパスを付けて記述します。読み込む階層が異なっていてもパスを変更する必要がないので便利です。
<?php include_once($_SERVER['DOCUMENT_ROOT'] . "/path/file.php"); ?>
$_SERVER['PHP_SELF']
$_SERVER['PHP_SELF']はクエリ文字列(?以降のクエリパラメータ)を含みませんが、PATHINFO も含めてしまうため、そのまま出力すると XSS(クロスサイトスクリプティング)に脆弱になる場合があるので注意が必要です。
ファイル名以降のパスを含むため、例えば URL エンコードされた「/%22%3E%3Cscript%3Ealert(%27XSS%27);%3C/script%3E/」のような文字列を URL の最後に付け加えると index.php/<script>alert(XSS)</script> とすることができてしまいます。
そのため、$_SERVER['PHP_SELF']を出力する(変数を出力する)場合は、htmlspecialchars 関数でエスケープする必要があります。($_SERVER['PHP_SELF'] の代わりに $_SERVER['SCRIPT_NAME'] を用いることも可能です)
<?php echo htmlspecialchars($_SERVER['PHP_SELF'], ENT_QUOTES, 'UTF-8'); ?>
/pr/php/php_basic_01.php
以下も PHP_SELF と同様の変数ですので注意が必要です。
- $_SERVER['PATH_INFO']
- $_SERVER['PATH_TRANSLATED']
関連項目:form タグの action 属性
変数や定数
PHP 変数 | 説明 |
---|---|
$_SERVER[ 'SCRIPT_NAME' ] | 現在のスクリプトのパス(スクリプト自身のページ)。ホームディレクトリからのパスを含むファイルの名前 |
$_SERVER[ 'HTTP_HOST' ] | アクセスされているページのホスト名 |
$_SERVER[ 'REQUEST_URI' ] | ページにアクセスするために指定された URI。(例) '/index.html' |
$_SERVER[ 'DOCUMENT_ROOT' ] | 現在実行されているスクリプトが存在するドキュメントルートディレクトリ(ドメイン直下のパス) |
$_SERVER[ 'PHP_SELF' ] | 現在実行しているスクリプトのファイル名。通常 $_SERVER[ 'SCRIPT_NAME' ]と同じ値(出力時はエスケープが必要) |
__DIR__ | カレント(読み込まれた)ファイルの存在するディレクトリ |
__FILE__ | カレント(読み込まれた)ファイルのパスとファイル名 |
dirname() | 親ディレクトリのパスを返す関数 |
basename() | パスの最後にある名前の部分を返す関数 |
realpath() | 正規化された絶対パス名を返す関数。空の文字列を指定した場合はカレントディレクトリを指定したものとみなす |
pathinfo() | ファイルパスに関する情報を返す関数。dirname、basename、extension、filename をキーとして連想配列を返す |
以下のような表を PHP ファイルで作成すれば、上記の変数などの出力を確認できます。
<table> <tr> <th>PHP</th> <th>出力結果(echo)</th> </tr> <tr> <td>$_SERVER[ 'SCRIPT_NAME' ]</td> <td><?php echo $_SERVER[ 'SCRIPT_NAME' ]; ?></td> </tr> <tr> <td>dirname( $_SERVER[ 'SCRIPT_NAME' ] )</td> <td><?php echo dirname( $_SERVER[ 'SCRIPT_NAME' ] ); ?></td> </tr> <tr> <td>basename( $_SERVER[ 'SCRIPT_NAME' ] )</td> <td><?php echo basename( $_SERVER[ 'SCRIPT_NAME' ] ); ?></td> </tr> <tr> <td>$_SERVER[ 'HTTP_HOST' ]</td> <td><?php echo $_SERVER[ 'HTTP_HOST' ]; ?></td> </tr> <tr> <td>$_SERVER[ 'REQUEST_URI' ]</td> <td><?php echo $_SERVER[ 'REQUEST_URI' ]; ?></td> </tr> <tr> <td>dirname( $_SERVER[ 'REQUEST_URI' ] )</td> <td><?php echo dirname( $_SERVER[ 'REQUEST_URI' ] ); ?></td> </tr> <tr> <td>$_SERVER[ 'DOCUMENT_ROOT' ]</td> <td><?php echo $_SERVER[ 'DOCUMENT_ROOT' ]; ?></td> </tr> <tr> <td>dirname( $_SERVER[ 'DOCUMENT_ROOT' ] )</td> <td><?php echo dirname( $_SERVER[ 'DOCUMENT_ROOT' ] ); ?></td> </tr> <tr> <td>htmlspecialchars( $_SERVER[ 'PHP_SELF' ], ENT_QUOTES, 'UTF-8' )</td> <td><?php echo htmlspecialchars( $_SERVER[ 'PHP_SELF' ], ENT_QUOTES, 'UTF-8' ); ?></td> </tr> <tr> <td> __DIR__</td> <td><?php echo __DIR__; ?></td> </tr> <tr> <td>dirname( __DIR__ )</td> <td><?php echo dirname( __DIR__ ); ?></td> </tr> <tr> <td>__FILE__</td> <td><?php echo __FILE__; ?></td> </tr> <tr> <td>dirname( __FILE__ )</td> <td><?php echo dirname( __FILE__ ); ?></td> </tr> <tr> <td>realpath( "" ) または realpath( "." ) </td> <td><?php echo realpath("") ?></td> </tr> <tr> <td>realpath( ".." )</td> <td><?php echo realpath( ".." ) ?></td> </tr> </table>
test.php というファイルに上記を記述してローカル環境で実行した例。
PHP | 出力結果(echo) |
---|---|
$_SERVER[ 'SCRIPT_NAME' ] | /pr/php/test.php |
dirname( $_SERVER[ 'SCRIPT_NAME' ] ) | /pr/php |
basename( $_SERVER[ 'SCRIPT_NAME' ] ) | test.php |
$_SERVER[ 'HTTP_HOST' ] | webdesignleaves.localhost |
$_SERVER[ 'REQUEST_URI' ] | /pr/php/test.php |
dirname( $_SERVER[ 'REQUEST_URI' ] ) | /pr/php |
$_SERVER[ 'DOCUMENT_ROOT' ] | /Applications/MAMP/htdocs/webdesignleaves |
dirname( $_SERVER[ 'DOCUMENT_ROOT' ] ) | /Applications/MAMP/htdocs |
htmlspecialchars( $_SERVER[ 'PHP_SELF' ], ENT_QUOTES, 'UTF-8' ) | /pr/php/test.php |
__DIR__ | /Applications/MAMP/htdocs/webdesignleaves/pr/php |
dirname( __DIR__ ) | /Applications/MAMP/htdocs/webdesignleaves/pr |
__FILE__ | /Applications/MAMP/htdocs/webdesignleaves/pr/php/test.php |
dirname( __FILE__ ) | /Applications/MAMP/htdocs/webdesignleaves/pr/php |
realpath( "" ) または realpath( "." ) | /Applications/MAMP/htdocs/webdesignleaves/pr/php |
realpath( ".." ) | /Applications/MAMP/htdocs/webdesignleaves/pr |
$_SERVER[ 'SCRIPT_NAME' ] からそのパスに含まれるディレクトリ名を分割して取得する例
$dirs は $_SERVER[ 'SCRIPT_NAME' ] をスラッシュで分割した値(ディレクトリ名)の配列
echo $_SERVER[ 'SCRIPT_NAME' ].'<br>'; $dirs = explode( "/", $_SERVER[ 'SCRIPT_NAME' ] ); echo '<br>配列の要素数(パスに含まれるディレクトリ数+1) ' ; echo '<br>count($dirs) : ' . count( $dirs ); echo '<br><br>配列の要素を出力(1番目[0]は空)<br>'; $count = 0; foreach ( $dirs as $directory ) { echo '<br>☆ $dirs[' . $count . ']:' . $directory; $count++; }
このページでの実行結果(例)
/pr/php/php_basic_01.php 配列の要素数(パスに含まれるディレクトリ数+1) count($dirs) : 4 配列の要素を出力(1番目[0]は空) ☆ $dirs[0]: ☆ $dirs[1]:pr ☆ $dirs[2]:php ☆ $dirs[3]:php_basic_01.php
var_dump()
var_dump() は変数に関する情報を表示します。以下が構文です。
void var_dump ( $expression [,$... ] )
この関数は、指定した式に関してその型や値を含む構造化された情報(変数の内容や命令の戻り値)を表示します。配列の場合、その構造を表示するために各値について再帰的に探索されます。
パラメータ
expression:調べたい変数。複数の変数や命令を確認したい場合は、引数をカンマで区切って指定することも出来ます。
戻り値
値を返しません。
ブラウザ上では、改行などが取り除かれた状態で表示されるので、必要に応じて pre 要素で囲むなどすると見やすくなります。または、ブラウザの「ソース表示」機能を利用します。
<?php $x = "foo"; var_dump($x); //string(3) "foo" //string は内容の型を、(3) は長さ文字列のバイト数を、ダブルクォート内が内容(値)を表します。 $y = "テスト"; $z = 123.456; var_dump($y, $z); //string(9) "テスト" //float(123.456) $array = ['a', 2, FALSE]; var_dump($array); /* array(3) { [0]=> string(1) "a" [1]=> int(2) [2]=> bool(false) } */ ?>
string(3) "foo"
string(9) "テスト" float(123.456)
array(3) { [0]=> string(1) "a" [1]=> int(2) [2]=> bool(false) }
isset()
isset() 関数は指定された変数が定義されているかどうかを調べます。変数が存在して NULL 以外の値をとれば TRUE、 そうでなければ FALSE を返します。
以下が構文です。
bool isset ( $var )
パラメータ
- var(mixed):調べたい変数。
戻り値
var が存在して NULL 以外の値をとれば TRUE、 そうでなければ FALSE を返します。
以下はサンプルです。
<?php $var = ''; // これは TRUE と評価されるので、テキストが出力されます。 if (isset($var)) { echo "変数 \$var は存在します(セットされています)。<br>"; } // 次の例では、var_dump を使って isset() の戻り値を出力します。 $aaa = "test"; $bbb; var_dump(isset($aaa)); // TRUE echo "<br>"; var_dump(isset($bbb)); // FALSE echo "<br>"; var_dump(isset($xyz)); // FALSE ?>
bool(true)
bool(false)
bool(false)
変数の削除
unset() 関数は、指定した変数の割当を解除(変数を削除)します。以下が構文です。
void unset ( $var [, $var... ] )
パラメータ
- var(mixed):破棄する変数。複数ある場合はカンマ区切りで記述します。
戻り値
値を返しません。
以下は変数($who)を削除して、isset() で変数が定義されているかどうかを調べています。
<?php $who = "foo"; var_dump( isset( $who ) ); //存在するので true echo "<br>"; unset($who); var_dump( isset( $who ) ); //削除されているので false ?>
bool(false)
複数の変数を削除する場合は、カンマ区切りで指定します。
<?php $value1 = 1; $value2 = 2; $value3 = 3; echo '$value1: ' .$value1 ."<br>"; echo '$value2: ' .$value2 ."<br>"; echo '$value3: ' .$value3 ."<br>"; unset($value1, $value2, $value3); echo "//値を表示しようとすると削除され未定義のためエラーが表示されます。"; echo '$value1: ' .$value1 ."<br>"; echo '$value2: ' .$value2 ."<br>"; echo '$value3: ' .$value3 ."<br>"; ?>
$value2: 2
$value3: 3
//値を表示しようとすると削除され未定義のためエラーが表示されます(xampp の例)
Notice: Undefined variable: value1 in C:\xampp\htdocs\webdesignleaves\pr\php\php_basic_01.php on line 1175
$value1:
Notice: Undefined variable: value2 in C:\xampp\htdocs\webdesignleaves\pr\php\php_basic_01.php on line 1176
$value2:
Notice: Undefined variable: value3 in C:\xampp\htdocs\webdesignleaves\pr\php\php_basic_01.php on line 1177
$value3:
※配列やその要素の削除については「配列・要素の削除」を参照ください。
変数の有効範囲(スコープ)
変数には有効範囲(スコープ)があります。通常、変数はスクリプト内のどこでも有効であり、この場合の変数のスコープを「グローバル」と言います。そしてそのような変数を「グローバル変数」と呼びます。
但し、関数定義内で使用される変数は、スコープが関数定義内のみなり、このような変数はローカル変数と呼びます。
そしてグローバル変数とローカル変数は、たとえ同じ名前であっても異なるものとみなされます。
<?php $g = "global"; //グローバル変数 function test() { echo "### ここから test() の内容 ### <br>"; echo $g ; //ローカル変数(未定義)→Notice: Undefined variable: g (エラー) var_dump($g); //未定義なので Notice エラーが表示され NULL と出力される $g = "local"; //ローカル変数を設定 echo "<br>" . $g . "<br>" ; //local と出力される global $g; //グローバル変数 echo $g . "<br>"; //global と出力される echo "### ここまで test() の内容 ### <br><br>"; } test(); //上記を実行 echo "グローバル変数: " . $g; ?>
### ここから test() の内容 ### Notice: Undefined variable: g in /.../php_basic_01.php on line xxxx Notice: Undefined variable: g in /.../php_basic_01.php on line xxxx NULL local global ### ここまで test() の内容 ### グローバル変数: global
関数内でグローバル変数を使用したい場合は「global」キーワードを指定します。但し、グローバル変数はどこで値が設定・変更されているかわかりづらいため、多用するとソースコードが読みにくくなりバグの原因ともなるので、できるだけ利用しない方が良いとされています。
グローバル変数は、include 文や require 文により読み込まれたファイル内でも有効になります。
また、スーパーグローバル変数は、関数内でも global キーワードを指定することなく利用できる特殊なグローバル変数です。
配列
通常の変数では、データを1つしか代入することができませんが、配列を使うと1つの変数に複数の値を代入することができます。
配列は仕切りのある箱のようなものと考えるとわかりやすいかも知れません。仕切りで区切られた箱(スペース)のそれぞれには、数値または文字列で名前を付けることができます。
数値で識別される配列を「通常配列」、文字列で認識される配列を「連想配列」と言ったりします。
配列を作成する方法は大きく分けると2つあります。
array 命令で作成
array 命令の構文は以下の通りです。
変数名 = array(要素1, 要素2, 要素3, ...);
変数名 = array(キー1 => 要素1, キー2 => 要素2, ...);
array 命令では、配列に格納したい要素をカンマ区切りで記述します。キーが省略された場合は、キー名には「その時点でのキーの最大値+1」が割り当てられます。
ブラケット [ ] で添え字(インデックス番号/キー)を指定すると配列の要素にアクセスできます。
<?php $data = array("JavaScript", "C++", "PHP", "Perl"); echo $data[1]; ?>
また、以下のように記述しても同じ内容の配列を生成することができます。
$data = array(0 => "JavaScript", 1 => "C++", 2 => "PHP", 3 => "Perl");
$data = array(); $data[] = "JavaScript"; $data[] = "C++"; $data[] = "PHP"; $data[] = "Perl";
配列のブラケット [ ] に添え字を指定せずに代入を行うと、必ず配列の末尾に要素が追加されます。
連想配列の場合は、配列の添え字を数値ではなく、文字列で指定します。PHP では通常の配列と連想配列に厳密な区別はなく、同じように使うことができます。また、PHP の連想配列は要素を追加した順番を保持しています。
<?php $data = array('php' => 'PHP: Hypertext Preprocessor', 'html' => 'Hyper Text Markup Language', 'ajax' => 'Asynchronous JavaScript And XML', 'css' => 'Cascading Style Sheet'); echo $data['ajax']; ?>
ブラケット構文で作成
ブラケット構文を使うと、配列の個々の要素に値をセットすることができます。
<?php $data[ 0 ] = "JavaScript"; //配列 $data を新たに生成 $data[ 1 ] = "C"; $data[ 2 ] = "PHP"; $data[ 3 ] = "Perl"; $data[ 1 ] = "C++"; //2番目の要素を書き換え $data[] = "Ruby"; //末尾に要素を追加 var_dump($data); ?>
array(5) { [0]=> string(10) "JavaScript" [1]=> string(3) "C++" [2]=> string(3) "PHP" [3]=> string(4) "Perl" [4]=> string(4) "Ruby" }
<?php $data = array("JavaScript", "C++", "PHP", "Perl"); $data[0] = "Java"; //0番目の要素を書き換え $data[] = "Ruby"; //末尾に要素を追加 echo $data[0], "<br>"; echo $data[4]; ?>
Ruby
通常の配列と連想配列
PHPでは、通常の配列(数値添え字)と連想配列に違いはなく、配列の型は1つしかありません。添え字を省略した場合、「数値添え字の最大値+1」が自動的に添え字となります。
以下の配列は全く同じ配列になります。
<?php $a = array(5 => "EEE", "FFF", "GGG", "x" => 99); $b = array(5 => "EEE", 6 => "FFF", 7 => "GGG", "x" => 99); ?>
配列の短縮構文(PHP5.4 以降)
PHP 5.4.0 から、配列の短縮構文が追加され、array() を [] と記述することができます。
//PHP 5.3 までの構文 変数名 = array(要素1, 要素2, 要素3, ...); //短縮構文 変数名 = [要素1, 要素2, 要素3, ...];
//PHP 5.3 までの構文 変数名 = array(キー1 => 要素1, キー2 => 要素2, ...); //短縮構文 変数名 = [キー1 => 要素1, キー2 => 要素2, ...];
以下は前述のサンプルを短縮構文で書き換えたものです。
<?php $data = ["JavaScript", "C++", "PHP", "Perl"]; echo $data[1]; ?>
$data = [ 'php' => 'PHP: Hypertext Preprocessor', 'html' => 'Hyper Text Markup Language', 'ajax' => 'Asynchronous JavaScript And XML', 'css' => 'Cascading Style Sheet' ]; echo $data['ajax'];
range()を使った配列の生成
range() を使うと引数で指定した開始値から終了値まで順番に増加する配列を作成することができます。
数字やアルファベット(1文字)の配列を作成するときに使用できます。以下が構文です。(構文表記については「関数」を参照ください。但し、引数の型は省略しています)
array range ( $start , $end [, $step ] )
パラメータ
- start:最初の値
- end:最後の値
- step:要素毎の増加数(正の数でなければなりません)。デフォルトは 1 です。
戻り値
start から end までの配列を返します。
<?php $data1 = range(1, 10); echo '$data1 = range(1, 10);'."<br>"; print_r($data1); $data2 = range(10, 1); echo "<br>".'$data2 = range(10, 1);'."<br>"; print_r($data2); $data3 = range(0, 100, 10); echo "<br>".'$data3 = range(0, 100, 10);'."<br>"; print_r($data3); $data4 = range("a", "g"); echo "<br>".'$data4 = range("a", "g");'."<br>"; print_r($data4); $data5 = range("a", "z", 2); echo "<br>".'$data5 = range("a", "z", 2);'."<br>"; print_r($data5); ?>
$data1 = range(1, 10);
Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => 5 [5] => 6 [6] => 7 [7] => 8 [8] => 9 [9] => 10 )
$data2 = range(10, 1);
Array ( [0] => 10 [1] => 9 [2] => 8 [3] => 7 [4] => 6 [5] => 5 [6] => 4 [7] => 3 [8] => 2 [9] => 1 )
$data3 = range(0, 100, 10);
Array ( [0] => 0 [1] => 10 [2] => 20 [3] => 30 [4] => 40 [5] => 50 [6] => 60 [7] => 70 [8] => 80 [9] => 90 [10] => 100 )
$data4 = range("a", "g");
Array ( [0] => a [1] => b [2] => c [3] => d [4] => e [5] => f [6] => g )
$data5 = range("a", "z", 2);
Array ( [0] => a [1] => c [2] => e [3] => g [4] => i [5] => k [6] => m [7] => o [8] => q [9] => s [10] => u [11] => w [12] => y )
多次元配列
array 命令を入れ子(ネスト)構造で記述することで、多次元の配列を表現することもできます。
<?php $data = array( array('鈴木', '女'), array('山田','男'), array('田中','男') ); print $data[2][0]; ?>
<?php $data = array( array('name' => 'Smith', 'age' => 33), array('name' => 'Davis', 'age' => 57), array('name' => 'Kelly', 'age' => 17) ); print $data[2]['name']; ?>
配列の内容をデバッグ表示
配列の内容をデバッグ表示するには、print_r()関数, var_dump()関数, var_export() 関数のいずれかを使います。
ブラウザ上では、改行などが取り除かれた状態で表示されるので、必要に応じて pre 要素で囲むなどすると見やすくなります。または、ブラウザの「ソース表示」機能を利用します。
関数名 | 説明 |
---|---|
print_r() | 変数の情報を人間が見てわかり易い形式で表示 |
var_dump() | print_r() とほぼ同じだが、データ型や要素数などの情報も表示される |
var_export() | PHP スクリプトの形式で表示 |
<?php $data = array( array('name' => 'Smith', 'age' => 33), array('name' => 'Davis', 'age' => 57), array('name' => 'Kelly', 'age' => 17) ); echo "<pre>"; echo "<br><strong>print_r()関数</strong><br>"; echo print_r($data); echo "<br><strong>var_dump()関数</strong><br>"; echo var_dump($data); echo "<br><strong>var_export()関数</strong><br>"; echo var_export($data); echo "</pre>"; ?>
print_r()関数
Array ( [0] => Array ( [name] => Smith [age] => 33 ) [1] => Array ( [name] => Davis [age] => 57 ) [2] => Array ( [name] => Kelly [age] => 17 ) ) 1
var_dump()関数
array(3) { [0]=> array(2) { ["name"]=> string(5) "Smith" ["age"]=> int(33) } [1]=> array(2) { ["name"]=> string(5) "Davis" ["age"]=> int(57) } [2]=> array(2) { ["name"]=> string(5) "Kelly" ["age"]=> int(17) } }
var_export()関数
array ( 0 => array ( 'name' => 'Smith', 'age' => 33, ), 1 => array ( 'name' => 'Davis', 'age' => 57, ), 2 => array ( 'name' => 'Kelly', 'age' => 17, ), )
定数
変数は代入された値によって変化しますが、定義するとそのままで変化しない値が定数です。
変数は、プログラム上で意味を持つ値にあらかじめ名前をつけておく仕組みのようなものです。
また、定数は一度定義した定数を再定義することはできません。
define() 関数
定数を使うには、define() 関数で定数を定義します。以下が define() 関数の構文です。
define ( '定数名' , '値' , TRUE )
3番目のパラメータはオプションで、大文字・小文字を区別しない場合は TRUE を指定します。省略すると(デフォルトでは)大文字・小文字を区別します。また、通常定数は全て大文字を使用します。
define() 関数は、定数の定義に成功したときに TRUE を、失敗したときに FALSE を返します。定数が未定義だったり、再定義された場合は FALSE を返し、Notice エラーを出力します。
以下は税抜き価格 $price に対して、1.05 を乗算して税込価格を求める例です。
<?php $price = 1780; $amount = $price * 1.05; ?>
このような式がスクリプトに何回も出現していると、もし消費税率が変更になった場合、それらの全てを修正する必要があります。
以下のように消費税率を定数として定義しておけば、もし消費税率が変更になっても定数の値を変更するだけで済みます。
<?php define('TAX', 1.05); //ここの1箇所のみの変更で済む $price = 1780; $amount = $price * TAX; ?>
定数の特徴
- 定数は、前にドル記号($)を要しません。
- 定数は、英字かアンダースコアが使えます。
- 通常、変数と区別するために、全て大文字にします。
- 定数は、プログラムのどこからでもアクセスできます。
- 定数は一度設定されると再定義または未定義とすることはできません。
参考:定数・構文
予め定義された定数
代表的な予め定義された定数には以下のようなものがあります。
定数名 | 内容 |
---|---|
PHP_VERSION | PHP のバージョン |
PHP_OS | PHP を実行している OS |
TRUE | 論理値:真 |
FALSE | 論理値:偽 |
NULL | 値がないことを示す |
マジック定数(自動的に定義される定数)
使われ方によって変化する自動的に定義される以下のような定数(マジカル定数)があります。
定数名 | 内容 |
---|---|
__LINE__ | ファイル上の現在の行番号。 |
__FILE__ | ファイルのフルパスとファイル名。 |
__DIR__ | そのファイルの存在するディレクトリ。 |
__FUNCTION__ | 関数名。 |
__CLASS__ | クラス名。 |
__METHOD__ | クラスのメソッド名。 |
__NAMESPACE__ | 現在の名前空間の名前。 |
__TRAIT__ | トレイト名。 |
定義済み定数の表示
get_defined_constants() 関数を使うと、定義済み定数の一覧を取得することができます。
PHP にはたくさんの定義済み定数がありますが、使用している環境によって異なるため、get_defined_constants() 関数を使って調べます。
get_defined_constants() 関数は配列を返すので、print_r() 関数や var_dump() を使って出力します。
<?php echo "<pre>"; print_r(get_defined_constants(true)); echo "</pre>"; ?>
以下は print_r() を使った際の出力例です。
Array ( [Core] => Array ( [E_ERROR] => 1 [E_RECOVERABLE_ERROR] => 4096 [E_WARNING] => 2 [E_PARSE] => 4 [E_NOTICE] => 8 [E_STRICT] => 2048 [E_DEPRECATED] => 8192 [E_CORE_ERROR] => 16 [E_CORE_WARNING] => 32 [E_COMPILE_ERROR] => 64 [E_COMPILE_WARNING] => 128 [E_USER_ERROR] => 256 [E_USER_WARNING] => 512 [E_USER_NOTICE] => 1024 [E_USER_DEPRECATED] => 16384 [E_ALL] => 32767 [DEBUG_BACKTRACE_PROVIDE_OBJECT] => 1 [DEBUG_BACKTRACE_IGNORE_ARGS] => 2 [TRUE] => 1 [FALSE] => [NULL] => [ZEND_THREAD_SAFE] => 1 ・・・以下省略・・・
エスケープシーケンス
キーボードから直接入力できない特殊文字や特別な意味を持つ記号($ など)を「\ + 文字」の形式で表すことができます。このような文字のことをエスケープシーケンスと呼びます。
PHP で利用可能なエスケープシーケンスには以下のようなものがあります。
文字 | 概要 |
---|---|
\r | 復帰 |
\n | 改行 |
\t | タブ |
\$ | ドル記号 |
\\ | 円記号(バックスラッシュ) |
\" | ダブルクォーテーション |
エスケープシーケンスは任意の文字列に含めることができますが、対象の文字列は必ずダブルクォーテーションで囲まなければならない点に注意してください。
シングルクォーテーション内では、文字列は記述されたそのままに解釈されます。
<?php echo "\$\\\"\n<br>"; echo '\$\\\"\n<br>'; ?>
\$\\"\n
演算子
PHP には、数値や文字列などに対して特定の処理を行うための演算子が数多く用意されています。
算術演算子
四則演算等の数学的な演算を行う演算子です。
演算子 | 概要 | 例 |
---|---|---|
+ | 加算 | 1 + 2 //3 |
- | 減算 | 5 - 3 //2 |
* | 乗算 | 3 * 7 //21 |
/ | 除算 | 9 / 3 //3 |
% | 剰余(余り) | 10 % 4 //2 |
++ | 前置加算 | $x = 5; $a = ++ $x; //$a は 6 |
++ | 後置加算 | $x = 5; $a = $x ++; //$a は 5 |
-- | 前置減算 | $x = 3; $a = -- $x; //$a は 2 |
-- | 後置減算 | $x = 3; $a = $x --; //$a は 3 |
インクリメント演算子(++)、デクリメント演算子(--)
インクリメント演算子(++)はオペランドに1を加算し、デクリメント演算子(--)はオペランドから1を減算します。
$x++ は $x = $x + 1 と同じことです。
$x-- は $x = $x - 1 と同じことです。
但し、これらの演算子で演算した結果を、他の変数に代入する場合は演算子をオペランドの前に置くか後に置くかで結果がことなります。
<?php $x = 5; $y = $x ++; echo $x, "<br>"; //6 echo $y, "<br>"; //5 //$x を $y に代入してから、$x のインクリメントを行う $x = 5; $y = ++ $x; echo $x, "<br>"; //6 echo $y, "<br>"; //6 //$x をインクリメントしてから、 $y に代入を行う ?>
5
6
6
代入演算子
指定された変数に値を代入する演算子です。
演算子 | 概要 | 例 |
---|---|---|
= | 値を代入 | $x = 3; //$x に 3 を代入 |
+= | 左辺の値に右辺の値を加算したものを代入 | $x = 5; $x += 2; //$x は 7 |
-= | 左辺の値に右辺の値を減算したものを代入 | $x = 5; $x -= 2; //$x は 3 |
*= | 左辺の値に右辺の値を乗算したものを代入 | $x = 5; $x *= 2; //$x は 10 |
/= | 左辺の値に右辺の値を除算したものを代入 | $x = 5; $x /= 2; //$x は 2.5 |
%= | 左辺の値に右辺の値を除算した余りを代入 | $x = 5; $x %= 2; //$x は 1 |
.= | 左辺の値に右辺の値を連結した文字列を代入 | $x = "A"; $x .= "B"; //$x は "AB" |
複合代入演算子
$x += 2 は $x = $x + 2 と同じことです。
$x ■= 2 は $x = $x ■ 2 //■ は +, -, *, /, % , .
<?php $x = 5; $x += 2; echo $x, "<br>"; $y = "A"; $y .= "B"; echo $y; ?>
AB
参照渡し
参照とは、同じ変数の内容への別名です。通常の「=」での変数の代入は、変数の値のコピーが代入され、これは「値渡し」と呼ばれます。「=&」での代入は「参照渡し」と呼ばれ、2つの変数が同じものを指します。
<?php $a = 10; $b = &$a; echo '$b =', $b, "<br>"; //$a の値を30に変更すると $a = 30; echo '$b =', $b, "<br>"; //$a が変更されたのを受けて $b も30と表示される ?>
$b =30
※ 参照渡しを乱用するとコードの流れや見通しが悪くなり、発見しにくいバグの原因になる場合があるので注意が必要です。
式の中に代入演算子を入れる
以下のように式の中に代入演算子を入れることも可能です。
<?php $x = ($y = 300) * 3; echo '$x =', $x, "<br>"; echo '$y =', $y; ?>
$y =300
これは、以下のように記述したのと同じことになります。
<?php $y = 300; $x = $y * 3; echo '$x =', $x, "<br>"; echo '$y =', $y; ?>
比較演算子
左辺と右辺の値を比較して、その評価の結果を TRUE / FALSE (真偽値の定数)として返します。主に、if, while, do...while 命令などの条件式で使用します。
演算子 | 概要 | 例 |
---|---|---|
== | 左辺と右辺の値が等しい場合は true | 7 == 7 //true |
!= | 左辺と右辺の値が等しくない場合は true | 7 != 7 //false |
<> | 左辺と右辺の値が等しくない場合は true | 7 <> 7 //false |
< | 左辺が右辺より小さい場合は true | 7 < 5 // false |
<= | 左辺が右辺以下の場合は true | 7 <= 7 //true |
> | 左辺が右辺より大きい場合は true | 7 > 5 // true |
>= | 左辺が右辺以上の場合は true | 7 >= 9 //false |
=== | 左辺と右辺の値が等しく、かつデータ型が同じ場合は true | 5 === "5" // false |
!== | 左辺と右辺の値が等しくない場合、またはデータ型が異なる場合は true | 5 !== "5" //true |
? : | 条件式 ? 式1: 式2 条件式が true の場合は式1を、false の場合は式2を返す | (x == 1) ? 1 : 0 // |
以下のように、数値の比較をしてみます。「10 == 10」の評価の結果が TRUE なので、定数 TRUE の値である 1 が出力されます。
<?php echo 10 == 10; ?>
整数値と文字列を比較してみます。この場合も結果には 1 が表示されて、「10 == "10"」は TRUE だということがわかります。
<?php echo 10 == "10"; ?>
「===」を使って、整数値と文字列を比較してみます。この場合は何も出力されません。これは出力結果が NULL だからで、定数 FALSE の値は NULL と同意なので、「10 === "10"」の比較は FALSE だということがわかります。これは、値は同じでも、型が違うため FALSE が返ります。
<?php echo 10 === "10"; ?>
論理演算子
複数の条件式を論理的に結合して、その結果を TRUE / FALSE (真偽値の定数)として返します。通常は前述の比較演算子と組み合わせて利用します。
演算子 | 概要 | 例 |
---|---|---|
&& | 左右の式が共に TRUE の場合は TRUE | 10 == 10 && 5 == 5 //TRUE |
|| | 左右の式のどちらかが TRUE の場合は TRUE | 3 == 3 || 4 == 5 //TRUE |
and | 左右の式が共に TRUE の場合は TRUE | 10 == 10 and 5 == 4 //FALSE |
or | 左右の式のどちらかが TRUE の場合は TRUE | 3 == 2 or 5 == 3 //FALSE |
xor | 左右の式のどちらか片方のみが TRUE (もう片方は FALSE)の場合は TRUE | 3 == 2 xor 5 == 5 //TRUE |
! | 式が FALSE の場合は TRUE | !(10 > 500) //TRUE |
演算子の優先順位
例えば、3 + 4 * 5 の結果は 23 になり、35 にはなりません。これは乗算の方が優先順位が高いためです。(3 + 4) * 5 のように括弧を使うと、括弧内の演算が優先されるので、結果は 35 になります。
同様に PHP の演算子にも、優先順位があります。優先したい演算を括弧で括ることで、優先順位を変更することができます。
また、優先順位が等しい場合は、結合性(左から評価するか、右から評価するか)に基づき優先順位が決まります。
例えば "-" は左結合なので、 1 - 2 - 3 は (1 - 2) - 3 とグループ分けされて、 評価結果は -4 になります。 一方、"=" は右結合なので、右から評価され $a = $b = $c のグループ分けは $a = ($b = $c) となります。
厳密には不要な場所であっても、括弧をつけておけばコードの可読性があがります。 明示的にグループ分けをしておくことで、演算子の優先順位や結合性による暗黙のグループ分けに頼らずに済むからです。
- 次の表では、優先順位が高い順に演算子を挙げています。
- 同じ行にある演算子は優先順位が等しくなります。
- 優先順位が等しい場合は、 結合時の評価(左から評価するか、右から評価するか)にしたがってグループ分けが決まります。
結合時の評価 | 演算子 | 追加情報 |
---|---|---|
結合しない | clone new | clone , new |
left | [ | array() |
right | ** | 代数演算子 |
right | ++ -- ~ (int) (float) (string) (array) (object) (bool) @ | 型 , 加算子/減算子 |
結合しない | instanceof | 型 |
right | ! | 論理演算子 |
left | * / % | 代数演算子 |
left | + - . | 代数演算子 , 文字列演算子 |
left | << >> | ビット演算子 |
結合しない | < <= > >= | 比較演算子 |
結合しない | == != === !== <> <=> | 比較演算子 |
left | & | ビット演算子 , リファレンス |
left | ^ | ビット演算子 |
left | | | ビット演算子 |
left | && | 論理演算子 |
left | || | 論理演算子 |
right | ?? | 比較演算子 |
left | ? : | 三項演算子 |
right | = += -= *= **= /= .= %= &= |= ^= <<= >>= => | 代入演算子 |
left | and | 論理演算子 |
left | xor | 論理演算子 |
left | or | 論理演算子 |
left | , | さまざまな利用法 |
以下は、代入演算子(=)と論理演算子(|| と or)の組み合わせの例です。
<?php $x = false || true; $y = false or true; echo var_dump($x) ."<br>"; //bool(true) echo var_dump($y) ."<br>"; //bool(false) ?>
bool(false)
$x = false || true; の場合、論理演算子(||)の方が代入演算子(=)より優先度が高いので、以下のように記述することと同じ意味になります。このため括弧内が評価されて、true が $x に代入されます。
$x = (false || true);
$y = false or true; の場合、代入演算子(=)の方が論理演算子(or)より優先度が高いので、以下のように記述することと同じ意味になります。
($y = false) or true;
以下は、代入演算子(=)と論理演算子(&& と and)の組み合わせの例です。(前述の例とは、true と false の記述順が異なります)
<?php $x = true && false; //$x = (true && false); $y = true and false; //($y = true) and false; echo var_dump($x) ."<br>"; //bool(false) echo var_dump($y) ."<br>"; //bool(true) ?>
bool(true)
or の論理演算式
or の論理演算式を使って以下のように記述されていることがあります。
<?php $fp = @fopen("sampleX.text", "r+b") or die("ファイルを開けません"); ?>
これは、or の論理演算式で、最初にファイルのオープン「fopen()」を実行して、これが成功(TRUE)だった場合 or が成立(どちらかが真の場合)するので、その後の die() は実行されず、無視されます。
ファイルのオープンに失敗した場合「fopen()」は戻り値として FALSE を返すので、die() が実行されます。
二重の論理否定演算子
! は論理否定演算子で、真偽の値を逆転する演算子です。!の後の内容が TRUE なら FALSE を返し、FALSE なら TRUE を返します。
真偽値を逆転させるので、二回連続で適用すると、TRUE が FALSE になり、そして TRUE に戻ります。
これによって TRUE の値(ゼロ以外の数字、空ではない文字列や配列)に対して論理演算子の値は TRUE となり、FALSE の値(0や0.0、空の文字列や配列)に対して論理演算子の値は FALSE になります。
これは、値に二回否定演算子を適用することで真偽値(Boolean)として取得する1つの方法です。
<?php $foo = ""; var_dump($foo); //string(0) "" var_dump(!$foo); //bool(true) var_dump(!!$foo); //bool(false) var_dump((bool)$foo); //bool(false) キャスト $bar = null; var_dump($bar); //NULL var_dump(!$bar); //bool(true) var_dump(!!$bar); //bool(false) var_dump((bool)$bar); //bool(false)キャスト $baz = []; var_dump($baz); //array(0) {} var_dump(!$baz); //bool(true) var_dump(!!$baz); //bool(false) var_dump((bool)$baz); //bool(false)キャスト $zero = 0; var_dump($zero); //int(0) var_dump(!$zero); //bool(true) var_dump(!!$zero); //bool(false) var_dump((bool)$zero); //bool(false)キャスト ?>
$foo="";
var_dump($foo) --> string(0) "" var_dump(!$foo) --> bool(true) var_dump(!!$foo) --> bool(false) var_dump((bool)$foo) --> bool(false)
$bar = null;
var_dump($bar) --> NULL var_dump(!$bar) --> bool(true) var_dump(!!$bar) --> bool(false) var_dump((bool)$bar) --> bool(false)
$baz = array();
var_dump($baz) --> array(0) { } var_dump(!$baz) --> bool(true) var_dump(!!$baz) --> bool(false) var_dump((bool)$baz) --> bool(false)
$zero = 0;
var_dump($zero) --> int(0) var_dump(!$zero) --> bool(true) var_dump(!!$zero) --> bool(false) var_dump((bool)$zero) --> bool(false)
文字列結合演算子
JavaScript などでは、プラス「+」で文字列を結合できますが、PHP ではドット「.」で文字列を結合することができます。
<?php $apple = "apple"; $banana = "banana"; $string = $apple." ".$banana; echo $string; print "<br>".$string." orange"; ?>
apple banana orange
以下は、複合代入演算子を使う例です。
<?php $string = ""; $string .= "apple"; $string .= " banana"; $string .= " orange"; echo $string; ?>
エラー制御演算子
式の先頭に「@」を付けることで、エラーメッセージを非表示にすることができます。
例えば、以下では 0 で除算を行っていますが、これは許されていないので「Warning: Division by zero in ...xxx.php on line 1516」のようなエラーが表示されます。
<?php print 1/0; ?>
しかし、式の先頭に「@」を付けると、エラーメッセージが抑制されて表示されないようになります。
<?php @print 1/0; ?>
これは一見便利なようですが、開発時にはエラーの原因を隠蔽してしまうためデバッグ作業を困難にする原因にもなるので注意が必要です。
参考:エラー制御演算子
if 文/三項演算子
プログラムでは、条件に応じて処理を分岐することができます。PHP では、分岐するための命令として、if 命令、三項演算子、switch 命令が用意されています。
if 文
if 文は「もし~ならば、....を実行する」という構造を表現するためのもので、特定の条件を満たしている(TRUE)場合にのみ処理を実行する構文です。
if(条件) { 条件にあっている場合に実行する処理 }
以下の場合、$x の値は10で $x が5以上と言う条件を満たしているので、「$x は5以上です」と出力されます。もし、$x の値が5未満の場合は何も実行されません。
<?php $x = 10; if($x >= 5) { echo '$x は5以上です。'; } ?>
else を使って、条件を満たしていない(FALSE)場合の処理を設定することもできます。
if(条件) { 条件にあっている(TRUE)場合に実行する処理 }else{ 条件にあっていない(FALSE)場合に実行する処理 }
以下の場合、$x の値は3で $x が5以上と言う条件を満たしていないので、else 節が実行され「$x は5未満です」と出力されます。
<?php $x = 3; if($x >= 5) { echo '$x は5以上です。'; }else{ echo '$x は5未満です。'; } ?>
条件にあっていない場合に、elseif() または else if() を使って更に別の条件を追加することもできます。
※「elseif」と「else if」は同じ意味ですが、「波括弧を使わない if 文」の場合は「elseif」を使わないとエラーになるので注意が必要です。参考:「elseif/else if」
if(条件1) { 条件1にあっている場合に実行する処理 }elseif(条件2) { 条件1にあっていない場合で、条件2にあっている場合に実行する処理 }else{ 条件1、条件2にあっていない場合に実行する処理 }
以下の場合、x の値は3で x が5以上と言う最初の条件を満たしていませんが、次の x が3以上と言う条件を満たしているため、コンソールに「x は3以上5未満です」と表示されます。
<?php $x = 3; if($x >= 5) { echo '$x は5以上です。'; }elseif($x >= 3) { echo '$x は3以上5未満です。'; }else{ echo '$x は5未満です。'; } ?>
ここで注意が必要なのは、条件式を記述する順番です。
以下の場合、最初の条件式($x >= 3)に合致して1番目のブロックが実行されるので、2番目以降のブロックは実行されず、「$x は3以上です」と表示されます。
<?php $x = 100; if($x >= 3) { echo '$x は3以上です。'; }elseif($x >= 5) { echo '$x は5以上です。'; }else{ echo '$x は5未満です。'; } ?>
if 命令では、前方から順番に条件式の判定を行います。if 命令で分岐されたブロックは、複数の条件に合致する場合でも、実行されるブロックは最初のひとつだけです。
三項演算子
if 命令を使わないで、三項演算子を使って記述する方法もあります。
三項演算子は、指定された条件式の真偽に応じて対応する式の値を出力する場合に使用します。以下がその構文です。
条件式 ? 式1(TRUE の場合) : 式2(FALSE の場合);
三項演算子は先頭の条件式を判定してその結果により値を返します。
先頭の条件式が TRUE の場合は式1の値を返し、先頭の条件式が FALSE の場合は式2の値を返します。
<?php $x = 3; echo ($x >= 5) ? '$x は5以上です。' : '$x は5未満です。'; ?>
同じことを if 命令を使って記述すると以下のようになります。
<?php $x = 3; if($x >= 5) { echo '$x は5以上です。'; }else{ echo '$x は5未満です。'; } ?>
三項演算子で echo を使用する場合は少し注意が必要です。以下のように記述するとエラー(Parse error: syntax error, unexpected 'echo' )になります。
<?php $x = 3; ($x >= 5) ? echo '$x は5以上です。' : echo '$x は5未満です。'; //Parse error: syntax error, unexpected 'echo' エラーになる ?>
以下のように print を使用すればエラーになりません。
<?php $x = 3; ($x >= 5) ? print '$x は5以上です。' : print '$x は5未満です。'; ?>
波括弧を使わない if 文
PHP では、波括弧を使わず、コロン(:)と endif を使った if 文があり、以下のように記述することもできます。
<?php $x = 20; if($x >= 5) : echo '$x は5以上です。'; else: echo '$x は5未満です。'; endif; ?>
以下のような使い方をします。
<?php $username = ''; ?> <?php if ($username == 'Suzuki'): ?> <p>Suzuki さん、こんにちは</p> <?php elseif ($username == 'Tanaka'): ?> <p>Tanaka さん、こんにちは</p> <?php else: ?> <p>名無しさん、こんにちは</p> <?php endif; ?>
波括弧を使わず、コロン(:)と endif を使った if 文の場合、elseif を else if と記述するとエラーになるので注意が必要です。
名無しさん、こんにちは
参考:PHP マニュアル「制御構造に関する別の構文」
switch 文
if 文を使って、if(){...} elseif(){...} elseif(){...}... のようにブロックを組み合わせれば、複雑な多岐分岐を実現できますが、見通しが悪くなる可能性があります。同一の変数に対して比較を行う場合は、switch 文を使うと簡潔に記述することができます。
以下が switch 文の書式です。
switch(式) { case 値1 : 式 == 値1である場合に実行する処理 break; case 値2 : 式 == 値2である場合に実行する処理 break; case 値3 : 式 == 値3である場合に実行する処理 break; ...... ...... default : 式の値が全ての値に合致しない場合に実行される処理 }
switch 文は以下のような流れで処理が行われます。
- 「式」の値が評価されます。
- 1. の値に合致する case ブロックが実行されます。
- 合致する case ブロックがない場合は、default ブロックが実行されます。
default ブロックはオプションで必須ではありませんが、省略しない方がどの条件にも合致しなかった場合の挙動を明確にできるので記述するようにします。実行する処理がなければ、空にしておきます。
以下のサンプルでは、「Bレベル」と出力されます。
<?php $level = "B"; switch($level) { case "A" : echo "Aレベル"; break; case "B" : echo "Bレベル"; break; case "C" : echo "Cレベル"; break; default : echo "不明"; } ?>
各 case ブロックの最後に break; 命令を指定していますが、これは現在のブロックから脱出するための命令です。break; 命令がないと、次の case ブロックが実行されてしまうので注意が必要です。
但し、次のサンプルのように、意図的に break; 命令を記述しない場合もあります。値が A または B の場合は「ハイレベル」と表示されます。
<?php $level = "B"; switch($level) { case "A" : case "B" : echo "ハイレベル"; break; case "C" : echo "中レベル"; break; default : echo "不明"; } ?>
以下は、date() 関数を使って曜日を出力する例です。date("w") は0 (日曜)から 6 (土曜)を返します。
<?php switch(date("w")) { case 0: echo "It's Sunday"; break; case 1: echo "It's Monday"; break; case 2: echo "It's Tuesday"; break; case 3: echo "It's Wenesday"; break; case 4: echo "It's Thursday"; break; case 5: echo "It's Friday"; break; case 6: echo "It's Saturday"; break; default: echo "ここには来ません。"; } ?>
上記は switch 文の例のためのもので、実際は date("l") を使えば曜日を返してくれます。
<?php echo "It's ". date("l"); ?>
波括弧を使わない switch 文
switch 文も波括弧を使わず、コロン(:)と endswitch を使った switch 文があります。
<?php $level = "A"; switch($level) : case "A" : echo "Aレベル"; break; case "B" : echo "Bレベル"; break; case "C" : echo "Cレベル"; break; default : echo "不明"; endswitch; ?>
但し、switch 文と最初の case の間で何か (空白文字も含む) を出力すると、構文エラーになるので注意が必要です。 以下は無効なコードの例です。
<?php switch ($bar): ?> <?php case 1: ?> ... <?php endswitch ?>
switch 文の行末の改行文字は終了タグ ?> の一部と見なされるため、 switch と case の間では何も出力されないので、以下のコードは有効です。
<?php switch ($bar): ?> <?php case 1: ?> ... <?php endswitch ?>
参考:PHP マニュアル「制御構造に関する別の構文」
while 文/ do while 文
while 文は、与えられた条件が TRUE(真)である間、ループを繰り返します。以下が書式です。
while(条件式) { 条件式が TRUE(真)である場合実行する処理 }
以下は x の値が10以下の場合、繰り返し処理が行われます。
<?php $x = 7; while($x <= 10) { echo $x ."<br>"; $x++; //$x の値を1増加 } ?>
8
9
10
while 文では、条件式がどこかの時点で FALSE(偽)になるようにします。
上記のサンプルでは n++; により n の値を増加させ、いずれは $x <= 10 が FALSE になるようにしてあります。
もし n++; がなければ、無限ループになりブラウザはフリーズしてしまいます。
波括弧を使わない while 文
while 文も波括弧を使わず、コロン(:)と endwhile を使った while 文があります。
<?php $x = 7; while($x <= 10) : echo $x ."<br>"; $x++; //$x の値を1増加 endwhile; ?>
8
9
10
以下のような使い方をします。
<?php $i = 1; ?> <?php while ($i <= 3): ?> <?php echo $i++, '<br />'; ?> <?php endwhile; ?>
2
3
do while 文
以下は、while 文のバリエーションの do while 文の構文です。
do{ 条件式が TRUE(真)である場合実行する処理 }while(条件式) ;
while 文では、ループの最初に条件判定をしますが、 do while 文ではループの後に条件判定をします。このため do while 文では、条件の真偽に関わらず、必ず1回ループが処理されます。
<?php $x = 11; do{ echo $x ."<br>"; $x++; }while($x <= 10); // 11 と表示される $x = 11; while($x <= 10) { echo $x ."<br>"; $x++; } //何も表示されない ?>
for 文
for 文は、あらかじめ指定された回数だけ繰り返し処理を実行します。以下は for 文の書式です。
for (初期化式 ; ループ継続条件式 ; 増減式) { ループ内で実行する処理 }
以下のサンプルは、カウンタ変数 $x が 0, 1, 2 の場合の3回処理が実行されます。
<?php for($x = 0; $x < 3; $x++) { echo '$x の値:' . $x . "<br>"; } ?>
$x の値:1
$x の値:2
for 文では、カッコ内の「初期化式」「ループ継続条件式」「増減式」の3つの式でループを制御します。
「初期化式」では、ループ回数を制御するカウンタ変数(上記では $x )を初期化します。変数名は任意の文字列が使えます。
「ループ継続条件式」は、ブロック内の処理を継続するための条件を設定します。ブロックの処理が1回実行されるたびに条件に合致するかを評価します。上記では $x が 3 未満という条件を設定。
「増減式」は、ブロックの処理が1回実行されるたびに実行されます。通常はカウンタ変数の増減を行うインクリメント/デクリメント演算子や代入演算子が使用されます。
前述の for 文は、以下のように while 文で記述することも可能です。
<?php $x = 0; while($x < 3) { echo '$x の値:' . $x . "<br>"; $x++; } ?>
$x の値:1
$x の値:2
複数の条件の設定
for 文のループ継続条件式に複数の条件が設定されている場合、その条件は「||」(または)条件になります。以下の例は、$x が5未満または $y が0未満の間だけループ処理されます。
<?php for($x = 0, $y = -10; $x < 5, $y < 0; $x++, $y += 3) { echo '$x の値:' . $x . "<br>"; echo '$y の値:' . $y . "<br>"; } ?>
$y の値:-10
$x の値:1
$y の値:-7
$x の値:2
$y の値:-4
$x の値:3
$y の値:-1
条件式の省略
全ての式を空白にすることもできます。この時、条件式を空白にすることにより、条件式が常に TRUE になります。この場合、必ずループを抜ける条件を記述して「break;」してループを抜ける必要があります。
<?php $x = 0; for(; ;) { echo '$x の値:' . $x . "<br>"; $x ++; if($x >= 3) {break;} } ?>
$x の値:1
$x の値:2
波括弧を使わない for 文
for 文も波括弧を使わず、コロン(:)と endfor を使った for 文があります。
<?php for($i = 0; $i < 100; $i ++) : echo $i; endfor; ?>
以下のような使い方をします。
<?php for ($i = 1; $i <= 3; $i++): ?> <?php echo $i, '<br />'; ?> <?php endfor; ?>
2
3
break/continue 命令
break 命令と continue 命令を利用すると、特定の条件下で繰り返し処理を中止したり、一部の処理をスキップすることができます。
break 命令
break 命令を利用すると、繰り返し処理の途中でループを抜けることができます。
以下は1~100までの値を加算して、合計が300を超えたときのループ変数を出力します。
<?php $sum = 0; for($i = 1; $i <= 100; $i ++) { if($sum >= 300) {break; } $sum += $i; } print '合計が100を超えるのは1~' . $i . 'までを加算したときです。'; ?>
continue 命令
continue 命令を利用すると、繰り返し処理の途中で処理をスキップすることができます。繰り返し処理の中で continue 命令を実行すると、現在のループをスキップして、次のループを継続して実行することができます。
以下は、1~10 までの偶数の値のみを加算する例です。
<?php $sum = 0; for($i = 1; $i <= 10; $i ++) { if($i % 2 != 0) {continue; } $sum += $i; } print "合計値は $sum です。"; ?>
入れ子になった繰り返し処理
while や for などでループ処理が2重以上ある場合に continue や break でループの階層を指定して、指定したループの階層をスキップしたり抜けたりすることができます。
指定する階層は、continue (break) 命令から見たループのレベルになります。continue (break) 命令の記述されたループの階層が「1」になります。また、省略された場合は「1」とみなされ、現在の構造のみをスキップまたは抜けることになります。
<?php $i = 0; while(1) { //2nd Loop $i++; echo "2nd Loop: $i <br>"; while(1) { //1st Loop echo "1st Loop<br>"; if( $i < 3) { continue 2; //2nd Loop の先頭へ戻る }else{ break 2; //2nd Loop を抜ける } echo "これは表示されません。"; } } ?>
1st Loop
2nd Loop: 2
1st Loop
2nd Loop: 3
1st Loop
foreach 文/配列のループ処理
foreach 文は配列の各要素に対して、繰り返し処理を行います。
foreach 文には2種類の構文があります。
foreach(配列 as 要素の値用の変数) { ループ処理 }
foreach(配列 as 要素の添え字用の変数 => 要素の値用の変数) { ループ処理 }
以下は配列の値を出力する例です。
<?php $fruit = array("Apple", "Melon", "Strawberry"); foreach($fruit as $value) { echo $value . " "; } ?>
以下は配列の添え字と値を出力する例です。
<?php $fruit = array("Apple", "Melon", "Strawberry"); foreach($fruit as $key => $value) { echo $key. ": " .$value . " "; } ?>
連想配列でも同様です。
<?php $data = array("Miles Davis" => "Jazz", "Steve Vai" => "Rock", "Yo Yo Ma" => "Classic"); foreach($data as $k => $v) { echo "$k : $v <br>"; } ?>
Steve Vai : Rock
Yo Yo Ma : Classic
波括弧を使わない foreach 文
foreach 文も波括弧を使わず、コロン(:)と endforeach を使った foreach 文があります。
<?php foreach($data as $value) : echo $value; endforeach; ?>
以下のような使い方をします。
<?php $fruits = array('Apple', 'Orange', 'Grape'); ?> <ul> <?php foreach ($fruits as $item): ?> <li><?php echo $item; ?></li> <?php endforeach; ?> </ul>
- Apple
- Orange
- Grape
foreach 文で配列へ要素の追加
以下は array_push() を使って foreach 文で $my_values の要素を1つずつ $new_array の最後に追加する例です。
先頭に追加する場合は、array_unshift() を使います。
<?php //この配列の要素を $new_array に追加 $my_values = [1,2,3]; //追加される配列 $new_array = array(); foreach ($my_values as $my_value){ array_push($new_array, $my_value); }; ?>
foreach 文でカウンタ変数を利用
for 文の場合、カウンタ変数がありますが foreach 文でも以下のようにすればカウンタ変数を設定して使うことができます。
カウンタ変数(以下の例では $i)を 0 で初期化しておき、配列の要素の個数を count() を使って取得しておきます。
foreach 文の中で $i の値を毎回1増加するようにしておけば、for 文とおなじようなことができます。
以下は名前の配列($names)の要素を li 要素で囲んで <ul><li></li></ul> の形式で出力する例です。
<?php $names = ["James", "David", "Alex"]; //$length は3 $length = count($names); $i = 0; //出力する HTML (初期状態) $output = "<ul>\n<li>"; //名前の間に追加する HTML $elements = "</li>\n<li>"; foreach($names as $name) { if($i == $length -1) { //最後の時だけ追加する HTML を変更 $elements = "</li>\n</ul>"; } $output .= $name . $elements; //毎回 1 増加させる $i ++; } echo $output; ?>
以下のような出力になります。
<ul> <li>James</li> <li>David</li> <li>Alex</li> </ul>
多次元配列のループ処理
以下は foreach() を使って、それぞれの要素を出力する例です。
<?php $data = array( array('鈴木', '女'), array('山田','男'), array('田中','男') ); foreach ($data as $value) { echo $value[0] . "<br>"; echo $value[1] . "<br>"; } ?>
女
山田
男
田中
男
以下は、foreach() をネストして処理する例です。
多次元配列の各要素の値を取得
<?php $data = array( array('鈴木', '女'), array('山田','男'), array('田中','男') ); foreach ($data as $v1) { foreach ($v1 as $v2) { echo "$v2 <br>"; } } ?>
女
山田
男
田中
男
多次元配列の各要素のキーと値を取得
<?php $data = array( array('鈴木', '女'), array('山田','男'), array('田中','男') ); foreach ($data as $k1 => $v1) { foreach ($v1 as $k2 => $v2) { echo "[{$k1}][{$k2}] : $v2 <br>"; } } ?>
[0][1] : 女
[1][0] : 山田
[1][1] : 男
[2][0] : 田中
[2][1] : 男
以下は、多次元の連想配列の例です。
<?php $data = array( "fruit" => array( "apple" => "りんご", "banana" => "ばなな", "orange" => "オレンジ" ), "Liquor" => array( "wine" => "ワイン", "beer" => "ビール", "sake" => "酒" ) ); foreach ($data as $k1 => $v1) { foreach ($v1 as $k2 => $v2) { echo "[{$k1}][{$k2}] : $v2 <br>"; } } ?>
[fruit][banana] : ばなな
[fruit][orange] : オレンジ
[Liquor][wine] : ワイン
[Liquor][beer] : ビール
[Liquor][sake] : 酒
ネストした配列の list() による展開
PHP 5.5 からは、値として list() を渡すと、 ネストした配列をループ変数に展開できます。 サポートされていない場合は、「Parse error: syntax error, unexpected T_LIST in ...」のようなエラーになります。
<?php $user = array( array('鈴木', '女', 22), array('山田','男', 19), array('田中','男', 37) ); foreach ($user as list($name, $gender, $age)) { echo "名前: $name /性別: $gender /年齢: $age <br>"; } ?>
以下のようにしても、同じ結果が得られます。(PHP 5.5 以前の方法)
<?php $users = array( array('鈴木', '女', 22), array('山田','男', 19), array('田中','男', 37) ); foreach ($users as $user) { list($name, $gender, $age) = $user; echo "名前: $name /性別: $gender /年齢: $age <br>"; } ?>
名前: 山田 /性別: 男 /年齢: 19
名前: 田中 /性別: 男 /年齢: 37
処理の終了 exit/die
exit() 関数や die() 関数を使用すると処理を終了することができます。それ以降のコードは実行されません。
exit() と die() は同じものです。以下が構文です。
void exit ([ $status ] )
パラメータ
- status(string/int):文字列の場合は、この関数は終了直前に status を表示します。(オプション)
status が integer の場合は その値が終了ステータスとして使われ、表示はされません。終了ステータスは 0 から 254 までの値でなければなりません。ステータス 0 は、 プログラムを正常終了させる際に使用します。
戻り値
値を返しません。
以下は、ファイルを開けなかった場合に、メッセージを表示してプログラムを終了するサンプルです。
<?php $filename = "someText.txt"; $fp = fopen($filename, 'r+b'); if(!$fp) { exit("ファイル({$filename})を開けませんでした"); } ?>
ファイルを開けなかった場合は以下のようなエラーとオプションで指定したメッセージが表示され、プログラムが終了します。
C:\xxxx\htdocs\xxxxxx\xxxxxx\php\php_basic_01.php on line 2965
ファイル(someText.txt)を開けませんでした
HTML の出力方法
echo や print 文で出力された内容は、ブラウザへと送信されます。また、直接 HTML で記述された内容も同様にブラウザに出力されます。以下のどの方法でも、ブラウザの「ソースの表示」で確認すると、全て同じ結果になります。
<html> <head><title>HTML output</title></head> <body>ABCD</body> </html> <!-- 全て直接 HTML で記述 -->
<?php echo "<html>\n"; echo "<head><title>HTML output</title></head>\n"; echo "<body>ABCD</body>\n"; echo "</html>\n"; ?> //全て PHP で出力
<?php echo ' <html> <head><title>HTML output</title></head> <body>ABCD</body> </html> '; ?> //全て PHP で出力(echo で全ての HTML を '' で囲む)
<html> <head><title>HTML output</title></head> <body> <?php echo "ABCD"; ?> </body> </html> <!--静的な部分を HTML で記述し、動的な部分を PHP で出力-->
以下は部分的に HTML と変数を出力する例です。以下の4つの例の出力結果は全て同じで以下のようになります。
<p class="text">出力内容</p>
以下の場合、変数を展開するために全体をダブルクォートで囲み、class 属性の値をシングルクォートで囲んでいます。(「クォーテーション " と '」を参照)
また、確実に変数を展開するために、変数を波括弧 { } で囲んでいます(波括弧はなくても問題なく変数を展開できる場合もあります)。
<?php $output = "出力内容"; echo "<p class='text'>{$output}<p>"; ?>
以下は、シングルクォーテーションと文字列の結合「.」を使う例です。
<?php $output = "出力内容"; echo '<p class="text">'. $output. '<p>'; ?>
以下は、ヒアドキュメントを使う例です。5行目の終了文字列の前後にスペース等が入っていてはいけません(Parse error: syntax error, unexpected end of file と言うエラーになります)。
<?php $output = "出力内容"; echo <<<OUT <p class="text">{$output}<p> OUT; ?>
以下は変数の部分のみ PHP タグで囲んで出力する例で、よく使われる方法です。
<?php $output = "出力内容"; ?> <p class="text"><?php echo $output;?><p>
一度 PHP を終了させて出力
以下のように一度 PHP の記述方法を終了させて PHP のエリアを区切って HTML を出力させることができます。
<?php if($condition) { ?> <p class="true">true の場合出力</p> <?php }else{ ?> <p class="false">false の場合出力</p> <?php } ?>
上記の場合、$condition が true であれば、以下の HTML が出力され、ブラウザには「true の場合出力」と表示されます。
<p class="true">true の場合出力</p>
以下は for 文を使った例です。
<ul> <?php for($i = 1; $i <= 5; $i++) { ?> <li>list # <?php echo $i; ?></li> <?php } ?> </ul>
上記の場合、以下の HTML が出力されます。
<ul> <li>list # 1</li> <li>list # 2</li> <li>list # 3</li> <li>list # 4</li> <li>list # 5</li> </ul>
ヒアドキュメント
長い文やまとまったブロックの HTML を出力したい場合、1行ずつ echo 文で出力するのは面倒です。ヒアドキュメントを利用することで、大量の文字列を出力することができます。
以下は、echo を使ったヒアドキュメントの構文です。
<?php echo <<<ID となる文字列 出力文字列を記述 ID となる文字列(終了文字列); ?>
ID となる文字列は、終了文字列と対になっていれば任意の文字列が使用できます。EOT でも EOD でも何でもかまいません。
終了文字列の行(17行目)には、終了文字列の前後にスペース等が入っていてはいけません。もし、スペースなどが入っていると「Parse error: syntax error, unexpected end of file」と言うエラーになるので注意が必要です。
また、ヒアドキュメント内に変数は代入された値が展開されてブラウザに送信(表示)されます。$ 記号を単なる文字として表示する場合は、「\$」とエスケープする必要があります。
<?php $word = "ヒアドキュメントの出力例"; echo <<<EOT <div class="table-responsive"> <table class="table table-bordered table-hover" style="max-width:600px;"> <caption>{$word}</caption> <tr> <th>命令</th> <th>内容</th> </tr> <tr> <td>echo</td> <td>echo は実際には関数ではありません (言語構造です)。このため、使用する際に括弧は必要ありません。</td> </tr> </table> </div> EOT ?>
命令 | 内容 |
---|---|
echo | echo は実際には関数ではありません (言語構造です)。このため、使用する際に括弧は必要ありません。 |
ヒアドキュメントでの変数の展開
ヒアドキュメント内の変数も、波括弧 { } で囲むことで確実に展開できます。
関数
PHP には予め豊富な関数が用意されています。
関数とは、与えられた入力に基づいて何らかの結果を返す(出力する)命令です。入力する値のことを引数(パラメータ)、出力のことを戻り値(返り値)と言います。
- 引数が2つ以上ある場合は、カンマ区切りで記述します。
- 引数が存在しない場合でも、関数名の後の括弧は省略できません。
- 関数によっては処理を行うだけで戻り値を持たないものもあります。
PHP で利用可能な関数は、オンラインの PHP マニュアルで調べることができます。以下は PHP マニュアルにおける基本的な構文表記です。
引数/戻り値のデータ型には、以下のようなものがあります。
データ型 | 内容 |
---|---|
array | 配列型 |
bool | 真偽型(TRUE/FALSE) |
float | 浮動小数点型 |
int | 整数型 |
mixed | 複数のデータ型を返す可能性がある場合 |
object | オブジェクト型 |
resource | リソース型 |
string | 文字列型 |
void | 戻り値がない場合 |
関数が戻り値を返さない場合、戻り値のデータ型は void と表記されます。また、処理の結果により異なる型を返す関数の場合、戻り値の型は mixed と表記されています。
ユーザー定義関数
PHP が提供する関数ではカバーされていない定型的な処理などは、ユーザーが独自に関数を定義することができ、そのような関数を「ユーザー定義関数」と呼びます。
ユーザー定義関数を定義するには、function 命令を使用します。以下が一般的な構文です。
function 関数名(仮引数1, 仮引数2, ...) { 処理の記述 return 戻り値; //オプション(必須ではない) }
仮引数とは関数定義時に使用される引数のことです。別の言い方をすると、ユーザー定義関数の処理内で参照可能な変数のことを言います。
また、実引数とはその関数を実際に使用するときに関数に引き渡される引数です。つまり、関数の実行時には、実引数の値が仮引数に代入されることになります。
以下は、簡単なユーザー定義関数の例です。repeatStrings 関数は、与えられた文字列($val)を指定回数($num)繰り返して表示します。また、3番目の引数($delim)が指定されていれば、その値を使って区切り文字とします。指定されていなければ、デフォルトで<br> を使用します。
<?php function repeatStrings($val, $num, $delim = "<br>") { for($i = 0; $i <= $num; $i ++) { print($val.$delim); } } //関数の実行 repeatStrings("Hello Universe!", 3, " -- "); ?>
関数のデフォルト引数(省略可能な引数)を定義するには、引数の定義で、「$変数=デフォルト値」の形式で指定します。これにより、引数が省略された場合、指定されたデフォルト値が使用されます。
但し、省略可能な引数は、必須の引数の後に配置する必要があります。以下のような記述はできません。
function repeatStrings($val, $delim = "<br>", $num) { ... }
戻り値
ユーザー定義関数が戻り値を持つ場合は、return 命令を使用して、処理結果を呼び出し元に返します。 return 命令が記述されなかった場合、ユーザー定義関数は戻り値を返しません。
以下は、引数に指定された値の二乗を返すユーザー定義関数の例です。
<?php function square($num) { return $num * $num; } //関数の実行 echo square(12); ?>
以下は、記述が長い関数の省略形を作る例です。
HTML では、& や < などの特別な意味を持つ文字は、& や < のような文字参照と呼ばれる表記に変換して記述する必要があります。PHP には、その処理を行う htmlspecialchars() と言う関数が用意されていますが、名前が長く、また引数を指定しなければなりません。通常以下のように記述します。
htmlspecialchars("対象の文字列", ENT_QUOTES, 'UTF-8');
これを毎回記述するのは、大変なので以下のようなユーザー定義関数を用意しておくと便利です。
<?php //function キーワードを使って、h() 関数を定義 function h($str) { $html = htmlspecialchars($str, ENT_QUOTES, 'UTF-8'); return $html; } $text = '<p>HTML では & は & と記述します</p>'; //関数の呼び出し $html = h($text); echo $html; ?>
上記をブラウザの HTML ソースで確認すると以下のようになっています。
<p>HTML では & は &amp; と記述します</p>
これにより、htmlspecialchars() という長い関数名とパラメータを指定せずに h() と記述するだけで同じことが可能になります。
外部ファイルの利用(include, require)
JavaScript などと同様に、PHP でも外部ファイルを取り込むことが可能です。共通に使用できる定数、関数、コードなどを外部ファイルに記述しておき利用することで管理が楽になります。
ファイルを取り込むには、「include」「require」「include_once」「require_once」の4つの命令を使用することができます。
include と require の違い
「include」と「require」の違いは、指定したファイルが読み込めなかった場合に、処理を継続するかどうかです。ファイルが読み込めなくても処理を継続するには「include」を使い、エラーで処理を停止したい場合は、「require」を使います。
_once
また、「_once」が付くものは、同じファイルを複数回読み込もうとした場合、最初の1回しか読み込みません。つまりファイルがすでに読み込まれている場合は再読み込みをしないということです。同じファイルが何回も読み込まれると関数の再定義などが起こり、エラーの原因となる場合もあります。(関数は再定義が不可)
通常、ファイルが読み込めなかった場合は致命的な障害になるのと、同じファイルを何度も読み込む必要はないので「include_once」を使うことが多いでしょう。
命令 | 動作 |
---|---|
include | 取り込むファイルがない場合 Warning エラーになるが、処理は継続される。 |
include_once | 取り込みは1度だけ。取り込むファイルがない場合 Warning エラーになるが、処理は継続される。 |
require | 取り込むファイルがない場合は Fatal エラーとなり終了。 |
require_once | 取り込みは1度だけ。取り込むファイルがない場合は Fatal エラーとなり終了。 |
引数
これらの命令は関数ではなく特別な言語構造であるため、 引数を囲む括弧 () は不要です。
引数は単なる文字列の場合はシングルクォート「'」で囲み、変数やエスケープシーケンスが入っている場合は、ダブルクォート「"」で囲みます(クォーテーション " と ' )。
例
以下を記述して、適当な名前(この例では、include_require.php)で保存します。
<?php for($i = 0; $i < 3; $i ++) { echo "外部ファイルです。<br>"; } ?>
そして、別のファイルで上記で作成したファイルを取り込んでみます。パスは記述するファイルを基点に指定します。
<?php echo "<strong>require</strong><br>"; require '../samples/PHP/include_require.php'; echo "<strong>include</strong><br>"; include '../samples/PHP/include_require.php'; ?>
取り込まれた「include_require.php」に記述されている内容が実行されます。
外部ファイルです。
外部ファイルです。
外部ファイルです。
include
外部ファイルです。
外部ファイルです。
外部ファイルです。
読み込まれるファイルのパスについて
読み込まれるファイルは、まず php.ini の include_path で設定されているディレクトリから検索し、次に、実行中の PHP ファイルのあるディレクトリ(カレントディレクトリ)を検索します。
複数の別の階層にあるファイルから読み込むような複雑な場合は、以下のようなコードを使うことで、include, require 命令が書かれているファイルの位置を基準に読み込まれるファイルを指定できます。
include_once 命令が書かれているファイルと同じディレクトリにある「foo.php」を読み込む場合は以下のようになります。
include_once realpath(dirname(__FILE__)). '/foo.php';
include_once 命令が書かれているファイルより1つ上のディレクトリの中の bar ディレクトリの中の「bar.php」を読み込む場合は以下のようになります。
include_once realpath(dirname(__FILE__)). '/../bar/bar.php';
dirname() は親ディレクトリのパスを返す関数です。 __FILE__ は現在の「.php」ファイルへのフルパスとファイル名を表すマジック定数です。
realpath () は、絶対パス名を返します。これはなくても、通常同じ結果になるので、省略してもほとんど変わりません(省略可能です)。
__DIR__ はそのファイルの存在するディレクトリを表すマジック定数で、 dirname(__FILE__) と同じ意味です。
<?php echo dirname(__FILE__)."<br>"; //出力 /home/username/public_html/webdesignleaves.com/pr/php echo realpath(dirname(__FILE__))."<br>"; //出力 /home/username/public_html/webdesignleaves.com/pr/php echo __DIR__; //出力 /home/username/public_html/webdesignleaves.com/pr/php ?>
以下のように $_SERVER['DOCUMENT_ROOT'] を使ってドキュメントルート(ドメイン直下)から指定すれば、呼び出す階層が違っていても書き換える必要がなく便利です。「path」はドキュメントルートからファイルまでのパスを指定します。
<?php include_once $_SERVER['DOCUMENT_ROOT'] . "/path/foo.php"; ?>
インクルードファイルでの注意点
以下のようなコードは、インクルードされる「lib/lib.inc」ファイルの中身がブラウザから表示できる可能性(ソースコードの流出)があります。
include 'lib/lib.inc';
これは、インクルードファイルの拡張子が .inc となっていて .php ではないので、Apache がテキストファイルであると認識してしまいファイルの中身を送信してしまうことと、インクルードファイルがブラウザからアクセスできる場所(ドキュメントルート以下)に置かれていることが原因です。
インクルードファイルは、ブラウザからアクセスする必要が全くないので、ドキュメントルートより上の階層に配置することによりこのようなことを防ぐことができます。また、インクルードファイルの拡張子は .php とします。
また、include や require 文(once も同様)で、引数にユーザーからの入力値が含まれる場合は、セキュリティ上の問題が生じるので注意が必要です。
共通部分をパーツ化
ヘッダーやフッター、ナビゲーションなどサイトのページの共通部分をパーツ化(外部ファイル化)して管理すると便利になります。
共通部分をパーツ化しておけば、サイト内で共通している部分の変更があった場合、そのパーツ化した部分のみを変更すれば良いので管理が楽になります。
例えば、以下のようなページ(例 index.php)のサイドバー部分をパーツ化(外部ファイル化)する場合、サイドバーの記述の部分を切り取り外部ファイル(例 sidebar.php)とします。
<!doctype html> <html lang="ja"> <head> <meta charset="utf-8"> <title>タイトル</title> </head> <body> <header> <h1>Parts template</h1> <nav> <ul> <li><a href="#">Home</a></li> <li><a href="#">News</a></li> <li><a href="#">About</a></li> <li><a href="#">Contact</a></li> </ul> </nav> </header> <div id="contents"> <div id="main"> <section> <h2>Heading H2</h2> <p>Lorem ipsum dolor sit amet...</p> </section> <section> <h3>Heading H3</h3> <p>Repellat nihil unde commodi...</p> <h4>Heading H4</h4> <p>Commodi harum nesciunt adip...</p> </section> </div> <!--ここからサイドバー部分--> <div id="side"> <aside> <h4>Side bar Heading H4</h4> <p>Recusandae nostrum cupiditate...</p> <p>Blanditiis aut id, quia paria...</p> </aside> </div> <!--ここまでサイドバー部分--> </div> <footer> <p><small>©2018 WDL</small> </p> </footer> </body> </html>
以下はサイドバー部分をパーツ化した sidebar.php です。
<div id="side"> <aside> <h4>Side bar Heading H4</h4> <p>Recusandae nostrum cupiditate...</p> <p>Blanditiis aut id, quia paria...</p> </aside> </div>
index.php では切り取ったサイドバーの部分に include() を使ってパーツ化した sidebar.php を読み込みます。
<!doctype html> <html lang="ja"> <head> <meta charset="utf-8"> <title>タイトル</title> </head> <body> <header> <h1>Parts template</h1> <nav> <ul> <li><a href="#">Home</a></li> <li><a href="#">News</a></li> <li><a href="#">About</a></li> <li><a href="#">Contact</a></li> </ul> </nav> </header> <div id="contents"> <div id="main"> <section> <h2>Heading H2</h2> <p>Lorem ipsum dolor sit amet...</p> </section> <section> <h3>Heading H3</h3> <p>Repellat nihil unde commodi...</p> <h4>Heading H4</h4> <p>Commodi harum nesciunt adip...</p> </section> </div> <!--ここからサイドバー部分--> <?php include dirname(__FILE__). '/sidebar.php'; ?> <!--ここまでサイドバー部分--> </div> <footer> <p><small>©2018 WDL</small> </p> </footer> </body> </html>
ファイルの読み込みは以下のように、$_SERVER['DOCUMENT_ROOT'] を使ってドキュメントルートからのパスで指定することもできます。
<?php include $_SERVER['DOCUMENT_ROOT'] . '/path to the file/sidebar.php'; ?>
ヘッダーやフッター部分なども上記と同じ方法でパーツ化することができます。
エラー
エラーメッセージ
PHP ではプログラムを正しく記述しないと動作しません。プログラムに間違いなどがあると PHP はエラーメッセージで、間違いがどの行で発生しているかを知らせてくれます。但し、必ずしも表示された行番号に間違いがあるとは限らず、発見するのが難しい場合もあります。
エラーメッセージにはいくつかの種類があり、代表的なものは以下の3種類です。
- Error (エラー/間違い)
- Warning (警告)
- Notice (注意)
Error (エラー/間違い)
Error には、Parse error や Fatal error などがあり、それらが発生した場合はプログラムは動きません。エラーメッセージには以下のようにどの行に間違いがあるかを表示してくれます。
Parse error: syntax error, unexpected '2' (T_LNUMBER), expecting ')' in \sample.php on line 52 //sample.php の52行目にエラーがある
Warning (警告)
Warning は、例えば setcookie() 関数の前に何らかの出力をしてしまった場合などに表示されるメッセージです。
メッセージが表示されても、プログラムはその後も動作しますが、正常に動作していない場合が多いはずです。
Warning: Cannot modify header information - headers already sent by ...sample.php on line 3 //sample.php の3行目に問題がある
Notice (注意)
Notice はレンタルサーバーの初期設定などでは表示されない場合もありますが、php.ini の設定を変更することで表示することができます。
例えば、配列で存在しないキーを指定したり、初期化されていない変数を使用すると表示される注意です。
プログラムが正常に動作しているように見えても、バグの原因になるなどするためエラーが発生しなくなるように修正します。
Notice: Undefined variable: value in .....sample.php on line 18 //sample.php の18行目に問題がある
エラーメッセージの制御
エラーメッセージの制御(表示・非表示など)の設定は以下のような方法があります。
- php.ini で指定(全ての php ファイルに適用)
- php ファイル内で指定(特定の php ファイルに適用)
php.ini で指定
php.ini で指定すると全ての php ファイルに適用することができます。
PHP の設定ファイル「php.ini」はデフォルトでは以下のフォルダにあります(ローカル環境の場合)。
- C:\xampp\php\php.ini(XAMPP の場合)
- /Applications/MAMP/bin/php/php* . * . */conf/php.ini(MAMPP の場合)
※ * . * . * はバージョン
開発環境の場合は、エラーがチェックできるように display_errors に On を指定してエラーを表示するようにます。
display_errors = On
※ 逆に本番環境では、エラーが表示されてしまうとファイルのパスなどが表示されてしまい、セキュリティ上問題があるのでエラーを表示しないように設定し、エラーはログで確認します。
全ての php ファイルに対してエラーを出力しないようにするには display_errors に Off を指定します。
display_errors = Off
エラー表示レベルの設定
また、開発環境では全てのエラーを表示するようにしておきます。
error_reporting で検索して、以下のように指定します。先頭のコメントアウトの記号「;」を削除するのを忘れないように。
error_reporting=E_ALL
PHP 5.3 以降のデフォルトは E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED です。 この設定では E_NOTICE や E_STRICT、そして E_DEPRECATED レベルのエラーは出力されません。開発時にはこのエラーを表示させたい場合は上記のように設定します。(error_reporting)
※ 変更した php.ini を有効とするには Apache を再起動する必要があります。本番環境では(ホスティングによっては)記述するだけで有効になる場合もあります(要確認)。
.htaccess で設定
.htaccess で、全ての php ファイルに対してエラーを出力しないようにするには .htaccess に以下を記述します。
php_flag display_errors off
php ファイル内で指定
ini_set()
特定の php ファイルでだけエラーの表示/非表示の設定を適用するには ini_set() を使用できます。
<?php // エラーを出力しない場合 ini_set('display_errors', 0); // エラーを出力する場合 ini_set('display_errors', 1); // 以降に php を記述 . . . ?>
ini_set() で設定した設定オプションは、スクリプトの実行中は新しい値を保持し、 スクリプト終了時に元の値へ戻されます。
php.ini で display_errors = Off を指定してすべての PHP ファイルでエラーを出力しないようにしている場合でも、ini_set('display_errors', 1); を指定すれば、そのファイルだけエラーを出力することができます。
error_reporting()
また、error_reporting() を使ってエラー表示を制御することもできます。
error_reporting(0); を設定することで全てのエラー出力をオフにすることができます。
// 全てのエラー出力をオフにする error_reporting(0); // E_NOTICE 以外の全てのエラーを表示する error_reporting(E_ALL & ~E_NOTICE); // 全ての PHP エラーを表示する error_reporting(E_ALL); // 全ての PHP エラーを表示する error_reporting(-1);
エラー制御演算子
@(エラー制御演算子)を使うとエラーを無視させる(表示させない)ことができます(@ 演算子は「式」に対してのみ動作します)。
@ を変数や関数など式の前に付けると、その変数や関数などにより発生したエラーによるエラーメッセージを表示しません。
但し、エラーメッセージが表示されないだけであり、エラーがなくなるわけではありません。エラー処理が必要な場合は、記述する必要があります。
また、一般に @(エラー制御演算子)を使うと実行速度が遅くなるのと、エラーの原因がわかりずらくなる可能性があるので使う場合は注意が必要です。
$test = 1/0; //以下のような Warning が表示されます。 //Warning: Division by zero in ...01.php on line 4253 @$test = 1/0; //@(エラー制御演算子)を使うとエラーは表示されません
以下のコードは、$_GET['name'] が定義されていない場合はエラーになり、Notice エラーが表示されます。
$name = $_GET['name']; //Notice: Undefined index: name in ...01.php on line xxxx
@(エラー制御演算子)を使って以下のように記述すると、$_GET['name'] が定義されていない場合でも、Notice エラーになりません。但し、処理速度は遅くなります。
$name = @$_GET['name'];
上記のコードは、以下のように三項演算子を使って記述すると同じ結果になりますが、実行速度はこちらの方が速くなります。
$name = isset($_GET['name']) ? $_GET['name'] : NULL;
または、以下のように filter_input() を使うと簡潔に記述できます。
$name = filter_input(INPUT_GET, 'name');
上記は以下と同じことです。
if(isset($_GET['name'])){ $name = $_GET['name']; } else { $name = null; } // または $name = isset($_GET['name']) ? $_GET['name'] : null;