PHP5上級試験/準上級試験の上級合格に挑戦(13) プログラミングPHP第3版 1章〜２章

タイトルの通り。
プログラミングPHP第３版で、黒本にはなかったところをまとめていきたい。

# 1章PHPについて
+ PHP設定変更後はPHPは再起動が必要


１）クロスプラットフォーム（複数の異なるプラットフォームで動作する）のGUIアプリケーションを作れるのは？
２）PHPが動作するOSで、Unix系を３つ答えよ
３）PHPが動作するWebサーバーを３つ答えよ
４）PHPが動作するDBを７つ答えよ
５）DBの抽象化やエラー処理といった一般的な作業をやるPHPコードを集めたライブラリとは？
６）PHPを初めて考案した人物は？また何年か？
　
　
　


解答
1) PHP-GTK
※なお、GUIはGraphic User Interface:画面操作の略。反対はCUI（Command User Interface)、すなわちコマンドラインからの操作のこと。
２）Linux,FreeBSD,Solaris
３）Apache,Microsoft IIS,Netscape/iPlanetサーバー
４）MySQL/PostgreSQL/Oracle/Sybase/MS-SQL/DB2/ODBCに準拠するDB/SQLite/MongoDB(NoSQL）
５）PEAR(PHP Extension and Application Repository)
6) Rasmus Lerdorf（ラズマス・ラードフ）・１９９４年


# ２章PHP言語の基本

+ PHPの終了タグ（？>)の直前のセミコロンは省略可能 (2.1.2 命令文とセミコロン）
+ 空白文字はPHPの動作に影響を及ぼさないので字下げを適切にして読みやすく (2.1.3 空白と改行）
+ コメントは//(C++形式）だけでなく、#(シェル形式）もあるし/*~*/（C形式、CSS形式）もある (2.1.4 コメント）
+ コメントは上記の組み合わせも可能 (2.1.4 コメント）
+ 式は左から右へと進んでいく　つまり、　2/2*2の結果はリアルで言うと(2/2)*2と同じ結果になる。(2.4.2 演算子の優先順位）

1）constとdefine()の違いはなにか？ (2.1.6.4 定数）
2）スカラー型とは？ (2.2 データ型）
3）整数型/浮動小数点/文字列/論理値/配列かどうかを調べる関数は？ (2.2 データ型）
4)浮動小数点のうち広い範囲の数値を扱う上で、必要なモジュールとは？ (2.2 データ型）
5)NULLは0であるか否か？ (2.2.9 NULL）
6）変数に値が入っているかどうかを調べる関数、変数を空っぽにする関数は？ (2.3.4 ガベージコレクション）
7）文字列と数値を比較する時、どのように比較されるか？ (2.4.4 暗黙のキャスト）
　
　
　
　

解答
1）defineは関数constは構文。したがって、constは返り値や変数などを使うことができない。関数内でも使えない。
　逆にdefineはクラス内での定数定義には使えない。といった違いがある。
2)単一の数値を取る型のこと。
3)IsInt()，IsInteger()　/ Isfloat(),isReal()/IsString()/IsBool()/IsArray()
4)BC拡張モジュール・GMBモジュール
5)NULLは０ではない
6)isset()、unset()
7）文字列は数値としては０となり、必ず数値のほうが大きいという判断になる。　

+ 値を返すのはreturnがあるが、返さなくてもいい終了ワードはexitになる。die()はそのexitに文字列を渡す 
  例は下記(2.5.8 exitとreturn)

```index.php
$db = mysql_connect("localhost",$USERNAME,$PASSWORD)
  or die("DB接続不備");

```





```index.php
echo 3 . 2.74;
print "<br>";
echo "9 Lives" -1;
print "<br>";
echo "3.14 Pies" * 2;
print "<br>";
echo "9 Lives" - 1;
print "<br>";
echo "1E3 Points of Light" + 1;

function double($i) {
    return $i*2;
}
$b = $a = 5;
echo '＄a:' . $a;
print "<br>";
echo '＄b:' . $b;
print "<br>";
$c = $a++;
echo '＄c:' . $c;
print "<br>";
$e = $d = ++$b;
echo '＄e:' . $e;
print "<br>";
echo '＄d:' . $d;
print "<br>";
$f = double($d++);
echo '＄f:' . $f;
print "<br>";
$g = double(++$e);
echo '＄g:' . $g;
print "<br>";
$h = $g += 10;
echo '＄h:' . $h;

$i = 'a';
$i++;
echo $i;
print "<br>";
$i = 'z';
$i++;
echo $i;
print "<br>";
$i = 'spaz';
$i++;
echo $i;
print "<br>";
$i = 'K9';
$i++;
echo $i;
print "<br>";
$j = ($k = 4) + 5;
echo $j;
print "<br>";
echo $k;
print "<br>";
$l = "Hello ";
$l .= "There!";
echo $l;

```
出力は

32.74
8
6.28
8
1001

＄a:5
＄b:5
＄c:5
＄e:6
＄d:6
＄f:12
＄g:14
＄h:24

b
aa
spba
L0
9
4
Hello There!


※ 最初は連結前にそれぞれ文字列に変換
※ 数値っぽいものは数値として変換される
※　1E3は1000として変換されるため
※ ++\$varの場合、先に加算される　\$var++の場合、後で加算される
bとcは後で加算されてるのでcはもとの５が入る。
eとｆは前で加算されてるので、eとｆは５に＋１した６が入る。
当然、fとｇもそのように計算される。　
* 最後の段は文字列もインクリメントされ、２６進数を扱っているかのようになる

# 関数
１）関数名が文字かアンダースコアで始まり、その後に任意の数の文字・ 数字・あるいはアンダースコアが続くもの
　→これを正規表現で表すと？
２）以下のコードはどう出力される？

```index.php
<?php

//(1)
function foo(&$var)
{
    $var++;
}

$a=5;
foo($a);
echo $a;
print '<br>';

//(2)
function &func(&$x){
  return $x;
}

$b = 1;
$c = & func($b);
$b = 2;
echo $c;
print '<br>';

//(3)
function &funct(&$y){
  echo $y + 2;
  print '<br>';
  return $y;
}

$c = 2;
$d = & funct($c);
$c = 5;
echo $d;

//4)
$foo = "bar";
$$foo = "baz";
echo $bar;
?>

```



解答
１）^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*\$. 
つまり、アルファベット（大文字小文字）、アンダースコア、0x7Fから0xFFまでの文字のいずれか。
2文字目からはこれらに加えて0から9までの数値が入る。
2)
6
2
4
5
baz
※参照渡しで、たしかに関数内では4になるのだが、なぜか外だと5になる。
関数内がどんな数式であっても、結局は代入された\$cの値が\＄dとなる。
()内で代入がされたら、それはそれで＄ｋ＋５されると考えれば良い

# ビット演算子
２進数の計算に使う。そもそもプログラムはビット、つまり０と１だけで動いている。
６つしかないので覚えてしまおう。

1.論理積
2.論理和
3.排他論理和
4.否定
5.左シフト
6.右シフト

それぞれ記号と意味を答えよ。
参照：https://www.sejuku.net/blog/78679
ありがとうございます！
　
　
　
解答
1.&(アンパサンド）　・・・1と1の場合は1でそれ以外は0
2.|(パイプ）　　　 ・・・0と0の場合は0でそれ以外は1
3.^(キャレット)    ・・・両方同じ場合は0、それ以外は1
4.~（チルダ）      ・・・すべての値が反転
5.<<      　　　 ・・・左に値をずらし、空いた桁は０
6.>>　　　　　　　・・・右に値をずらし、余った桁は無視（なくなる）、空いた桁は０

※代入演算子もあるが、＋＝とかと同じ挙動なので省略
※参考　※覚えておくとビット計算のときに役立つはず
bindec() 2進数を10進数に変換する
decbin() 10進数を2進数に変換する

#キャスト演算子
これをつけると特定の型として扱うことができる。
それぞれの予期しない数値になることもあり、下記の記事を参考にどういう結果になるのか
確認しておく。

参照：@mpywさん
　https://qiita.com/mpyw/items/3aac811629622f7f4d8b

#その他演算子

+ エラー抑制演算子　→＠
+ 実行演算子　→ `(バックティック）で囲まれた文字列をシェルコマンドとして実行
+ 条件演算子　→要するに三項演算子
+ 型演算子　→instanceof　クラスのインスタンスを調べる際に使用

# Switch
Caseが以下のように２つ並んでいる場合「または」という意味になる

```index.php
// 'sivel'または'brutus'のときにYesとプリント
switch ($name){
     case 'sivel' :
     case 'brutus':
       print 'yes';
       break;
     default :
       print 'no';
       break;
}
```
# continue & breakの数値オプション
数値オプションは数値の分だけループから抜けることを意味する。
これはcontinueでも同じ。

``` index.php
$i = 0;
$j = 0;

while ($i < 10){
  while ($j < 10){
    if ($j == 5){
       break 2; //２種類のwhileループから抜けることを意味する
    }
   $j++;
  }
 $i++;
}

echo "{$i}, {$j}";
```
出力
0,5

でもcontinueはもっと複雑かも。

``` index.php
$i = 0;
$j = 0;

while ($i < 10){
  $i++;
  while ($j < 10){
    if ($j == 5){
       continue 2; //２種類のwhileループから抜けることを意味する
    }
   $j++;
  }
}

echo "{$i}, {$j}";
```
出力
 10,5
continueは一旦その場はスキップするという処理。
それを２回分する場合、一番上のwhileの初めまで戻るということ。
つまり\$iはどんどん増えていくが、\$jはいつまでたっても５以上にはならず、永遠にスキップし、
\$iの条件式が終わるまで続く。
そのため10,5という結果になる。

# declare文
declare 文は、あるコードブロックの中に 実行ディレクティブ（現在はticks、 encoding、 strict_types をセットするというもの。
オプションは実行する回数になる。
この記述がスクリプト冒頭にない場合はphp.iniのzend.script_encodingの設定が元になる。


## ticks
・declareが宣言されてるコードで、N個の低レベル tick 可能な文を実行するごとに 発生するイベントのことです。Nの値は declareブロックのディレクティブの箇所で ticks=Nのように 指定します。（下記）
ただし、条件式や引数式などは tick できない。
イベントごとにコールされる関数はtick_handler()で作成し、それをregister_tick_function()でコールする。

```index.php
<?php


declare(ticks=1);

// tick イベントごとにコールされる関数
function tick_handler()
{
    echo "tick_handler() called";
    print "<br>";
}

register_tick_function('tick_handler'); // tick イベント発生

$a = 1; // tick イベント発生

if ($a > 0) {
    $a += 2;   // tick イベント発生
    print($a . "<br>"); // tick イベント発生
}

?>

```

出力は
tick_handler() called
tick_handler() called
tick_handler() called
3
tick_handler() called

register_tick_functionでtickイベントごとにコールされる関数を登録、
それ以降行ごとにtickイベントが発生してコールされている。

## encording

スクリプトのエンコーディングをスクリプトごとに指定するために使う。

```index.php
declare(encoding='ISO-8859-1');
// ここにコードを書きます
```
## strict_type(厳密な型付け）
マクロで言う、Option Explicitみたいなもの。
型宣言に正確に対応する値のみを受け入れ、 そうでない場合、TypeError が発生する。

```index.php
declare(strict_types=1);
```

# SGML形式/ASP形式/\<script>タグ/直接入力

+ SGML形式はショートタグと呼ばれ、「<? echo "..." ?>」とかく　はじめのタグにphpがないだけ
+ --enable-short-tagsオプションか、short_open_tagを有効にする
+ ASP形式は「<%　echo "..." %>」
+ \--enable-asp-tagsオプションか、asp_tagsを有効にする
+ スクリプト形式はJSと同じように\<script language="php">\</script>とし、その中に書く
+ 直接入力は「<?= "DAWN"; ?>」みたいな形式。これはASP形式でも可能。