PHPで忘れがちなこと(その1)

ProgeteでPHPをやっています。
これまで断片的に調べながら書いていたので、体系的に学習することは、とても効率的だと実感しています。

特にPHPでもWordPressから入った身としては、オブジェクトやクラスなどを意識することなく、世にたくさんある参考サイトを見ながらコードを貼り付けていました...そんな感じでサイトを作れてしまうWordPressは易しいというか。

次第にフレームワークを使ったサイトやフルスクラッチのサイトを垣間見ては行き詰まり、解読してちょろっと書いて...という状態です。

手元にはLaravelの本もあるのにほとんど読んでいません。
本を買ったときの情熱を思い出して、基礎から勉強します!

前置きが長くなりましたが、思い出したときに振り返られるように、私が忘れがちなことを書きました。

文字列の中に変数を入れる

$name = "太郎";  
echo "こんにちは、{$name}さん";  // こんにちは、太郎さん
echo 'こんにちは、{$name}さん';  // こんにちは、{$name}さん

ダブルクォーテーション "" で囲むと変数展開というものができます。
一方でシングルクォーテーション'' で囲むと、中を文字列として扱います。

だいたいは echo "こんにちは、".$name."さん" として書くことが多いのですが、場合によっては上記の書き方の方が見やすいので書き分けたいところです。

また変数展開同様に改行コードを使うときもダブルクォーテーションで囲みます。

echo "\r\n";  // 改行される。文字列扱いしたいのなら「"\\r\\n"」と書く(エスケープ処理)
echo '\r\n';  // \r\n として出力される。

となります。

https://yaruzou.net/html-quotation

""'' どちらを使うべき?

これらのような場合以外ではどちらでも使える、というシングルクォーテーション''とダブルクォーテーション""
コードの中で混ざっていると気持ち悪いです。

統一するならどちらだろうと調べました。

PHPのダブルクォーテーションとシングルクォーテーションの違いを理解する - Qiita

速度に違いがあるとは!基本シングルクォーテーションを使うようにします。

htmlのタグを出力するときなどもシングルクォーテーションで囲った方が便利です。

echo '<img src="image.jpg">';
echo "<img src=\"image.jpg\">";  

後者のように "" で囲った中で "" を使う場合は、文字列として認識させるためのエスケープ処理が必要です。

javascriptの場合

javascriptでも変数展開を見かけた事があったのでついでに。

var = "花子"   
console.log(`こんにちは、${name}さん`)   // こんにちは、花子さん

囲むのはバッククォート` を使います。 そしてこれはES2015(ES6)からのテンプレート構文(Template literal)で使えます。

バッククォートでも囲える!

JavaScript (ES2015) 文字列中に変数展開できるテンプレート構文のメモ - かもメモ

そして「シングルクォートとダブルクォート(加えてバッククォート)どちらがいいの?」という問題ですが、

JavaScriptのシングルクォーテーションとダブルクォーテーション - Qiita

【JavaScript】コーディング規約の文字列リテラルのクオートはどれを採択すべきか

PHP同様、状況に応じて使い分けたほうがよさそうです。
処理速度については調べ切れませんでした。

()のくくり方

if文の if(条件A && 条件B){} という書き方。
私がよくやってしまうのが if((条件A) && (条件B)){} という書き方。
() が余計なのです。

「条件A」に == などの比較演算子が使われていると () でくくりたくなってしまいます。くくっても動きはするのですが冗長なのでやめます。

$i = 15;
if ($i % 3 == 0 && $i % 5 == 0){}  // これでOK
if (($i % 3 == 0) && ($i % 5 == 0)){}  // 条件式を()でくくらなくてよい

全ては演算子

  • 評価の優先順位
    and < = < && の順で強い、など
  • 評価順
    1 - 2 - 3(1 - 2) - 3 で左から評価されている→左結合
    $a = $b = $c$a = ($b = $c) で右から評価されている→右結合

という調整の際に()でくくったりします。

https://www.php.net/manual/ja/language.operators.precedence.php

優先して評価させたいがうまくいかないときは () でくくる、と考えておけばいいのかなと思いました。 (その前にそもそものコードの見直しもしたい!)

1行のコードであれば文末の「;」は不要

<?php echo $name ?> でいいのです。

正しくは

phpの「?>(終了タグ)」の直前は「 ; (セミコロン)」を省略することが出来ます。
これはPHPの終了タグにセミコロンが含まれていると解釈されるからです。

PHP の 区切り文字 「 ; (セミコロン)」の扱いについて | WEPICKS!

優しい設計ですね。ただ、複数の文になるときは ; は全ての文末に入れた方がいいですね。

foreachのつかい方

私がループでよく使うのがforeach文です。
for文やwhile文を書かないのは使い分けがうまくいっていない気がするのですが...。

それはさておき、キー変数も入れる foreach($array as $key => $value) という書き方もあまりしない、無駄な書き方をしているのではないかと思い、見直してみます。

foreach($array as $key => $value) は連想配列

結論は、「foreach($array as $key => $value)$key =>連想配列でも省略できるので、$key が使いたければこの書き方をすればよい」となりました。

普通の配列でもこのforeach($array as $key => $value)は使えて、

$fruits = ['apple', 'orange', 'banana'];
foreach($fruits as $key => $value) {
echo 'フルーツの' . $key . 'つ目は' . $value . 'です';
echo '<br>';
}
// フルーツの0つ目はappleです
// フルーツの1つ目はorangeです
// フルーツの2つ目はbananaです

と、$key にはインデックス番号が入ります。
なので◯番目がどう...とかしたいときには使えそうです。

そこで、いつもどのように foreach を使っているか振り返ってみると、多次元配列が多い気がしました。

$foods = [
  ['group' => 'fruit', 'name' => 'banana', 'color' => 'yellow'],
  ['group' => 'vegetables', 'name' => 'carrot', 'color' => 'orange'],
  ['group' => 'fruit', 'name' => 'apple', 'color' => 'red']
];
foreach($foods as $food) {
  echo '食べ物の種類は' . $food['group'] . 'で、名前は' . $food['name'] . 'で、色は' . $food['color'] . 'です';
  echo '<br>';
}
// 食べ物の種類はfruitで、名前はbananaで、色はyellowです
// 食べ物の種類はvegetablesで、名前はcarrotで、色はorangeです
// 食べ物の種類はfruitで、名前はappleで、色はredです

という書き方です。
そこで、別の方法を考えると、

foreach($foods as $food) {
  foreach($food as $key => $value) {
  echo $key . ':' . $value . '、';
  }
  echo '<br>';
}
// group:fruit、name:banana、color:yellow、
// group:vegetables、name:carrot、color:orange、
// group:fruit、name:apple、color:red、

foreachの中にforeachを入れました。近い感じになりました。

それにしても例の配列の中身、微妙。

おさらい↓

【PHP入門】多次元配列・連想配列の使い方と便利な関数を解説! | 侍エンジニア塾ブログ(Samurai Blog) - プログラミング入門者向けサイト

ここまで書いて、もしかして、配列ありきのループはforeachを使うと都合いいのでは?...と思ったのですが、確信持てず。
その都度forやwhileも念頭に置きながら書いていこうと思います!

***

以上です。

結構文法ミスのエラーの場合もあるので、小さいことでも抑えておきたいです。

タイトルに「(その1)」と付けてしまったので「(その2)」も書きます。クラスについて書く予定です。

追記:その2書きました!