PHPプログラミング診断室

第1回 HTMLとPHPの見事なハーモニー(診断編)

この記事を読むのに必要な時間:およそ 7.5 分

こんにちは。新原です。PHPプログラミング診断室はじまりました。巷に溢れる病めるPHPコードを診断していきたいと思います。

PHPのコードと聞くとどういったイメージを想像されるでしょう? 昔からPHPを知っている方であれば,まずイメージするのが,HTMLとPHPが混在するコードではないでしょうか。HTMLの中にPHPが書けるのは大きなメリットでもあります。ただ,すべての処理がHTMLの中に混在すると,これはなかなか理解しづらいコードになっていきます。もしかすると,そんなコードを見て,PHPに良くないイメージを持った人がいるかもしれません。

初めての診断は,まさにHTMLとPHPが混在するコードです。では,お入りください。

関数定義がなく,流れるようなコードの妙技

今回のPHPコードは,2002年ごろに書かれたものです。とあるWebサイトで稼働していました。内容は,よくあるメールマガジンの申し込みフォームです。フォームでメールアドレスと購読するメールマガジンを入力して送信すると,DB(PostgreSQL)に保存します。元のコードでは,メール送信などの処理もあったのですが,ここでは省略しています。

では,さっそくPHPコードを見てみましょう。

<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=euc-jp">
<title></title>
</head>
<body>
<center>
<form method="POST" action="">
<table border=1 cellspacing=2 cellpadding=5 width=700><tr><td>

<?php
$err_idx = -1;

switch($mode) {
case "":
  print "<input type=\"hidden\" name=\"mode\" value=\"add_check\">\n";
  print "<div align=\"center\">\n";
  print "<br><br>\n";
  print "<br>\n";
  print "<table border=0 cellspacing=2 cellpadding=5>\n";
  print "<tr><td align=\"center\" colspan=2 nowrap>メールマガジン購読</td></tr>\n";
  print "<tr><td align=\"left\" colspan=2 nowrap>メールアドレスをご記入下さい。</td></tr>\n";
  print "<tr>\n";
  print "<td align=\"right\" nowrap>E-mail : </td>\n";
  print "<td align=\"left\" nowrap><input type=\"text\" name=\"frm_email\" size=30 maxlength=100 value=\"$frm_email\"></td>\n";
  print "</tr>\n";
  print "</table>\n";
  print "</div>\n";

  $cn = pg_connect('user=vagrant dbname=app');
  if ( $cn == false ) { $err_idx++; $err_value[$err_idx] = "system error"; break; }
  $sql = "select * from magazines;";
  $rec_magazines = pg_exec($cn,$sql);
  if ( $rec_magazines == false ) { $err_idx++; $err_value[$err_idx] = "system error"; pg_close($cn); break; }

  $mailm_cnt = pg_numrows($rec_magazines);
  if ( $mailm_cnt == 0 ) {
    $err_idx++; $err_value[$err_idx] = "購読できるメールマガジンがありません";
  } else {
    if ( $mailm_cnt != 1 ) {
      print "<div>\n";
      print "<hr>\n";
      print "購読するマガジンにチェック後,購読ボタンをクリックしてください。\n";
      print "</div>\n";
      print "<table border=0 cellspacing=2 cellpadding=5>\n";

      for ( $idx = 0;$idx < $mailm_cnt;$idx++ ) {
        $id = pg_result($rec_magazines,$idx,id);
        $name = pg_result($rec_magazines,$idx,name);

        print "<tr><td align=\"left\" valign=\"top\">\n";
        print "<input type=\"checkbox\" name=\"frm_id[$idx]\" value=$id>\n";
        print "<b>$name</b><input type=\"hidden\" name=\"frm_name[$idx]\" value=\"$name\">\n";
        print "</td></tr>\n";
      }

      print "</table>\n";
    } else {
      $id = pg_result($rec_magazines,0,id);
      $name = pg_result($rec_magazines,$idx,name);

      print "<input type=\"hidden\" name=\"frm_id[0]\" value=$id>\n";
      print "<input type=\"hidden\" name=\"frm_name[0]\" value=\"$name\">\n";
    }
    print "<input type=\"hidden\" name=\"frm_mailmg_cnt\" value=$mailm_cnt>\n";
    print "<div align=\"center\">\n";
    print "<br>\n";
    print "<input type=\"submit\" value=\"購読\">\n";
    print "</div>\n";
    print "<div align=\"center\">\n";
    print "<div class=\"mainlink\">\n";
    print "<br><br>\n";
    print "<br><br>\n";
    print "</div>\n";
    print "</div>\n";
  }
  pg_freeresult($rec_magazines);
  pg_close($cn);

  break;

case "add_check":
  if ( trim($frm_email) == "" ) {
    $err_idx++; $err_value[$err_idx] = "メールアドレスを入力して下さい!";
  }
  elseif ( eregi("^[_]{1}|^[\.]{1}|^[\-]{1}",$frm_email) == True ) {
    $err_idx++; $err_value[$err_idx] = "メールアドレス記入に誤りがあります!";
  }
  elseif ( eregi("(^[0-9A-Za-z_\.\-]+[@]{1})([^_\.\-]{1})([0-9A-Za-z_\.\-]+)([^_\.\-]{1})$",$frm_email) == false ) {
    $err_idx++; $err_value[$err_idx] = "メールアドレス記入に誤りがあります!";
  }
  else {
    $cn = pg_connect('user=vagrant dbname=app');
    if ( $cn == false ) { $err_idx++; $err_value[$err_idx] = "system error"; break; }
    $sql = "select * from members where lower(trim(email)) = '" . strtolower(chop($frm_email)) . "';";
    $rec_members = pg_exec($cn,$sql);
    if ( $rec_members == false ) { $err_idx++; $err_value[$err_idx] = "system error"; pg_close($cn); break; }
    $members_cnt = pg_numrows($rec_members);
    pg_freeresult($rec_members);
    pg_close($cn);
    if ( $members_cnt != 0 ) {
      $err_idx++; $err_value[$err_idx] = "すでにメールマガジン購読受付が完了しています!<br>" . "[ " . $frm_email . " ]";
      break;
    }
  }

  $ok_flg = 0;
  print "<input type=\"hidden\" name=\"frm_mailmg_cnt\" value=$frm_mailmg_cnt>\n";
  if ( $frm_mailmg_cnt > 1 ) {
    for ( $idx = 0;$idx < $frm_mailmg_cnt;$idx++ ) {
      if ( $frm_id[$idx] ) { $ok_flg = 1; break; }
    }
  } else {
    $ok_flg = 1;
  }
  if ( $ok_flg == 0 ) { $err_idx++; $err_value[$err_idx] = "購読希望するマガジンへチェックをお願いします。"; }

  if ( $err_idx != -1 ) { break; }

  $mode = "add";

  break;
}

switch($mode) {
case "add":
  $cn = pg_connect('user=vagrant dbname=app');
  if ( $cn == false ) { $err_idx++; $err_value[$err_idx] = "system error"; break; }

  $sql = "select * from members order by id desc;";
  $rec_members = pg_exec($cn,$sql);
  if ( $rec_members == false ) { $err_idx++; $err_value[$err_idx] = "system error"; pg_close($cn); break; }
  $members_cnt = pg_numrows($rec_members);
  $gid = 0;
  if ( $members_cnt != 0 ) { $gid = pg_result($rec_members,0,id); }
  $gid++;

  $gentymd = date("Y/m/d",time());
  $gemail = ereg_replace("\t","",$frm_email);

  $sql = "BEGIN TRANSACTION;";
  $result = pg_exec($cn,$sql);
  if ( $result == false ) { $err_idx++; $err_value[$err_idx] = "system error"; pg_close($cn); break; }

  $ng_flg = 0;

  $sql = "insert into members values('".$gid."','".chop($gemail)."','".$gentymd."');";
  $rd = pg_exec($cn,$sql);
  if ( $rd == false ) { $err_idx++; $err_value[$err_idx] = "system error"; $ng_flg = 1; break; }

  if ( $frm_mailmg_cnt > 1 ) {
    for ( $idx = 0;$idx < $frm_mailmg_cnt;$idx++ ) {
      if ( !$frm_id[$idx] ) {
      } else {
        $sql = "insert into member_magazines values($gid,$frm_id[$idx]);";
        $rec_member_magazines = pg_exec($cn,$sql);
        if ( $rec_member_magazines == false ) { $err_idx++; $err_value[$err_idx] = "system error"; $ng_flg = 1; break 2; }
      }
    }
  } else {
    $sql = "insert into member_magazines values($gid,$frm_id[0]);";
    $rec_member_magazines = pg_exec($cn,$sql);
    if ( $rec_member_magazines == false ) { $err_idx++; $err_value[$err_idx] = "system error"; $ng_flg = 1; break; }
  }

  if ( $ng_flg == 1 ) {
    $sql = "ROLLBACK TRANSACTION;";
    $result = pg_exec($cn,$sql);
    if ( $result == false ) { $err_idx++; $err_value[$err_idx] = "system error"; pg_close($cn); }
    break;
  } else {
    $sql = "COMMIT TRANSACTION;";
    $result = pg_exec($cn,$sql);
    if ( $result == false ) { $err_idx++; $err_value[$err_idx] = "system error"; pg_close($cn); break; }
  }

  pg_freeresult($result);
  pg_freeresult($rec_members);
  pg_freeresult($rec_member_magazines);
  pg_close($cn);

  print "<div align=\"center\">\n";
  print "<table border=0 cellspacing=2 cellpadding=2>\n";
  print "<tr><td colspan=3 align=\"center\" nowrap> メールマガジン購読完了</td></tr>\n";
  print "<tr><td colspan=3 align=\"center\">\n";
  print "登録が完了しました。";
  print "</td></tr>\n";
  print "</table>\n";
  print "</div>\n";

  break;
}

if ( $err_idx != -1 ) {
  print "<br>\n";
  print "<div align=\"center\">\n";
  print "<table border=0 cellspacing=2 cellpadding=5>\n";
  print "<tr><td><font color=\"#ff0000\">\n";
  for ($idx=0;$idx<=$err_idx;$idx++) {
    print "・$err_value[$idx]<br>\n";
  }
  print "</font></td></tr>\n";
  print "<tr><td align=\"center\">\n";
  print "<input type=\"button\" value=\"戻 る\" onclick=\"history.back()\">\n";
  print "</td></tr>\n";
  print "</table>\n";
  print "</div>\n";
}
?>
</td></tr></table>
</form>
</center>
</body>
</html>

著者プロフィール

新原雅司(しんばらまさし)

1×1株式会社 代表取締役

大阪でPHPを駆使してWebシステムの開発を行う日々。MotoGPをこよなく愛す。愛車はPCX。

Twitter:shin1x1
blog:Shin x blog

コメント

コメントの記入