PHP

PHP初期学習まとめ

More than 1 year has passed since last update.

PHPを仕事で使うことになりそうなので、自分が後から参照するためにまとめてみた。

なお、PHPは、公式のマニュアルが充実している印象である。


序論・変数・演算子


  • ステートメントは「;」で区切る。

  • 変数名は、大文字小文字の区別がある。

  • 関数名は、大文字小文字の区別がない。

  • 1行コメントは「#」「//」の2種類。

  • ブロックコメントは「/* ... */」の1種類。

  • 変数名の前には、$を付ける。

  • グローバル定数は「const HOGE = 1;」のように定義する。

  • ローカル定数は「define("HOGE", 1)」のように定義する。

  • デバッグ時には、print_r()かvar_dump()を利用すると良さそう。ブラウザ上では、「pre」で囲むと出力が見易くなる。

  • 演算子は、C/C++などに似ている。文字列の結合を「.」で行うことができる。

  • 厳密な比較は「===」「!==」で行う。(「"99"==99」はtrueになるが「"99"===99」はfalseになる。)

  • PHP7から「<=>」の比較演算子が使えるようになった。

  • PHP7から「??」が使えるようになった。「a ?? b ?? c」と記載すると、aがNULLのとき、bが評価され、bがNULLのときはcが評価される。途中でNULLがなかった場合にはその値がこの式の値になる。

  • キャストは、(int)$aのように記載する。int, boo, float, string, array, object, unsetなどがある。unsetはNULLになる。


  • $a instanceof DateTimeは、$aという変数がDateTime型のときにtrueになり、それ以外のときにfalseになる。


演算子の優先順位

演算子
結合性

clone, new
結合しない

[

**

++, --, ~, (int)などのキャスト, @

instanceof
結合しない

!

*, /, %

+, -, .

<<, >>

<, <=, >, >=
結合しない

==, !=, ===, !==, <>, <=>
結合しない

&

^


&&

||

??

?:

=, +=, -=, =, *=, /=, .=, %=, &=, |=, ^=, <<=, >>=, =>

and

xor

or

,


可変変数

$vehicle = "car";

$$vehicle = "車"; // $vehicleに入っている値の変数名にアクセスしている。すなわち、$carという変数に「車」という文字列を設定している。
echo $car; // 「車」が出力される。


制御構文


if


if

if(条件式) {

処理
} else if(条件式) {
処理
} else {
処理
}


switch


switch

switch() {

case 値1:
処理
break;
case 値2:
処理
break;
default:
処理
break;
}


while, do-while, for

ループ内の制御として、break, continueが使用できる。


while

while(条件式) {

処理
}


do-while

do {

処理
} while(条件式);


for

for(カウンタの初期化;条件式;カウンタの更新) {

処理
}


関数


基本形


関数定義の書式

function 関数名( 引数1=初期値1,  引数2=初期値2,  引数3, ...) : 返り値の型 {

処理
return 戻り値;
}

引数の型や返り値の型は省略可能。


可変引数


可変引数の関数定義の書式

function 関数名(引数1, ...引数3) {

処理
return 戻り値;
}

具体的には、以下の感じになる。


可変引数関数の具体例

function hoge($arg1, ...$args) {

print_r($arg1 . PHP_EOL);
print_r($args);
}

hoge('a', 'b', 'c', 'd')


以下のように出力される。

a

Array
(
[0] => b
[1] => c
[2] => d
)


参照渡し

引数の前に「&」を付けると参照渡しができる。


参照渡しの関数定義の書式

function hoge($arg1, &$arg2) {

$arg2 += 10;
}

$v1 = 10;
$v2 = 11;
hoge($v1, $v2)


上の例では、hogeを呼び出すことで$v2に10が足されて21になっている。


可変関数

動的に関数呼び出しを変更できる。

関数が存在するか否かをfunction_exists()で確認できる。

function func1($hoge) {

echo "func1 : {$hoge}";
}

function func2($hoge) {
echo "func2 : {$hoge}";
}

$run = "func2";
if(function_exists($run)) {
$run('GO');
}


無名関数

$func = function($hoge) {

echo "無名関数 : {$hoge}";
}; // ←代入文なので「;」が必要

$func('GO');

呼び出し元にある変数を使用するには以下のように定義する。

但し、funcに代入した時点のvar1が代入されるためfuncに入れた後に、var1を変更した上で、funcを呼び出しても、var1の値はvar1が変更される前の値になる(遅延評価されない)。

$var1 = 'あいうえお'

$func = function($hoge) use ($var1) {
echo "無名関数 : {$hoge}" . $var1 ;
}; // ←代入文なので「;」が必要

$func('GO');


その他


  • 関数内でグローバル変数にアクセスする場合にはglobal $変数名;と宣言した上で、関数内で使用する。


文字列操作


  • 文字列中で変数展開可能。"{$var}あいう"のような感じ。定数は展開できないので注意すること。

  • printf, sprintf有り。


ヒアドキュメント

ダブルクォートで囲んだ文字列と同等(変数展開される)。

<<< "識別子" // 識別子はダブルクォートで囲む

任意の文字列
識別子;


NowDoc

シングルクォートで囲んだ文字列と同等(変数展開されない)。

<<< '識別子' // 識別子はシングルクォートで囲む

任意の文字列
識別子;


文字列操作関数

関数
機能

mb_strlen(文字列)
文字数を取得

mb_substr(文字列, 文字位置, 文字数)
文字列から文字を取り出す。文字位置に負の数を指定すると後ろから

mb_convert_kana(文字列, オプション, エンコーディング)
オプションに応じて文字列を変換(対応表は後述)

strtoupper(文字列)
大文字に変換

strtolower(文字列)
小文字に変換

ucfirst(文字列)
英文の先頭の文字を大文字に変換

ucwords(文字列)
英文の各単語の先頭の文字を大文字に変換

trim(文字列)
先頭、末尾の半角空白、タブ、改行、キャリッジリターン、NULL、垂直タブを削除。第2引数で他の文字を削除対象に指定できる。(全角空白も追加したいなら"\x20\t\n\r\0\v "と指定する)

ltrim(文字列)
先頭の半角空白、タブ、改行、キャリッジリターン、NULL、垂直タブを削除。第2引数で他の文字を削除対象に指定できる

rtrim(文字列)
末尾の半角空白、タブ、改行、キャリッジリターン、NULL、垂直タブを削除。第2引数で他の文字を削除対象に指定できる

htmlspecialchars(文字列, ENT_QUOTES, 'UTF-8')
HTML文字をエスケープ。ENT_QUOTESを指定するとダブルクォートとシングルクォートが対象。デフォルトはダブルクォートのみ

strip_tags(文字列)
HTMLタグを取り除く

rawurlencode(文字列)
URLエンコード(空白文字を%20に変換)

urlencode(文字列)
URLエンコード(空白文字を+に変換)

rawurldecode(文字列)
rawurlencodeの結果をデコード

urldecode(文字列)
urlencodeの結果をデコード

mb_convert_kanaのオプションについて

オプション
変換

r
全英→半英

R
半英→全英

n
全数→半数

N
半数→全数

a
半角の英数記号→全角の英数記号

A
全角の英数記号→半角の英数記号

s
全角スペース→半角スペース

S
半角スペース→全角スペース

h
ひらがな→半角カタカナ

H
半角カタカナ→ひらがな

c
全角カタカナ→ひらがな

C
ひらがな→全角カタカナ

k
全角カタカナ→半角カタカナ

K
半角カタカナ→全角カタカナ

V
濁点付きの文字を1文字に変換


配列操作

配列には以下の2種類がある。


  • インデックス配列($a = [要素1, 要素2, ...];又は$a = array(要素1, 要素2, ...);で初期化可能)

  • 連想配列($a = [キー1 => 値1, キー2 => 値2, ...];又は$a = array(キー1 => 値1, キー2 => 値2, ...);で初期化可能)


配列操作関数

関数
機能

count(配列)
要素数を取得

explode(文字列, 文字)
文字列から指定された文字で区切って配列にする。rubyのsplitに相当

implode(文字, 配列)
配列から指定した文字で区切って文字列にする。rubyのjoinに相当

array_splice(&配列, 開始位置, 長さ)
配列の要素を削除する。削除された要素が返却される。

array_merge(配列1, 配列2, ...)
連結された配列が返却される。「+」演算子では連結という動きにはならない。連想配列でキーが重複していた場合には後勝ち

array_merge_recursive(配列1, 配列2, ...)
連結された配列が返却される。連想配列でキーが重複していた場合には多重配列にする

array_combine(配列1, 配列2)
配列1をキー、配列2を値にした連想配列が返却される

array_unique(配列)
重複した値を取り除く

array_slice(配列, 開始位置, 長さ)
部分配列を作成する

array_filter(配列, 関数)
配列要素を引数とした関数がtrueとなる要素のみの配列が返却される

array_reverse(配列)
配列の逆順にする

in_array(値, 配列)
値が配列に入っていればtrue、いなければfalse

array_search(値, 配列)
値が配列に入っていれば最初に見つかった値のキーを返却、見つからなければfalse

array_diff(配列1, 配列2, 配列3, ...)
配列1の中で、配列2, 3, ...に入っていない値を配列で返却する

str_replace(配列1, 配列2, 配列3)
配列3が置換対象。配列2の文字列を配列3で置換する。インデックス配列が対象

str_ireplace(配列1, 配列2, 配列3)
str_replaceの大文字小文字無視バージョン

preg_replace(配列1, 配列2, 配列3)
配列3が置換対象。配列2の文字列を配列3で置換する。連想配列が対象。検索・置換対象は値

preg_grep(正規表現文字列, 配列)
正規表現文字列にマッチする要素を配列として返却。第3引数にPREG_GREP_INVERTを指定するとマッチしなかった配列を取得できる

ソートに関するものは別表に抜き出した。

関数
機能
キーと値の関係性が維持されるか

sort(&配列)
インデックス配列の昇順ソート
×

rsort(&配列)
インデックス配列の降順ソート
×

asort(&配列)
連想配列を値で昇順ソート

arsort(&配列)
連想配列を値で降順ソート

ksort(&配列)
連想配列をキーで昇順ソート

krsort(&配列)
連想配列をキーで降順ソート

natsort(&配列)
自然順のソート

natcasesort(&配列)
大文字小文字を無視した自然順のソート

uasort(&配列)
ユーザー定義順に値でソート

uksort(&配列)
ユーザー定義順にキーでソート

usort(&配列)
ユーザー定義順に値でソート
×


構文


全要素に対する処理をするときの構文(インデックス配列)

foreach ($array as $value) {

処理($value)
}


全要素に対する処理をするときの構文(連想配列)

foreach ($array as $key => $value) {

処理($key, $value)
}


インデックス配列を変数に展開

list($var1, $var2, ...) = 配列;


rubyのmapっぽいやつ

$userdataは無くてもよい。

array_walkが成功するとtrueが返却され、失敗するとfalseが返却される。

$arrayがインデックス配列の場合には、$keyにはインデックス番号が渡される。

array_walkは引数に渡した配列の内容が変化する。

array_walk(&$array, $callback, $userdata);

fuction コールバック関数名($value, $key, $userdata) {
処理
}

array_mapは引数に渡した配列の内容は変化しない。

インデックス配列のみが対象。

要素数が同じ配列であれば、1〜複数指定できる

$mapped_array = array_map($callback, $array1, $array2, ...);

fuction コールバック関数名($value1, $value2, ...) {
処理
}


クラス、トレイト、インターフェース、抽象クラス


  • 多重継承不可。

  • trait、interface、abstractが存在している。

  • interfaceは実装を持てず、abstractは実装を持てる。

  • interfaceは、メソッドと定数のみ設定可能。publicのみ設定可能(サンプルには記載していないが、extendsで親インターフェースクラスを指定可能)。

  • 1つのクラスは、trait、interfaceを複数利用可能である。

  • アクセス指定子は、C++と同等扱いのpublic, protected, privateがある。

  • 自身のプロパティ($property)には、$this->$propertyでアクセスする。$thisを省略するとローカル変数を探しにいってしまう。


クラス関連の宣言例

class クラス名 extends 親クラス名 implements インターフェース名, インターフェース名, ... {

use トレイト名, トレイト名, ...;
// クラスメソッド、クラスプロパティ
public static const 定数名 = ;
public static 変数名;
public static function メソッド名(引数, 引数, ...) {
}
// プロパティ
public 変数名;
protected 変数名;
private 変数名;

// メソッド
public function メソッド名(引数, 引数, ...) {
}
protected function メソッド名(引数, 引数, ...) {
}
private function メソッド名(引数, 引数, ...) {
}
}

interface インターフェース名 {
const 定数 = ;
function 関数名(引数, 引数, ...);
}

abstract class 抽象クラス名 {
abstract function 抽象メソッド名(引数, 引数, ...);
}

trait トレイト名 {
// プロパティ
// メソッド
}


クラス関連のサンプルコード。


class.php

<?php

abstract class Vehicle {
private $color;

function __construct($color) {
$this->color = $color;
}

function getColor() {
return $this->color;
}

abstract function run();

function stop() {
echo "乗り物停止<br>";
}
}

trait Audio {
function turnon() {
echo "オーディオ電源オン<br>";
}
}

trait Navigation {
function turnon() {
echo "カーナビ電源オン<br>";
echo "どこに行きますか?" . $this->whereAreYouGoing() . "<br>" ;
}

// トレイトを利用するクラスに実装させることができる。
abstract function whereAreYouGoing();
}

interface SafetyCheck {
function check();
}

class Car extends Vehicle implements SafetyCheck {
// トレイトの利用
use Audio, Navigation {
// メソッド名の衝突関連
Audio::turnon as audioTurnon;
Navigation::turnon as naviTurnon;
Audio::turnon insteadof Navigation; // 単にturnonがコールされたらAudioのメソッドを呼ぶ
}

// プロパティ(public, protected, private)
const TYPE = '車';
private $number;

// コンストラクタ
function __construct($color, $number) {
parent::__construct($color); // 親クラスのコンストラクタを呼び出す。
$this->number = $number;
}

// メソッド(public, protected, private。省略時は、public)
function run() {
// 抽象メソッドをオーバーライドして実装
echo self::TYPE . ":Fast Speed!<br>";
}

function stop() {
echo self::TYPE . "停止<br>";
}

// Navigationトレイトを利用する場合に実装が必要なメソッド
function whereAreYouGoing() {
return '東京';
}

function check() {
echo "ブレーキ、ミラー、ランプ確認OK<br>";
}

// 文字列型にキャストされたときに返却する値。
function __toString() {
return self::TYPE . ": {$this->getColor()}";
}
}

class Bicycle extends Vehicle implements SafetyCheck {
// トレイトの利用
const TYPE = '自転車';
use Navigation;

// コンストラクタ
function __construct($color) {
parent::__construct($color); // 親クラスのコンストラクタを呼び出す。
}

// メソッド(public, protected, private。省略時は、public)
function run() {
// 抽象メソッドをオーバーライドして実装
echo self::TYPE . ":Slow Speed!<br>";
}

// Navigationトレイトを利用する場合に実装が必要なメソッド
function whereAreYouGoing() {
return '富士山';
}

function check() {
echo "ブレーキ、ランプ確認OK<br>";
}
}



index.php

<?php

require_once("class.php");
?>

<pre>
<?php
echo "【車】の確認<br>";
$car = new Car('赤', '12-34');
$car->turnon(); // オーディオが起動
$car->naviTurnon();
$car->audioTurnon();
$car->check();
$car->run();
$car->stop();
echo "{$car}<br>"; // 文字列型にキャスト

echo "<br>";

echo "【自転車】の確認<br>";
$bike = new Bicycle('青');
$bike->turnon();
$bike->check();
$bike->run();
$bike->stop();
?>
</pre>



実行結果

【車】の確認

オーディオ電源オン
カーナビ電源オン
どこに行きますか?東京
オーディオ電源オン
ブレーキ、ミラー、ランプ確認OK
車:Fast Speed!
車停止
車: 赤

【自転車】の確認
カーナビ電源オン
どこに行きますか?富士山
ブレーキ、ランプ確認OK
自転車:Slow Speed!
乗り物停止