メニューボタン
IBMi海外記事2010.03.17

RPGの観点からみたPHP-パート1:PHPの基礎

ジョン・パリス 著

PHP基礎概要: 変数、基本出力、配列など

私はPHPを2年以上使用しており、PHPプログラミングをすっかり楽しんでいます。しかし、昔の恋人であるRPGを見捨てたということではありません。私は今でも、ビジネス・アプリケーションのコア・コンポーネントを構築するための言語としては、RPGが一番だと思っています。しかしブラウザを扱うこととなると、RPGでは様々な課題が生じます。最初の、そしてほとんどの人にとって最大の課題は、IBMがネイティブRPG GUI を実装してくれなかったという点です。その結果、ウェブ開発でRPGを使用したい場合、どのサード・パーティー製のAPI群を使用するのかを選択しなければなりません。CGIDEV2など一部のAPI群は無償で使用できますが、他は数百ドルから数千ドルと値段も様々です。CGI API群そのものを直接使ってコーディングするという可能性は、ここでは無視している点に注意してください。CGI API群を直接使用するのは、私たちのほとんどにとってはレベルが高すぎます。こうした様々な選択肢はいずれもそれぞれ長所と欠点がありますが、2つの点が共通しています。アプリケーション、サンプル、トレーニング、コーディング支援などはどちらかというとあまり用意されておらず、Ajax、ウェブ・サービス、ツイッターなどといった新しいテクノロジーが登場しても、それが選択したツールで使えるようになるにはかなり時間がかかります。

PHPにはこうした問題はありません。そして、JavaよりもPHPの方が、慣れるまでが簡単のようなので、私はウェブ開発にはPHPを主な言語として選択するようになりました。私のように、皆さんにもうまく機能するかどうか、まず使ってみて判断しようと思っていただければと思います。本稿は、RPGのプログラマにPHP言語を紹介することを目的とした連載(RPGの観点からみたPHP)の第1回目です。PHPとRPGをできるだけ多く比較することで、両者の違いや類似点を説明していきます。

このパート1では、変数の定義から基本的な制御構成要素や簡単な出力など、PHP言語の基礎にフォーカスを当てます。さらに、print_r()とvar_dump()という2つのPHPデバッグ用関数についても説明します。この関数はすぐに皆さんの「親友」となるでしょう。PHPを学習していくにしたがって、PHPプログラム内でデータがどのように構成されているのかを理解するのに、この2つの関数は貴重な存在です。

PHPの文法の詳細を単に紹介するのではなく、簡単なPHPスクリプト(PHPで「プログラム」のことを指す用語)を通じて、PHP言語のいくつかの主要な機能を紹介します。このスクリプトはたくさんの処理をするわけではなく、いくつかのデータをブラウザに出力するだけのものですが、PHP言語のいくつかの主要な機能をカバーしており、皆さんが「Hello World」のプログラム例から学んだことは少なくないと思います。

本稿をお読みいただくだけでなく、このシリーズに「お付き合い」いただいて、ご自分のPHP環境でスクリプトを実行させてみることを、強くお勧めします。この第1回の記事に登場する2つのスクリプト(図-1図-2)は、テキストファイルとしてオンラインで入手できますが、これくらいの短い例でしたらご自分で手入力されることをお勧めします。お仲間に加わっていただくのに、IBM i にPHPをインストールする必要はないということをお忘れなく。最初のいくつかのスクリプト例は、いずれもどのバージョンのPHPでも動作します。本シリーズの後の方でIBM i固有の機能を説明するときになったら、IBM i へのアクセスが必要になります。

PHPは、この世の中にあるほとんどのプラットフォーム上にて無償で使用できますので、ご自宅またはオフィスのPCに(もちろんIBM i にも)インストールして、すぐに旅に出ることをお勧めします。下方にある「PHP広場の設定」には、最適なバージョンのPHPをどこで見つけたら良いかに関する情報が掲載されています。

さあ始めましょう

PHPのスクリプトは<?PHPという文字列で始まり(図―1のA)、PHPの「コードの島」の始まりを表します。あとでお分かりになると思いますが、コードの島をHTMLのページ中に組み込むことができます。そしてこのマーカーこそが、ファイル中のPHPとHTMLのコンポーネントとをシステムが区別できるようにしているのです。

このすぐ後にはPHPのコメント・ブロックが続きます。CLで使用しているのと同じフォーマット(つまり/*で始まり*/で終わる文字列)ですからお分かりになるでしょう。スクリプトの後の方で出てきますが、PHPは現在のRPG IVで使用されている、//改行というスタイルのコメントのフォーマットもサポートしています。スクリプト例の図―1のBでは、スクリプト中で初めて「本当の」PHP文が登場します。

図―1のBでは、変数$myNameに値を代入しているだけです。ご覧の通り、PHPには、RPGのD-仕様に相当するものはありません。変数は単に使用することで定義されます。もちろん、変数の定義をまとめておくというのは良い習慣ですが、言語自体がそれを強制しているわけではありません。実際、PHPでは変数を定義する前にその変数を参照しても問題ありませんが、Zend Studioのような優秀なエディタは、そういうことをすると警告を表示します。これ以外にいくつか気をつけていただきたいことを以下に列挙します。

  • PHPの変数はすべて$記号で始まる
    この記号があることで、変数を扱っているということがわかります。
  • 変数名中の大文字と小文字は区別される(したがって$Nameと$nameは2つの異なる変数です。)
    これがまず1つ目のRPGと異なる点です。RPGでは、上記の2つの表記は同じ変数とみなされます。これは、多くのRPGプログラマが大文字と小文字を区別する言語を初めて使用する際に躓く「道のこぶ」ですが、Zend Studioのような良いツールでは、変数名を入力し始めると使用可能な値を提示してくれるので、こうした問題に躓く可能性を最小限にしてくれます。ほとんどの場合、PHPの関数や言語構成要素(if、elseなど)は大文字と小文字を区別しませんが、変数名では常に大文字と小文字が区別されます。
  • 変数のタイプはその変数に何が格納されているかに依存する
    この(図―1のB)場合、文字列を格納しているのでこの変数のタイプは文字列です。これと図―1のCを比べてみてください。$experienceという変数には整数を格納していますから、この変数のタイプは整数と定義されています。(たとえば)変数$experienceを変数$myNameにコピーしたらどうなるのかと思っていらっしゃるのであれば、もう少し我慢していただければすべてがお分かりいただけます。
  • PHPの文字リテラルは引用符で囲む
    PHPでは、一重引用符(')と二重引用符(")のどちらを使用してもリテラルを区切ることができますが、完全に互換性があるわけではありません。二重引用符で囲まれた文字列は組み込み変数を含むことができますが、一重引用符で囲まれた文字列では、それができません。下に示したEのポイントの記述がその例です。
  • PHPの文はセミコロンで終了する
    これはフリー・フォームのRPGと同じです。しかし、RPGではすべての文においてセミコロンを使用しなければなりませんが、PHPではIf ... Elseのような制御構造では例外があります。これについてはこの後で説明します。

配列の定義と使用

これまでのところは、簡単な文字列や整数変数の定義の仕方について説明してきました。図―1のDでは、$languagesという配列を宣言しています。PHPではこの配列を読み込む方法は多数ありますが、これはRPGでコンパイル時配列としているもっとも一般的な方法です。PHPのarray()関数を使用して、必要な値を正しい順番でリスト表示します。つまり「RPG IV」が最初の値、2番目が「PHP」といった具合です。

PHPの配列は信じられないくらい強力です。確かに、配列を使用していないPHPのスクリプトはほとんど見たことがありません。本当です。PHPの配列をしばらく使ってみると、RPGのコーディングに戻った時に裸になったように感じるでしょうし、PHPで使い慣れていた機能がRPGにはないことに気づくでしょう。配列のその他の側面について下記に説明しますが、これらはRPGとPHPの配列の違いのほんの一部に過ぎません。

  1. PHPの配列の添え字は四角括弧で囲む
    例: $languages[ $index ]
  2. PHPの配列のインデックスは0から始まる
    $languagesという配列の2番目の要素(「PHP」という値を保持している要素)にアクセスするには、PHPでは$languages[1]と記述するのに対して、RPGでは$languages(2)と記述します。
  3. PHPの配列要素はすべてが同じでなくてもかまわない
    RPGでは、配列のすべての要素が同じ「形」(つまり同じデータ・タイプで同じサイズ)でなければなりません。PHPではこのような制限はありません。1番目の要素が文字列で、2番目が整数、3番目が浮動小数点値、4番目がまた別の配列というのでもかまいません。でもちょっと先走りし過ぎてしまいました。多次元配列については、このシリーズの次のパートまでお待ちください。

ブラウザへの出力

スクリプト中にいくつか変数を定義したので、出力を生成してみましょう。PHPの特徴がよくわかるようにするため、例中のHTMLコンテンツ部分は必要最小限に抑えました。改行して出力の形式を整えるために、<br>タグを使用しただけです。「content-type」などといったヘッダーやHTMLタグを自分で書くに越したことはないのですが、PHPではこれらを書かなくても自動的に生成してくれます。

図―1のEでは、echo関数がウェブ・ページにコンテンツを追加しています。Echo関数はPHPの言語構成要素の一つで、パラメータが括弧で囲まれているのをよく目にしますが、括弧で囲む必要は必ずしもありません。出力されるリテラル文字列は、二重引用符で囲まれている点に注意してください。このため、文字列中の任意の変数は、出力される際に格納されている値に置き換わります。ですからウェブ・ページ上に表示されるのは、「このスクリプトはジョン・パリスによって書かれました。」という文字列です。もしここで一重引用符を使用していたら、出力は「このスクリプトは$myNameによって書かれました。」となっていたでしょう。

RPGでリテラルと変数を同じように組み合わせようとすると、もっと大変な作業になります。上記の場合でいえば、次のようなコードを書かなければならないでしょう。

'This script was written by ' + $myName + '.<br>';

これだけだと大した差はないように見えるかもしれませんが、RPGバージョンは、空白の扱い方とか句読点の管理がずっと難しいのです。ですから、PHPのアプローチの方がずっと単純であることがお分かりいただけると思いますし、特にもっと複雑な文字列を作る場合には、PHPの方が簡単であるとお分かりいただけるでしょう。

図―1のEに続く2行は、ウェブ・ページにさらにデータを追加し、複数の変数を文字列中に組み込む方法の例を示しています。また、PHPは基本的な数値変数($experience)を出力する際の基本的な編集機能を提供しています。この場合の効果は、あたかもRPGのBIF %Charを使用したのと同様の効果(つまり先頭の0が削除される)が得られます。PHPはRPGと同様にもっと複雑な編集が行えますが、それについてはまた別の機会で触れましょう。

さて、PHPの構成要素の中でも私のお気に入りのforeach (図―1のF)の話です。この構成要素は、配列に対してその各要素に同じ処理を繰り返すための、実にシンプルな方法を提供するものです。この例では、配列$languages中の各要素を1つ取って順番に変数$languageに割り当てるように、PHPに対して指示しています。括弧{ ... }で囲まれたコード・ブロックが次にこの変数の値を使って実行されます。ここで実行しようとしていることは、変数の中身を出力することです。今回の場合は、print構成要素を使用しています(図―1のG)。条件式中での括弧の使用方法については、このシリーズの後半で別途説明します。

どんな処理を行おうとしているのかを明確にするために、同じ処理をRPGで記述してみました。

   d $languages   s       20a  Dim(6)
   d $language    s       20a
   d $i       s       10i 0

   /free
    For $i = 1 to %elem($languages);
     $language = $languages($i);
     dsply $language;
    EndFor;

率直に申し上げて、PHPとRPGのコードはまったく同じではありません。というのも、PHPは以下に述べる2つの状況を自動的に処理しますが、これはRPG版では処理しようとはしなかったことだからです。1つ目は、私が記述したRPGコードは、配列のすべての要素に値が入っているということを前提としていることです。PHPのforeach()は値がセットされている配列エントリだけを処理します。RPGでこれに対処するには、配列のカウントを用意する必要があります。また、RPGには配列のエントリが「空」という概念がありません。PHPでは(たとえば)、1番目、4番目、6番目の要素だけに値を格納している場合、foreach()は空の配列要素を自動的にスキップしてくれます。

さてprintとechoの両方を紹介しましたが、これらの違いは何なのでしょうか。これら2つの唯一の大きな違いはといえば、echoは複数のパラメータを受け付けますが、printは1つのパラメータしか受け付けないという点です。実用目的でいえば、この2つの構成要素はほぼすべての場合において相互置換可能で、どちらを選択するかはスタイルあるいは個人の好みの問題です。

デバッグ支援

スクリプトの主要な部分は以上です。しかしここで幕引きとする前に、PHP用の2つの素晴らしいデバッグ用ツールをご紹介しておきたいと思います(図―1のH)。PHPは特に配列など多くの点でRPGとは異なるため、私は勉強を始めたころに、次の2つの関数が役に立つと思いました。両方とも果たす基本的な機能は同じ(変数の中身をダンプする)ですが、その提供する詳細の程度が異なります。ある意味RPGのDUMPオペレーション・コードと似ていますが、RPGのDUMPでは不可能なレベルの細かさで提供してくれます。出力内容に対する操作も容易です。

1つ目の関数はprint_r()関数です。ご覧になってお分かりの通り、詳細を知りたい変数の名前($languages)をこの関数へのパラメータとして単純に渡しているだけです。この呼び出しの結果、PHPは配列の中身を取り出して、表示形式を整えた上で表示します。ここであげた例(図―3)では、その出力結果は以下のようになります。

Array ( [0] => RPG IV [1] => PHP ...

この結果からわかることは、この関数に渡した変数は配列であり、その最初の要素(つまりインデックス[0]が付いている要素)には、「RPG IV」という値が格納されていたということです。2番目には「PHP」といった具合に続きます。=>の組み合わせを「指し示す」という意味と考える、すなわち、[0]は値「RPG IV」を「指し示す」と考えると便利だと思いました。

2番目のデバッグ用関数はvar_dump()です。var_dump()は、print_r()よりももっと詳細な情報を提供してくれます。つまり、配列中の各要素のデータ・タイプやその中身の長さを識別します。この関数は、中身に空白が含まれている場合に便利です。というのも、ブラウザは通常、データを表示する際に連続する空白を1つの空白とみなしてしまうからです。ここで示した例(図―4)の出力は以下のようになります。

array(6) { [0]=> string(6) "RPG IV" [1]=> string(3) "PHP" ...

最初の(6)は、この配列に6個の要素があることを示しています。同様に、配列中の各要素の長さとデータ・タイプが識別されています。

連想配列

最初のPHPスクリプトについてはここまでです。すでにたくさんの分野をカバーしましたが、今後の記事ではまだまだ沢山の事柄が出てきます。しかし、ここで終える前にもう1つだけ、私のお気に入りの機能である連想配列について、簡単に触れておきます。

連想配列は、配列の要素が順番づけられた位置ではなく、キーによってインデックスが付けられています。実際、$languagesのような配列も裏を返せば、数字のインデックスを連想キーと考えれば連想配列とみなせます。

連想配列について説明するために、$languagesの定義を少し変更して現在の言語名をインデックス(キー)とし、実際の値をその言語の使用経験年数とします。変更後の定義は次のようになります。

$languages = array("RPG IV"=> 16, "PHP"=> 3, "Java" => 10, ...);

「=>」記号が、キー(「RPG IV」)とその値(16)を連想づけるのに使用されている点に着目してください。

キーと値を言語経験のリストに含めたい場合は(結局経験年数はそれ自体だけではあまり意味を成さないのですが)、次のようにforeachオペレーションを修正します。

foreach ($language as $name=>$years) {
  print "$name for $years years<br>";
}

ここまでくれば、この文法がどのように動作するのかお分かりいただけると思います。つまり、各要素に対して順番にキーを変数$nameに、その変数が「指し示す」値を$yearsに割り当てるように、PHPに対して言っています。そして次に、この2つの変数の値を出力するように指示しているだけです。これ以上は簡単にはなりません。そしてもちろんRPGの交互配列よりもずっと簡単で強力になっています。

このような配列の要素に直接アクセスするには、ご想像の通り、キーをインデックスとしたコードを書けばよいのです。つまり、$languages["RPG IV"]と書けば、整数値16が返ってきます。

修正されたスクリプトの完全版(図―2)では、同じ配列の中で文字型要素と整数型要素の両方を使うという概念を、こっそり入れておいたのにお気づきになるかもしれません。このスクリプトを実行するときは、var_dump()が出力する内容の違いを調べてください。

PHPの世界への第一歩をお楽しみいただけたかと思います。次回は、if/elseやfor、whileなどといったPHPの制御構造について掘り下げます。またブラウザへの出力の基礎を覚えていただいたので、ウェブ・ページからの入力に関するPHPの処理機能についても紹介します。

PHP広場の設定

PHP広場用にはどのバージョンのPHPを使用したら良いでしょうか。以下にいくつかの候補を挙げます。主要なディストリビューターはいずれも、Apacheウェブ・サーバーとMySQLデータベース・システムのコピーもインストールしてくれて、完全な作業環境を用意してくれるでしょう。ほとんどの場合、MySQLデータベースを使用する際の便利なツールであるphpMyAdminもインストールしてくれます。

もっともお勧めなのはZend Server Community Editionでしょう。なぜ「もっともお勧め」なのでしょうか。それは新しいZend Serverが、IBM i上のPHPの次世代版のベースとなる可能性が高いからです。Zend Server Community Editionのコントロール・パネル(すでにIBM i上のコントロール・パネルに非常に似ています)に慣れておけば、あとになって大いに役立つでしょう。Zend CEはPC、Mac、Linux上で使用できます。

もう一つの人気のオプションは、Friends of Apacheから提供されているXAMPPです。XAMPPは、私がWindows PC上で最初に使用したオリジナルのPHPシステムです。私がMacに替えた当時にMac上でも利用可能であったならば、いまだにXAMPPを使用していたかもしれません。

幸運にもMacを使用されている方には、MAMPももう一つの強力なライバルで、私も一部の作業ではこれをいまだに使用しています。

データベースやウェブ・サーバーのコンポーネントは不要で、PHPをちょっとだけ使ってみたいだけだという方向けの選択肢としては、Zend Studioがあります。PHPのコーディングやデバッグにはいずれにしろこれをダウンロードすることになるのですが、このシリーズで使用するような簡単なスクリプトを試してみるのに、Zend Studioを使用することもできます。Zend Studioは、Zend Coreと同様に、IBM iの開発者に対して無償で提供されています。一般の人は$399を支払わなければなりませんが、IBMとZendは、パッケージの中にZend Studioを同梱しています。Zend Studioについては本稿では長々と話しませんが、Zend StudioはEclipseベースのツールで、PHPのコーディングの速度を上げるための素晴らしい機能を備えており、IBMのRDiに統合してRGP、CL、SQLでの作業と同じ環境でPHPの開発を行うこともできます。

あわせて読みたい記事

PAGE TOP