RAKUS Developers Blog | ラクス エンジニアブログ

株式会社ラクスのITエンジニアによる技術ブログです。

新人エンジニアがはじめてのPHPで戸惑ったこと

はじめに

初めまして。新卒1年目エンジニアのdd_fortranです。
業務でPHPを使い始めて4ヶ月が経ちました。私は学生時代はC言語Fortran、新人研修ではJavaを使用しており、PHPに触れるのはこれが初めてでした。これまでコンパイラ言語に多く触れてきたため、はじめてインタプリンタ言語に触れ戸惑いが多くありました。

本記事では、PHP初心者の私が戸惑ったことについてまとめようと思います。

目次

戸惑ったこと

まず、初めにPHPを学習して戸惑ったことは変数についてです。 今まで学習してきた言語と変数の扱いが大きく異なり、慣れるまで時間が掛かりました。

変数の暗黙の型変換

暗黙の型変換とは、PHPが変数をオートキャストしてくれることです。(便利ですね)

<?php
  $str = "2";
  $int = 5;
  $result = $str * $int;  // $result = (int) 10 
 ?>

上記の場合、「$str = (int) 2」のようにオートキャストされ計算されます。
一見、便利のようですが次の場合には不具合が発生してしまう可能性があります。

<?php
  $str = "2abc";
  $int = 5;
  $result = $str * $int;  // $result = (int) 10 
?>

上記のような実装はすることはないと思いますが、フォームの内容などは文字列として取得されるため比較する際には注意が必要です。

  • 緩やかな比較と厳密な比較

PHPには、緩やかな比較(==)と厳密な比較(===)があり緩やかな比較では型がキャストされてから比較され、厳密な比較では型がキャストされずに比較されます。
例えば次のような違いがあります。

<?php
  $str = "1";
  $int = 1;
  if( $str == $int ) { }     // true
  if( $str === $int) ( }    // false
?>

緩やかな比較と厳密な比較に注意して実装する必要があります。
PHPの公式ドキュメントにPHP 型の比較表があるので、比較の結果が分からなくなった場合にはこれを参考にするとよいでしょう。

戻り値の型が不定

PHPでは戻り値の型が必須ではありません。 例えば次のような実装が可能になります。

<?php
  public function test($bool) {
    if( $bool ) {
      return "OK";
    } else {
      return array();
    }
  }
?>

この場合、戻り値で条件式に利用すると前項の暗黙の型変換と合わせると不具合のもとになります。

また、PHPの組み込み関数では実行し失敗した場合にfalseを返す関数が多く、今まで使ってきた言語ではnullが返ってくることがほとんどだったので違和感があり、最初のころは間違えることが多かったです。

その他

bindValue()とbindParam()の違い

bindValue()とbindParam()とはDBアクセス時にSQLにパラメータをバインドするための関数です。

  • bindValue() :

    値をパラメータにバインドする
    プリペアドステートメントで使用する SQL 文の中で、 対応する名前あるいは疑問符のプレースホルダに値をバインドします。

  • bindParam() :

    指定された変数名にパラメータをバインドする
    準備された SQL ステートメント中で、 対応する名前もしくは疑問符プレースホルダにパラメータをバインドします。 PDOStatement::bindValue() と異なり、 変数は参照としてバインドされ、PDOStatement::execute() がコールされたときのみ評価されます。

PHPの公式マニュアルには上記のように記載があります。
この二つの関数の大きな違いは、bindValue()は値に置き換えであり、bindParam()は参照変数に置き換わるということです。

例えば次の場合に問題が発生します。

<?php
  // 正常に実行される
  foreach ($array as $key => $value) {
    $stmt->bindValue($key, $value);
  }
  $stmt->execute();
  
  // すべてのKEYが$arrayの最後の$valueに置き換わる
  foreach ($array as $key => $value) {
    $stmt->bindParam($key, $value);
  }
  $stmt->execute();
?>

bindValue()の場合は値が置き換わっているため問題なく実行できます。しかし、bindParam()を用いると参照変数に置き換わるため、参照している変数である$valueがループ中に中身が変わり意図しない値がバインドされてしまいます。
このため、通常バインドしたいときにはbindValue()を用いることで不具合は防ぐことができます。

まとめ

PHPを使い始めて4ヶ月の間で戸惑ったことについてまとめました。 PHPにも少しづつなれてきましたが、まだまだ知らない仕様もたくさんあります。 今後はPHPフレームワークにも触れていきたいと考えています。

本記事がこれからPHP学習する方の参考になれば幸いです。


◆TECH PLAY
techplay.jp

◆connpass
rakus.connpass.com

Copyright © RAKUS Co., Ltd. All rights reserved.