PHP
基本事項
コマンドラインで php ファイルを実行
php test.php
デバッグ用出力
print_r(); // 簡易
var_dump(); // 詳細
Basic Syntax
<?php
ではじめて、?>
で終わる。終わりのタグは、可能であれば省略する。- 命令文の最後には
;
が必ず必要。ただし終了タグの直前においては省略も可能。
// echoのショートハンド
<?php echo 'hello world' ?>.
<?= 'hello world' ?>
// comment1
# comment2
/*
* comment3
*/
Types
概要
- scalar(数学) types
- boolean
- integer
- float(=double)
- string
- compound types
- array
- object
- callable
- iterable
- special types
- resources
- NULL
- pseudo types
- mixed
- number
- callback
- array|object
- void
Type の確認方法
var_dump(123)
タイプと値をコンソール出力するgettype(123)
タイプを文字列として取得する(デバッグ用)is_type(123)
その型かどうかを判定したいときにつかう
var_dump(123); // => int(123)
echo gettype(1); // => integer
if (is_int(1)) {};
if (is_string('a')) {};
boolean
真偽値。case-insensitive である。
if ($action == "show_version") {}
$is_valid = true;
if ($is_valid) {}
echo
boolean を echo (文字列に Cast)すると、true は 1 を出力し、false は何も出力しない。
キャスト
キャストしたいときは(bool)
を使う。他のタイプでも同じだが、殆どの場合で自動キャストされるので、使うことはほぼない。
var_dump((bool) '1');
FALSE として判定されるもの
- FALSE
- 0(integer)
- 0.0(float)
- 空文字列及び"0"(string)
- 長さのない array
- NULL
TRUE として判定されるもの
- 上記以外のすべて(resource と NAN を含む)
Integer
整数。
$a = 1234; // 10進数 正の整数
$a = -123; // 10進数 負の整数
$a = 0123; // 8進数
$a = 0x1A; // 16進数
$a = 0b11111111; // 2進数
float への変換
計算結果が integer の範囲を超える場合は自動的に float が返される。
$large_number = 2147483647;
var_dump($large_number); // int(2147483647)
$large_number = 2147483648;
var_dump($large_number); // float(2147483648)
$million = 1000000;
$large_number = 50000 * $million;
var_dump($large_number); // float(50000000000)
計算結果が小数になる場合も float が返される。なお、round()
は四捨五入、(int)
は 0 に近い方に切り捨てる。
var_dump(25/7); // float(3.5714285714286)
var_dump((int) (25/7)); // int(3)
var_dump(round(25/7)); // float(4)
int への cast
-
boolean
- true は 1
- false は 0
-
float
- 0 に近い方にまるめられる
-
string
echo (int) "10.5"; // 10
echo (int) "-1.3e3"; // -1300
echo (int) "bob-1.3e3"; // 0
echo (int) "bob3"; // 0
echo (int) "10 Small Pigs"; // 10
echo (int) "10.2 Little Piggies"; // 10
echo (int) "10.0 pigs "; // 10
echo (int) "10.0 pigs "; // 10
Float
float = double = real numbers
$a = 1.234;
$b = 1.2e3;
$c = 7E-10;
float へのキャスト
-
string
echo (float) "10.5"; // 10.5
echo (float) "-1.3e3"; // -1300
echo (float) "bob-1.3e3"; // 0
echo (float) "bob3"; // 0
echo (float) "10 Small Pigs"; // 10
echo (float) "10.2 Little Piggies"; // 10.2
echo (float) "10.0 pigs "; // 10(float)
echo (float) "10.0 pigs "; // 10(float)
String
文字列には4種類の記法がある。
- single quoted
- double quoted
- heredoc syntax
- nowdoc syntax
single quoted
- 複数行に渡って書ける
'
を出力する時のみエスケープが必要- 制御文字は使えない
- 変数は展開されない
- 基本的にそのまま文字列として出力される
// 複数行書ける
echo 'You can also have embedded newlines in
strings this way as it is
okay to do';
// 'を出力するには\でエスケープ
echo 'Arnold once said: "I\'ll be back"';
// 下記はただの文字列として出力される
echo '$some_val with \r newline';
double quoted
- 複数行に渡って書ける
\
を使って制御文字を出力できる- 変数は展開される
echo "$some_val with \r newline
and multiline
is ok";
Nowdoc
- single quote の別の書き方。
- 中身は評価されない
'EOT'
の部分をシングルクオートで囲むこと。名前は任意に書き 換えて OK。
echo <<<'EOT'
My name is "$name". I am printing some $foo->foo.
Now, I am printing some {$foo->bar[1]}.
This should not print a capital 'A': \x41
EOT;
Heredoc
- double quote の別の書き方。
- 中身が評価される
EOT
の部分をダブルクオートで囲むか、もしくは囲まないこと。名前は任意に書き 換えて OK。
$a = 'John';
$str = <<<EOT
my name is $a \r Doe
EOT;
変数のパース - simple syntax
double quoted 等の中において変数をパースする方法は、simple と complex の 2 種類がある。simple-syntax では、$
を使う。変数名の区切りをはっきりさせる必要があるときは変数名を{}
で囲む。
echo "my name is $myname. nice to meet you";
echo "my name is ${myname}. nice to meet you";
echo "$people->john drank some $juices[0] juice.".PHP_EOL;
変数のパース - complex syntax
複雑な Expression を書ける方法、という意味で Complex と呼ばれている。{}
を使う。下記のような場合に使用する。
- シングルクオートを使いたい
- 動的に変数名を設定したい
- Object のプロパティ 名の区切りを明示したい
echo "This is {$arr['foo']}";
echo "This is ${$great}";
echo "This square is {$square->width}00;
ブラケットによるアクセス
文字列の特定の場所にアクセスしたいときはブラケット[]
もしくは braces{}
を使う。2 文字以上を操作したいときは、substr()
orsubstr_replace()
を使う。UTF に対応していないので実際 は使い物にならない。
'string'[0]; // => 's'
'string'[-2]; // => 'n'
結合
文字列は.
で結合できる。
echo "my name "."is"." android";
String への Cast
(string)
orstrval()
で文字列にキャストできる。echo
やprint
function では自動的にキャストが行われる。
array, object, resources はそのままキャストしても意味がない("Array"などになってしまう)ので、print_r()
やvar_dump()
を使うこと。
- boolean
- true は"1"に、false は""になる
- integer, float
- そのまま文字列になる
- array
- "Array"という文字列になる
- echo などしたいときは
[]
で中の要素を取り出して表示すること
- object
__toString
に実装されている値になる
- resouces
- "Resource id #1"のような文字列になる。数字の部分は一意のリソースナンバーを指す。
- NULL
- ""になる
なお、php で使うほとんどの値はserialize()
を使 うことで string の表現に変換できる。シリアライズ化した値は、unserialize()
でもとに戻すことができる。
Arrays
PHP の Array は、実際は Ordered Map(key-value ペア) である。下記のような用途に使うことができる。
- array
- list(vector)
- hash table
- dictionary
- collection
- stack
- queue
array()
による作成
- キーには integer 又は string を使うことができる
- value にはあらゆる値を格納できる
print_r(array(123, 456));
// => Array ( [0] => 123 [1] => 456 )
print_r(array(
"foo" => "bar",
"bar" => "foo", // trailing commaが使える
));
print_r([ // PHP 5.4以降では[]も使える
"foo" => "bar",
"bar" => "foo",
]);
// => Array ( [foo] => bar [bar] => foo )
- キー名は、次のルールによりキャストされる
- Valid な 10 進数を含む String は integer に
- float は trunc された integer に
- boolean は integer に
- null は""(empty string)に
- なお、array と object は key として使用することはできない
- キーを省略すると、Auto Increment な integer が順に振られる。この際、その配列において過去に一度でも使われた数字は、すでに配列から消去されている場合でも、再利用はされない。再利用したい場合は
array_values()
を使って reindex する作業が必要。
$array = array(
"a",
"b",
6 => "c",
"d",
);
/*
array(4) {
[0]=>
string(1) "a"
[1]=>
string(1) "b"
[6]=>
string(1) "c"
[7]=>
string(1) "d"
}
*/
- 要素へのアクセスは
[]
or{}
をつかう。なお、この 2 つの記法は全く等価である。
var_dump($array["foo"]);
var_dump($array[42]);
var_dump($array{42});
var_dump($array["multi"]["dimensional"]["array"]);
[]
による作成・変更
[]
で特定の要素を作成、取得、変更できる- もし
$arr
が存在しなかった場合は作成される(Array 作成の方法としては非推奨) - Key を省略した場合は、Auto Increment な数値が自動で振られる。
$arr[] = 56;
$arr["x"] = 42;
// Array([0] => 56, [x] => 42)
Array に関連した便利なファンクション
-
unset($arr)
,unset($arr[key])
要素又は配列を削除する。reindex は行わない。$arr = array(5 => 1, 12 => 2);
$arr[] = 56; // $arr[13] = 56;
$arr["x"] = 42;
unset($arr[5]); // This removes the element from the array
unset($arr); // This deletes the whole array -
array_values($arr)
reindex した配列を返す -
foreach ($array as $value) {}
-
foreach ($array as $key => $value) {}
-
count($arr)
-
sort($arr)
-
array_diff($arr1, $arr2)
String へのキャスト時の注意
key のタイプによってキャスト時の作法が変わる
// Keyが変数のとき
echo "$array[$i]"; // ""で囲む
// KeyがStringのとき
echo "{$array['test']}"; // complex-syntaxを使う
echo $array['test']; // 又は""の外に出して、`.`でconcatして対応する
Array へのキャスト
-
(array) someval
で Array にキャストできる。 -
int, fload, string, boolean, resource の場合、
array(someVal)
したのと同じことになる。つまり、長さ 1 の配列に、someVal が格納される。print_r((array) 123); // => Array([0]=>123)
-
NULL の場合、長さが 0 の配列になる。
-
object の場合
- プロパティがキー名になる
- private の場合は
\0クラス名\0プロパティ名
になる - protected の場合は
\0*\0プロパティ名
になる \0
は null を表す。なぜこれが必要なのかはよくわからない。
class MyClass
{
public $myPublic;
private $myPrivate;
protected $myProtected;
}
/*
array(3) {
["myPublic"]=> NULL
["\0MyClass\0myPrivate"]=> NULL
["\0*\0myProtected"]=> NULL
}
*/
配列の比較
array_diff($arr1, $arr2)
によ り、arr2 に存在しない要素を抽出できる。
$array1 = array("a" => "green", "red", "blue", "red");
$array2 = array("b" => "green", "yellow", "red");
$result = array_diff($array1, $array2);
// => Array([1] => blue)
参照渡しと値渡し
Array の場合、デフォルトは値渡しになる。参照渡しにしたい場合は&
を付与する。
$arr1 = array(2, 3);
$arr2 = $arr1;
$arr2[] = 4; // arr1は変更されていない
$arr3 = &$arr1;
$arr3[] = 4; // arr1は変更されている
Iterables
PHP 7.1 以降で使える疑似タイプ。下記を受け付ける。foraech することができる。
- array
- Traversable interface を備えた Object
function arr(): iterable
{
return [1, 2, 3];
}
function gen(): iterable
{
yield 1;
yield 2;
yield 3;
}
foreach (arr() as $value) {}
foreach (gen() as $value) {}
Objects
object = クラスインスタンスのこと。
class Dog
{
public function bark()
{
echo "bow!";
}
}
$dog = new Dog;
$dog->bark();
object へのキャスト
-
object へキャストした場合は、
stdClass
というビルトインクラスを基にしたインスタンスが作成される。 -
NULL はプロパティを持たないインスタンスに変換される
var_dump((object) null);
/*
object(stdClass)#1 (0) {}
*/ -
Array は、key-value がそのまま property-value に変換される。
$arr = [
"name" => "john",
"age" => 33,
];
var_dump((object) $arr);
/*
object(stdClass)#1 (2) {
["name"]=> string(4) "john"
["age"]=> int(33)
}
*/ -
int や string など、scalar な値は、
scalar
というプロパティに格納される。var_dump((object) 123);
/*
object(stdClass)#1 (1) {
["scalar"]=> int(123)
}
*/
Resources
- 外部への参照を持つ、特別な値。
- 作成や使用の際は、特別なファンクションを使う。
- メモリの開放は自動で行われる。ただし、データベースへのコネクションだけは別である。
null
変数が値を持っていないことを示す。
- null を明示的にセットした変数
- まだ一度も値がセットされていない変数
- unset()された Key 又は Array
null へのキャスト
昔は(unset)
が使えたが、今は強く非推奨。
Callbacks / Callables
call_user_func()
or usort()
など、いくつかのファンクションは、コールバックを受け取ることができる。
コールバックの渡し方は下記の 4 つがある。
- 文字列で渡す方法
- array で渡す方法
- object を渡す方法
- Anonymous Function を渡す方法
シンプルな関数をコールバックに指定
function myCallbackFunction($text = "")
{
echo 'hello world!'.$text;
}
call_user_func('myCallbackFunction');
call_user_func('myCallbackFunction','hello2');
クラスメソッド、インスタンスメソッドをコールバックに指定
注意:JS と異なり、PHP ではクラスメソッドをインスタンスを起点にして呼ぶことができる。
// An example callback method
class MyClass
{
public static function myCallbackMethod()
{
echo 'Hello World!';
}
}
// Static class method call
call_user_func('MyClass::myCallbackMethod');
call_user_func(array('MyClass', 'myCallbackMethod')); // old fasion
// Object(instance) method call
$obj = new MyClass();
call_user_func(array($obj, 'myCallbackMethod'));
親クラスのメソッドをコールバックに指定
class MyChildClass extends MyClass
{
public static function myCallbackMethod()
{
echo "some message";
}
}
call_user_func(array('MyChildClass', 'parent::myCallbackMethod')); // => Hello World!
__invoke
を実装しているクラスのインスタンスをコールバックに指定
class MyInvokableClass
{
public function __invoke($name)
{
echo 'Hello ', $name, "\n";
}
}
$c = new MyInvokableClass();
call_user_func($c, 'PHP!');
Closure
Closure = Anonymous function のこと。
// closure
$double = function ($a) {
return $a * 2;
};
$new_numbers = array_map($double, [1,2,3,4,5]);
// => 2,4,6,8,10
Pseudo-types
PHP のドキュメントにおいて、説明の便宜上、定義しているタイプのこと。引数のタイプや値を正しく説明するための架空のものであり、実際の PHP のプリミティブタイプとして存在するわけで はない。
mixed
いくつかのタイプを受け取る事ができるタイプ。例)gettype()
number
integer + float
callback
callable のこと。callable が登場する以前は、callback という擬似タイプが存在していた。
array|object
array もしくは object
void
何もリターンしない、何も引数として受け付けない、というタイプ。PHP7.1 以降ではリターンタイプとして使える。
型の相互変換
自動変換
PHP の方は、文脈によって自動的に決定される。例えば乗算演算子では、下記のように型が自動変換される。
オペランドのいずれかが | オペランドの評価 | 結果 |
---|---|---|
float を含む | すべて float | float |
float を含まない | すべて integer | integer |
キャストの種類
- (int), (integer) - 整数へのキャスト
- (bool), (boolean) - 論理値へのキャスト
- (float), (double), (real) - float へのキャスト
- (string) - 文字列へのキャスト
- (array) - 配列へのキャスト
- (object) - オブジェクトへのキャスト
- (binary) - バイナリへのキャスト
- (unset) - NULL へのキャスト (強く非推奨)
Variables
Basics
-
命名規則 →
\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*
-
値の代入
- デフォルトではすべて値渡し。Object についても、handle(object の実体への参照のようなもの)を値渡ししている。
- 参照渡ししたい場合は、代入する値に
&
を使う。これにより エイリアス (同じ向き先を持つ変数)が作成される。 &
をつ けることができる対象は、名前付き変数のみ(&(1+2)
などは無効)
$a = 1;
$b = $a;
$b = 2;
var_dump($a); // => 1
Predefined Variables
PHP には多くの定義済み変数がある。特に、Superglobals と呼ばれる下記のものは、プログラムのどこからでも、なんの手続きもせずに 使用することができる。
$GLOBALS
$_SERVER
$_GET
$_POST
$_FILES
$_COOKIE
$_SESSION
$_REQUEST
$_ENV
Scope
スコープの種類は、グローバルか、ローカル(ファンクション内)の 2 つ。
Include
他のファイルを Include した場合、Include した場所にそのファイルを差し込んだようなイメージになる。
$a
は、other.php
内で使用可能other.php
内の変数・メソッドは、取り込み主で使用可能。スコープは、include
文が存在している場所によって決まる。ただし、ファンクションとクラスはグローバルスコープになる。詳細はこちら。
$a = 1;
include 'other.php';
グローバル変数とローカル変数
ファンクションの中からアクセスできるのはローカル変数のみ。
$a = 1; // グローバル
function test()
{
echo $a; // ローカル変数を参照する。グローバルにはアクセスできない。
}
global
キーワードを使ってグローバルにアクセス
$a = 1;
function Sum()
{
global $a;
echo $a; // グローバルにアク セスできる
}
$GLOBALS
を使ってグローバルにアクセス
$a = 1;
function Sum()
{
echo $GLOBALS['a'];
}
static 変数
static 変数を使うと、ファンクションの終了後も値を保持しておくことができる。
function test()
{
static $a = 0;
echo $a;
$a++;
}
test(); // 0
test(); // 1
test(); // 2
static 変数を使って再帰処理を書くとこんな感じ。
function test()
{
static $count = 0;
$count++;
echo $count;
if ($count < 10) {
test();
}
}
References with global and static variables
TODO: 意味不明
Variable Variables
動的に指定できる変数名のこと。
$a = 'hello';
$$a = 'world';
echo "$a $hello"; // hello owrld
echo "$a ${$a}"; // hello world
配列で使う場合は、あいまいさを{}
で解消する必要があるので注意。
$$a[1] // invalid as it's ambiguous
${$a[1]} // ok
${$a}[1] // ok
クラスのプロパティに動的にアクセスしたいときは、変数や、{}
を使うことができる。
class foo
{
public $bar = 'I am bar.';
public $r = 'I am r.';
}
$foo = new foo();
$name = 'bar';
$names = array('foo', 'bar');
echo $foo->$name . "\n"; // I am bar.
echo $foo->{$names[1]} . "\n"; // I am bar.
echo $foo->{'b' . 'ar'} . "\n"; // I am bar.
echo $foo->{'arr'[1]} . "\n"; // I am r.
Variables From External Sources
フォームで送られてきた値の取得
使うことはなさそう。必要になったら学習する。
$_POST['username']; // POSTのbodyのみ取得
$_REQUEST['username']; // POSTのbodyと、Queryも取得
Cookies
setcookie()
で値をセット$_COOKIE
で値を取得
// 下記のように配列「風」にしておけば、取り出す際に自動で配列にしてくれる
setcookie('mycookie[0]', 'mydata-1');
setcookie('mycookie[1]', 'mydata-2');
var_dump($_COOKIE);
ドットの扱い
外部から取得したデータの変数名(Key など)にドットが含まれている場合、PHP では変数名にドットが使えないので、自動的に_
に変換される。
Constants
Basics
- scalar と array を値に設定できる。resource は使うな。
- 変更できない
- case-sensitive
- 慣例として名前はすべて大文字にする。 命名規則 =>
[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*
Syntax
変数との違い
$
が頭につかない- 変数のスコープとは異なり、どこでも宣言でき、どこからでもアクセスできる。
- 値を変更できない
宣言方法
const
を使う方法とdefine()
を使う方法がある。const
の場合はコンパイル時に定義されるため、トップレベルのスコープでのみ使用できる。- ファンクションやループの中で動的に定義したい場合は
define()
を使うこと。 get_defined_constants()
で定義済み定数の一覧を Array で取得できる
const CONSTANT = 'Hello World';
define("CONSTANT", "Hello world");
const ANIMALS = array('dog', 'cat', 'bird');
define('ANIMALS', array(
'dog',
'cat',
'bird'
));
Magic constants
定義済みの定数。コンパイル時に定義される。詳細はこちら。
__LINE__
__FILE__
__DIR__
__FUNCTION__
__CLASS__
__TRAIT__
__METHOD__
__NAMESPACE__
ClassName::class
Expressions
PHP では、すべてが Expressions であり、評価の対象である。
Expressions とは?
最終的に値になるものすべて。「式」と訳される。
$a = 5
// 5は、integerの5を表すExpressionである
// 代入後は、$aも、int(5)を表すExpressionになる
// さらに、代入後は、'$a = 5'自体も、int(5)を表すExpressionになる
// <= 下記も全部Expression
someFunc()
i++
1 > 5
a += 5
Statement とは?
何らかのexpression;
が Statement である。「文」と訳される。
$b = $a = 5;
// '$b = $a = 5;'がStatement
/// $b, $a, 5, '$a=5' などはExpression
Operators
Precedence
- オペレータの優先順位によって、計算順が決まる
- 計算順が同じ場合は、Associativity(left or right)により、計算順が決まる。
- Associativity が non-associative なオペレータを 2 つ以上つなげることはできない
詳細はこちら
Operators の種類
気になったところだけ記載した。
-
+$a
,-$a
-
$a = 1
自体も Expression である- combined operators
+=
,*=
など - 原則としてすべて値渡しである。object は参照渡しのように見えるが、実際は handle(object の実体への参照のようなもの)を値渡ししている。
&new
はエラーになる
-
- 必要になったら調べる
-
-
==
,!=
,<>
タイプの自動変換後の比較 -
===
,!==
タイプの自動変換をせずに厳密比較 -
<=>
大きいか(1)、小さいか(-1)、イコールか(0)を返すecho 1 <=> 1; // 0
echo 1 <=> 2; // -1
echo 2 <=> 1; // 1
echo "b" <=> "a"; // 1 -
Ternary Operator
$action = (empty($_POST['action'])) ? 'default' : $_POST['action'];
-
Null Coalesing(合体) Operator
- 左辺が null だったときのみ右辺を評価する
$a = null ?? 'true!';
-
Error Control Operators
@
のこと。Expression に前置すると、その Expression に関するエラーを無視する。
詳細はこちら。
Execution Operators
backtick で囲むことでシェルコマンドを実行できる。
echo `ls -al`;
Incrementing/Decrementing Operators
++$a
, $a++
, --$a
, $a--
Logical Operators
and
どちらも trueor
少なくとも 1 つが truexor
どちらか一方のみ true!
&&
||
and/or
は =
よりも優先度が低い。||/&&
は=
よりも優先度が高い。このため、下記のような事故がおこりがち。
$bool = true && false;
var_dump($bool); // false, that's expected
$bool = true and false;
var_dump($bool); // true, ouch!
String Operators
.
で文字列を接続する。.=
も使える。
Array Operators
+
配列を結合する。キー重複時は左辺が優先される。- 緩い比較
==
同じ key-value ペアを持っているか!=
,<>
上記の否定形
- 厳密な比較
===
同じ key-value ペアを持っているかつ、同じ順番、同じタイプか!==
上記の否定形
Type Operators
instanceof
あるインスタンスがあるクラスから生成されたかどうかを返す。- 継承、インターフェースの実装でも True を返す。
- 右辺は文字列でも OK
class MyClass{}
class NotMyClass{}
$a = new MyClass;
var_dump($a instanceof MyClass); // true
var_dump($a instanceof NotMyClass); // false
Control Structures
JS とほぼ同じ書き方のもの
if/elseif/else
while
do-while
for
switch