PHPの言語仕様ー型と演算子(配列も)
なんかインスピレーション的に大事そうと思ったとこだけメモ。
◆整数型
$int3=011 //8進数表記で9の値だよね。懐かしい。
$int4=0xff //16進数で255の値。
整数型へのキャスト
$int1=intval("1");
もしくは
$int2=(int)"1";
$float1=1.2; //実数
$float2 = 1.2e3; //指数部を指定
キャスト方法
$float1 = floatval("1.2"); //文字列の1.2を、浮動小数点数にキャスト
もしくは
$float2 = (float)"1.2";
◆文字列
シングルクオート 変数、\n、\tなどのエスケープ文字展開しない。
ダブルクオート 変数、\n、\tなどのエスケープ文字展開する。
ちなみにこんなときあるよね・・・
echo "$ageyears old."; Noticeエラーになる。
$ageが変数名だがそのあと空白をあけたくない!
↓
echo "${age}years old."; これでうまくいく。
◆ヒアドキュメント
<<< のあとに終端識別子がでるまでを文字列とする。
※空白は禁止で改行する。
※ダブルクオートはそのまま表示される。
※変数は展開される。
例
$foo = <<<EOI
あいうえおあいうえお
tomは$age歳です。
EOI;
→tomは15歳です。
HTMLのテンプレート、コマンドラインのヘルプ文などに役立つ。
◆Nowdoc
ヒアドキュメントの変数が展開されないバージョン。
<<<のあとに書く識別子はシングルクオートで囲む。
PHP5.3以降導入。
例
$foo = <<<'EOI'
あいうえおあいうえお
tomは$age歳です。
EOI;
→tomは$age歳です。
◆文字列型とキャスト
echo 15.0;
→15と表示。
基本的には数字とかは全て文字列型にキャストされる。
この例も自動的に文字列型にキャストされて、整数と判断されるから.がなくなる。
いやなら printf('%.1f',15.0); こう書く。
◆論理型
真偽値
$boolean = true; trueを代入
$boolean = (bool)1; //trueを代入
基本的には値があればtrueだが、以下7つはfalse扱い。
false(論理型)
0(整数型)
0.0(浮動小数点型)
空の文字列("") , 文字列のゼロ("0") //これもfalse !!!!!
要素の数がゼロの配列
null(値がセットされてない変数も含む)
空のタグから作成されたSimpleXMLオブジェクト
※PHP4の場合のみ→メンバ変数の数がゼロのオブジェクト
◆リソース
リソース型はファイルやDB接続など外部リソースへの参照を保持している。
$mysql = mysql_connect('server', 'username' , 'password'); //mysql サーバへ接続
$var_dump(get_resource_type($mysql)); //mysql link
キャストすることは不可。
◆null
代入もせずに変数を出力→null
unset($var); とした後に出力→nullだし、Noticeエラーにもなる。
◆自動キャスト
どんな時に自動キャストされるのか。
→異なる型同士で演算を行う場合
→演算子、制御構造、関数やメソッドが特定の型の引数を必要としており、
それとは異なる型を渡した場合
◆文字列のキャスト
if('0.0' == '0'){
echo ' "0.0"と"0"は等しいです。';
}
→これは等しいと表示されてしまう!!
文字列型同士で比較したが、数値らしき文字列の場合、
整数型もしくは浮動小数点数型へとキャストするという性質がある。
↓
よくあるログイン画面のパスワード認証などで、
確認のため二回パスワードを求められる時などはセキュリティ上のリスクがある!
◆演算子
わかってるけど不安なのでメモ。
・論理演算子
&& 、and もつかえる。
|| , or も。
xor 排他的論理和。どっちが片方だけがtrueで、もう片方がfalseの組み合わせならtrueになるということ。
つまり下記
------------------
A B 判定
------------------
True True False
True False True
False True True
False False False
・短絡評価
if(isset($argv[1]) && $argv[1]) {
echo '引数は真です' , PHP_EOL;
}
論理演算子では、評価結果がわかった時点で演算結果を返す。
あゝなんて短絡的なんだ。 というわけで短絡評価。
引数が与えられてるかどうかをまず評価し、真ならその時点で演算結果を返す。
isset($argv[1])が真なら次の$argv[1]の評価はされない。
◆比較演算子
== 右辺と左辺が等しいとtrue、型が違う場合キャストされる。
=== 〃 、 〃 キャストされない。
!= もしくは<> 右辺と左辺が等しくないとtrue、型が違う場合キャストされる。
!== 〃 、 〃 キャストされない。
◆型演算子
・特定のクラスを継承したクラスのインスタンスか?
・特定のインターフェースを実装したクラスのインスタンスか?
がわかる。
$a =new SomeClass();
if($a instanceof SomeClass){
echo '$aはSomeClassのインスタンスです',PHP_EOL;
}
これは真になる。
他の例
interface FooInterface{
}
class ParentFoo{
}
class Foo extends ParentFoo implements FooInterface{
}
class Bar{
}
$a = new Foo();
var_dump($a instanceof Foo); //true
var_dump($a instanceof ParentFoo); //true
var_dump($a instanceof FooInterface); //true
var_dump($a instanceof Bar); //false
この赤くしたところは調べてもよくわからないのでとりあえず飛ばす。
追々勉強しよ。
いままでのは単項、二項演算子だったので一応違うかたちらしい。
条件式?式1:式2
条件式を評価し、真なら式1を。偽なら式2を返す。
if文と同じように使えて短い。
◆三項演算子の省略記法
条件式?:式1
式2を省略できる。真なら条件式を。偽なら式1を返す。
例
function some_func(){
$val = ...... //DBのデータを取得するなど。取得失敗したらfalse
return $val;
}
//省略できるので下記でOK!
$result = some_func() ? : 'default'; これならsome_func()は一度呼ばれるだけ!
◆三項演算子の結合規則
三項って多いな。。。でもこれでおしまい。
PHPは特殊で、ネストした時に左結合らしい。
つまり
$flag1 = true;
$flag2 = false;
echo $flag1 ? 1 : $flag ? 2 : 0;
これは2が出力される!!
解説↓ 実際はこうなってる。
echo ( ( $flag1 ? 1 : $flag2) ? 2 : 0);
要するにカッコはなるべくつけようという話。もしくは使わないでif文でやるとか。
動きは変わらないけどね。
◆その他の演算子
・エラー制御演算子 @をつかう。
$var=@$_GET['foo'];
普通こうかくとfooというパラメータが渡されないとエラーになる。Noticeで。
でも@つけるとエラーにならなくなる。
基本は非推奨。
・実行演算子
バッククオートで囲むと外部のシェルコマンド実行する。
' じゃなくて ` ね。似てるから嫌い。
$result = `grep -irn php *`; とか。
◆配列
まず初期化
$fruits = array(
'apple',
'banana',
'orange',
);
最後のカンマはあってもなくてもいいけど追加する時にミスりそうだからつけとく。
ちなみに下記も同じ意味になる。※初期化の初めて使われる時に限る。
$fruits = 'apple';
$fruits = 'banana';
$fruits = 'orange';
下記はエラーになる
$fruits =1;
$fruits = 'apple';
配列の中身は複数の型が混在していてもOK!!!
さらにキーをもつ要素ともたない要素も混在OK!!!
$fruits_color = array(
'peach',
'apple' =>'red';
'banana' =>'yellow';
下記も知っておくと得かも
$array = array(
4,
5,
1=>"これは1", //キーが1の要素を上書き。つまり5が入ってるの上書き。
・多次元配列
$fruits = array(
'apple' => array(
'price' => 100,
'count' => 2,
);
'banana' => array(
'price' => 80,
'count' => 5,
);
);
◆配列の演算
特殊な挙動するね。
$a = array('a' => 1, 'b' => 3, 'c' => 5);
$b = array('a' => 1,'c' => 5 , 'b' => 3);
$c = array('a' => 1, 'b' => 2);
var_dump($a==$b) //true
var_dump($a===$b) //false
これはまあわかる。
続いて大事なこと。
配列の結合は、左辺に同じキーをもつ要素があればそれを上書きしない。
var_dump($a + $c);
これは下記となる。
array(3){
["a"] => int(1)
["b"] => int(3)
["c"] => int(5)
}
またこうすると
var_dump($c + $a);
今度はこうなるということ。
array(3){
["a"] => int(1)
["b"] => int(2)
["c"] => int(5)
}
◆配列のキーがセットされているか調べる方法 2つ
$array = array('hoge'=>1 , 'fuga' = > 2);
array_key_exists('hoge',$array);
isset($array['hoge']);
違い
・array_key_exists()
配列を全てチェックするので遅い。
値があればnullでもtrueを返す。
・isset()
キー要素がセットされてるかチェックするので早い。
値がnullならfalseを返す。当然null以外ならtrue。