PHP5上級試験/準上級試験の上級合格に挑戦(5)　4章文字列前編

#参考
[PHP5技術者認定試験(上級)に学ぶ、文字列との和解(2) | ＠tmak_tsukamoto
さん](https://qiita.com/tmak_tsukamoto/items/41673ab2d6fedeef0980)

#4章 文字列

### キーワードと概要
エスケープ/変数の展開/ヒアドキュメント/言語構造/printf/デバッグ関数/文字列操作関数/エンティティ置換関数・エンコード処理関数・エスケープ処理関数/文字列比較関数/文字列分解・結合関数/文字列検索関数/

+ ここでは基本的に関数とメソッドが多く出てくる。テーマごとに分けてしっかり覚える
+ 変数の展開・ヒアドキュメント・言語構造でマルバツ問題出題が多い
+ セキュリティ上、エスケープ処理やエンティティ置換などの関数は他の章でも多々出てくる印象。ここで覚えておくと後が楽。 

### エスケープ
+ もともと文字列を囲む場合””(ダブルクォート)と''(シングルクォート）の２つがある
+ 上記とバックスラッシュをただの文字列として入れたい場合エスケープシーケンス（特殊な文字の前にバックスラッシュ(\)を置くやり方）を使用する。
+ ちなみに改行は\n、タブは\t。
+ 大抵の場合、クォートをカッコとして使いたいときや、HTMLにPHPを埋め込むときによく使う。

```
$baloon = "\"ある青年の日常\"という本";　// "の前に\をおく
echo $baloon;
```
出力は　"ある青年の日常"という本
となる。　

### 変数展開

+ <b>ダブルクォート(")</b>で囲まれた文字列と、<b>ヒアドキュメント</b>内で可能
+ 文字列内に変数が入ると、変数の内容が文字列に埋め込まれるというもの
+ 展開したい変数名の後ろに識別子として使える文字が続くと、変数名が続いてると解釈される
+ 変数名を波括弧（｛｝）でくくるとよい
+ コードを出して、どう出力されるかが問われるのが多い


```index.php 
//(1)
$namae = 'ご機嫌';
echo "やあ、$namae";
//(2)
$namae = 'ご機嫌';
echo "やあ、$namaeかい";
//(3) （２）の修正
$namae = 'ご機嫌';
echo "やあ、{$namae}かい";
```
（１）は「やあ、ご機嫌」と出力
（２）は「やあ、」と出力
（３）は「やあ、ご機嫌かい」と出力

### ヒアドキュメントとNowdoc

+ どちらも複数行からなる文字列を記述する際に使用
+ HTMLでいう\<pre>~\</pre>のような整形済テキストのようなもの
+ \<<<EOSとEOS;で文章を囲む EOS;は終端IDと呼ばれる
+ Nowdocの場合<<<’識別子'と識別子; と、はじめの行でシングルクォートで識別子を囲むだけ
+ 前項にもあるとおり<b>ヒアドキュメントは変数展開OKだがNowdocはできない</b>(正誤問題に出そう）
+ ヒアドキュメント内に記述された空白文字、シングルクォート、ダブルクォートは記述通りに出力
+ 最終行の改行は取り除かれる(コードの正誤問題に出そう）
+ <b>最終行はスペースやタブを使ってインデントにしたり、コメントを書くことができない</b>（○×問題に出そう）

【問題】下記の記述をヒアドキュメント、Nowdoc、2つの形式で記述せよ。

\<p>Hello,
PHP
World!\</p>



```index.php
//(1) ヒアドキュメント
echo '<p>';
echo <<<EOS
Hello,
PHP
World!
EOS;
echo '</p>';

//(2) NowDoc
echo '<p>';
echo <<<'EOD'
Hello,
PHP
World!
EOD;
echo '</p>';
```

### 言語構造
+ [3章の可変換数のところで説明済](https://qiita.com/Atsulabo/items/b1499fdbcbc7425549a1)
+ 単数の引数であれば、<b>かっこはくくってもくくらなくてもOK </b>
+ echoは複数の引数を区切って記述できる
+ ただし、その場合は<b>かっこでくぐらない</b>　ここややこしいので結構出題されそう。
+ print（）は返り値を持つ→式の一部として使える

``` index.php
//(1)
print ('Hello,World');
//(2)
echo 'Hello','World';
//(3)
echo ('Hello','World');
//(4)
print 'Hello','World';


```
(1) Hello,WOrld
(2) HelloWorld （,は含まれない）
(3) エラー　（echoで複数の引数の場合は囲まない）
（４） エラー　（ｐrintはコンマで複数の引数を扱えない）

### printf
+ 書式文字列を用いて、値を所定の書式にフォーマット化
+ printf(string \$format [, mixed \$args [, mixed $...]]) 
+ 引数は順番に「書式文字列」「出力する式（いわゆる対象）」
+ 簡単に言うと引数1番目は変えるFMT形式、2番めは変える対象を表す。
+ 書式文字列は「置き換えマーク」を含め「型指定子」で終わる。「修飾子」をこの間に入れることも可

問題
（１）printfを使い、「７７」という数字を10進数、3桁（空白あり）、0埋め3桁に変更せよ。 
（２）printfを使い、「３．１３２」を浮動小数点数、整数部1桁と小数部2桁に変更せよ。
（３）printfを使い、「mix]という文字を文字列、５桁、左寄せ５桁に変更せよ。
（４）pritnfを使い、「mix」「７」「３」という文字を文字列・１０進数似変更せよ。
 
``` index.php
//(1)
print('(1)');
print('<br>');
printf('%d',77);
print('<br>');
printf('%3d',77);
print('<br>');
printf('%03d',77);
print('<br>');
//(2)
print('(2)');
print('<br>');
printf('%f',3.132);
print('<br>');
printf('%1.2f',3.132);
print('<br>');
//(3)
print('(3)');
print('<br>');
printf('%s','mix');
print('<br>');
printf('%5s','mix');
print('<br>');
printf('%-5s','mix');
print('<br>');
//(4)
print('(4)');
print('<br>');
printf('%s,%d,%d','mix',5,4);
print('<br>');

```
答え
(1)
77　（１０進数） ※decimalから%d
77　（３桁）
077　（０埋め３桁）
(2)
3.132000（浮動少数点数) ※floatから%f
3.13(整数１桁小数点２桁）
(3)
mix（文字列）　※stringから%s
mix（５桁）
mix（左詰め５桁）
(4)
mix,5,4　（複数の場合複数発動）

### デバッグ用関数

+ print_r()とvar_dump()を使用
+ 出力形式が違う
+ どちらも自分自身を含む再帰的にたどって出力を行う。

問題１　array(1,2)を出力するとき、以下の表示はprint_r()とvar_dump()のどっちを使用しているか。
//(1)
Array
(
   [0] => 1
   [1] => 2
)  
//(2)
array[2]{
   [0] =>
    int(1)
   [1] =>
    int (2)
}

問題２　以下のクラスを出力するとき、以下の表示はprint_r()とvar_dump()のどっちを使用しているか。

class X {
  public \$p = 1;
  private $q = 2;
}

//(1)
X Object
(
   [p] => 1
   [q:X:private] => 2
)  
//(2)
object(X)#1 [2]{
   ["p"] =>
    int(1)
   ["q":"X":private] =>
    int (2)
}

問題３



問題１と２のどちらも、答えは、（１）がprint_r(),(2)がvar_dump();

### 中間まとめ

+ 今回は、エスケープ/変数の展開/ヒアドキュメント/言語構造/printf/デバッグ関数だけ扱った。
+ コード形式の問題で出力の正誤を問う問題が多く出題されるイメージ。
+ printfは結構慣れるまでは難しいので調べながら書く練習をしておきたい。第１引数の’’のつけ忘れにも注意
+ デバッグ関数は、print_r()とvar_dump()の書式の違いと、再帰的にたどると出力がどうなるか、という出題が多そう。
+ 実際にコードを打ってみてどういう結果になるのか試しながら勉強すると良いと思う。
+ 次回は主に関数全般を扱う。