ブログ

  • 【書評】つくって覚えるPHP入門

    つくって覚えるPHP入門 オフィス加減(著)の書評です。

    良い点

    • 実践的なミニアプリが4本
    • アプリ作成の学習が楽しめる
    • 図がわかりやすい
    • 簡素で無駄がなく内容が濃い
    • お手軽な薄さ

    悪い点

    • セキュリティが甘い点あり
    • 朱(薄赤)と黒の二色刷り

    総評

    他のPHP入門本に比べて、コンパクトで薄い本です。
    しかし、実践的で、内容が濃いです。

    『つくって覚える』のタイトル通り、アプリを作りながらPHPを学ぶ構成になっています。作成するミニアプリは次の4つ。

    • メールフォーム
    • 画像アップローダー
    • アンケートシステム
    • 会員制掲示板

    どれも手頃な難易度のスクリプトで、PHPの文法書に飽きた初心者にお勧めのサンプルです。

    基礎の復習と応用に向いていて、中級レベルの知識もそこそこ扱われています。

    PHPに慣れている人なら、1つのアプリを1時間弱でこなせるので、4時間あれば読み終えられます。

    開発環境はXAMPPが紹介されています。この導入部分もわかりやすいです。

    データベースはMySQLを利用しています。

    悪い点として挙げた、赤(朱)と黒の二色刷りの点ですが、これは好みによりますね。赤は目が疲れるので、自分的には青と黒の二色刷りが良いのです。

    セキュリティは、この本だけでは不足しているので、他の本でしっかり学ぶ必要があります。この本を読んだらステップアップとして、セキュリティに詳しい本を次に読むことをお勧めします。

    全体的には、解説が丁寧で著者の真摯さが伝わってくる良書だと思います。

    [補足]

    この本には、SSHやTelnetなどの用語がでてきます。これらは、サーバーにログインして、サーバーを操作する方法です。SSH接続するには、TeraTermというフリーソフトがお勧めです。TeraTerm SSH で検索すると使い方が出てくるので目を通すと良いかもしれません。ただ、ここら辺はPHPの本質的な部分ではないので、わからなければ、飛ばして読んでもそれほど問題ないと思います。

    ちなみに、自分は、以前、世界でいちばん簡単なUnixのe本 という本を読み、SSHとTeraTermについて学習しました。

    つくって覚えるPHP入門

  • 【書評】パーフェクトPHP

    パーフェクトPHP(技術評論社)の書評です。

    良い点

    • 基礎をプロの視点で掘り下げて解説
    • あやふやになりがちな点をきちんと説明
    • セキュリティの章が秀逸
    • 上質紙を使っている

    悪い点

    • 誤字脱字が所々に散見される
    • 白黒の一色刷り

    総評

    この『パーフェクトPHP』は、PHP中級者以上、もしくは、他言語既習者を読者として想定しています。“はじめに”として、その旨が明記されています。

    構成は、パート1~6(全14章)と付録で構成されています。

    ぜひ読んでおきたいのが、パート4のセキュリティの部分です。約90ページほどかけて、WEBアプリケーションのセキュリティについて解説しています。

    このセキュリティのパートは、他のPHP本と比べても特に秀逸な出来になっています。
    『説明』→『脆弱性のコード例』→『対応方法』と、良くまとまっています。典型的な16ほどの攻撃パターンを丁寧にわかりやすく解説しています。

    パート2では、140ページほどかけて、基礎的な文法を、中級レベルの視点で解説しています。あやふやな点を明確にして、コーディングの質を高めるプロの姿勢が感じられます。
    最後のパート6では、100ページほどかけて、PHPのリファレンス的な内容になっています。

    この本の肝となるパート3では、実践的なWEBアプリケーションの作成(ミニブログ)に取り組みます。

    ここでは、この本独自のフレームワークを使った開発手法が取られています。フレームワークの本質を学びたい人には、役立つパートだと思います。

    ただ、いわゆるレガシーな昔ながらの手法で手一杯な人には、このパートはハードルが高くなります。

    ——————————————————-

    (補足)

    この本の肝は、基礎の解説、フレームワークの解説、セキュリティの解説の3つにあると思います。

    基礎とセキュリティは、レガシーコード志向にも役立ちますが、フレームワークについては、敷居が高くなってしまいます。興味はあるのですが。

    フレームワークを使った開発は、JavaやRoRなどでの開発経験がないと厳しいのかもしれません。

    PHPでは、フレームワークが乱立している状態で、標準が無いのが、学習意欲を減退させているようにも思います。

    フレームワークを学ぶなら、Rubyを一から習得してRailsを学ぶ方が学習コストが少ないのかもと思ったりもします。

    実際、個人で簡単なPHPスクリプトを組むだけならフレームワークはいらないのですが、やはり、プロとして働く人にはフレームワークの習得は必須なのでしょう。

    パーフェクトPHP

  • 【MySQL】nullを取得できないケースの対策

    PHPとMySQLを使っていて、null値の取得ができない場合の対策について覚書しておきます。

    テーブルからデータを取り出し(fetch)して、繰り返し処理で、配列に値を入れる場合、当該データがNULL(null)のケースでは、上手くいかないことがあります。

    具体的に言うと、null値でデータが無い場合には、ゼロ(0)が入って欲しいところ、データ自体(データの行そのもの)が無いものと処理されて、期待した結果にならないケースです。

    この場合には、先に、当該データを0で初期化するのが一つの解決方法です。

    つまり、あらがじめ、データを格納する配列の値に、繰り返し処理で0を代入しておく訳です。

    $i = 1 ;
    while ($i <= count($data)) {
      $data[$i] = 0 ; //0に初期設定
      $i++ ;
    }
    
    $sql = "SELECT * FROM table1" ;
    $res = mysql_query($sql) or die("error") ;
    while ($row = mysql_fetch_assoc($res)) {
      $i        = $row["no"] ;
      $data[$i] = $row["value"] ;
    }

    この様にゼロで初期化してから、データをfetchして配列$dataに入れれば、仮に、当該配列の値がnullで値を取れなくても、ゼロで初期化されているので、そのままゼロを出力できるようになるのです。

    ちなみに、whileでなくforで繰り返し初期化しても同様の結果になります。

  • 【PHP】2重ループ(2重while)が動かない時の注意点

    コーディングしていると、2重ループのスクリプトを書くケースが出てきます。

    今回、このケースで少し躓いたので覚書しておきます。

    結論を言うと、外側のループと内側のループでは、処理に違う変数を使うこと。

    当たり前のことですが、外側と内側で同じ変数を使うと2重ループとして処理されず、おかしな挙動になります。

    ちなみに、この場合は、構文エラーではないので、エラーメッセージが出ず不具合の原因がわかりにくくなっています。

    具体例を出すと下のような構文です。

    while($row = mysql_fetch_assoc($res1)) {
        while($row = mysql_fetch_assoc($res2)){
         echo $row["sample"] ;
        }
    }

    外と内のループで同じ変数$rowで結果を受けています。

    この場合には、二重ループとして処理されず、期待通りの結果になりません。

    $row を、$row1、$row2などと区別してやる必要があります。

    先にも述べましたが、このケースでは、エラーが出ないので間違いが分かりにくくなっています。

    単純なケアレスミスですが、一応、覚書しときます。

  • 【PHP】入力チェック用スクリプトの一覧

    PHPでは、フォームからの入力に対して、入力値のチェックが欠かせません。

    そこで、ここでは、PHPの基礎的な関数を利用して、入力値のチェックをする方法を一覧にしておきます。

    //ポストされた時のみ処理
    if ($_SERVER["REQUEST_METHOD"]=="POST"){
    //エラー格納変数の配列初期化
    $_errors = array() ;
    //変数$dataにポストの値を代入
    $data = $_POST['data'] ;
    //$dataが空でないかチェック
    if(trim($data) ==''){
    $_errors[] = "入力されていません。" ;
    }
    //文字数チェック
    if (strlen($data) > 8) {
    $_errors[] = "文字数が8文字を超えています" ;
    }
    //$dataが数値(整数値のみ)であるかチェック
    if(!ctype_digit($data)){
    $_errors[] = "数値以外が含まれています。" ;
    }
    //$dataに数値0-9以外が含まれていないかチェック
    if(preg_match("/[^0-9]/",$data)){
    $_errors[] = "数値以外が含まれています。" ;
    }
    //入力値が半角英数で10文字以内かチェック
    if (!preg_match("/^[A-Za-z0-9]{1,10}$/", $data)){
    $_errors[] = "入力値が不正です。";
    }
    //メールアドレスのチェック1
    if (!preg_match("/^[^@]+@([-a-z0-9]+\.)+[a-z]{2,}$/", $data)){
    $_errors[] = "不正なメールアドレスです。";
    }
    //メールアドレスのチェック2
    $reg = 
    "/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/iD";
    if (!preg_match($reg, $data)) {
    $_errors[] = "不正なメールアドレスです。";
    }
    foreach ($_errors as $error){
    echo "$error".'<br>';
    }
    //if_end
    }
    //その他
    //特定の文字以外は空に置き換える
    $data = preg_replace("/^[A-Za-z0-9_.-]/","", $data) ;
    //変数を整数型に変換する
    $data = intval($data) ;
    
    //変数を浮動小数点型に変換する
    $data = doubleval($data) ;
    //日付チェック
    if (!checkdate($month,$day,$year)) {
    $_errors = "日付に誤りがあります" ;
    }