はじめに
ランダムに広告を表示したり、多くの応募者から何人かの当選者をランダムに選ぶ場合など、プログラムでランダム性が必要とされる状況はいくつかあります。これらの機能を実現するため、PHPでコンテンツをランダム取得する手法についていくつかの例を見ていきましょう。
対象読者
PHPを既にお使いの方を対象としています。基本的な内容ですが、PHPに関する入門用の内容は含んでいません。また、Amazon Webサービスについての基本的な使用方法なども説明しておりません。必要に応じてPHPマニュアルなどのマニュアルや各書籍をご覧ください。
必要な環境
PHPがインストールされ、PHPスクリプトが動作可能な状態であることを前提としています。また、「広告をランダムに取得する」はMySQL 4.0がインストールされ、「ad.sql」の実行によってadテーブルが作成されていることが必要です。「Amazonからランダムに商品情報を取得する」はPHP5がインストールされ、Amazon Webサービスのデベロッパーキット(SDK)の使用に必要なデベロッパートークンを入手する必要があります。
10回に1回当たりを発生させる
ランダムに値を取得する簡単な例は、mt_rand
関数によるランダムな数値の取得です。ランダムに生成した数値の範囲によって処理を分岐する処理、たとえば、10回に1回の当たりを発生させたいような場合に使われます。次の例では「mt_rand(1, 10)
」と1から10の間で数値をランダムに取得して、「1」の時は当たりと認識しています。これにより、おおむね10回に1回程度、特定の処理に分岐することができます。
<html> <head> <title>ランダムに数値を取得する</title> </head> <body> <?php //「1」が出たら当たりを通知する $var = mt_rand(1, 10); if ($var == 1) { echo "<p>当たりです。"; } echo "<p>取得した値:".$var; ?> </body> </html>
当選者を2人選ぶ
前述の方法では、10回に1回の割合で当たりを発生させることができますが、ランダムに発生させる当たりの回数が決まっている場合は問題もあります。たとえば、応募者の中から当選者を2人選ぶようなケースです。「10回に1回」のように確率をコントロールして当たりを発生させていくと「おおむね」想定の範囲内で収まるでしょうが、結果にばらつきが生じ、場合によっては想定した当選者以上が出てしまうかもしれません。
全員の応募者から2人の当選者を選ぶ場合、応募者分の要素を持ち、値が「0」の配列を用意して、当選を表す「1」を2つセットしておきます。shuffle
関数によって配列をシャッフルすることで、当選者を示すインデックスがランダムな位置に移動するので、「1」がセットされている要素を取得すれば当選者を2人選択することができます。配列を出力した次の図では「高橋」、「佐藤」が当選していることを示しています。
<html> <head> <title>当選者を2人選ぶ</title> </head> <body> <?php //応募者の名前 $array_name = array("田中", "高橋", "小林", "佐藤", "鈴木"); //当選者のインデックスをシャッフルする $array_value = array(1, 1, 0, 0, 0); shuffle($array_value); //応募者と当選者のインデックスを結合する $array_result = array_combine($array_name, $array_value); //配列を出力する print_r($array_result); ?> </body> </html>
広告をランダムに取得する
データベースに格納した広告など、ランダムにデータを取得したいこともあります。MySQLなら、SELECT
コマンドに「ORDER BY RAND()
」を付加することによって、取得するデータをランダムに並べ替えることができます。
次の例ではadテーブルからSELECT
コマンドでデータを取得するときに「ORDER BY RAND()
」を記述しているので、このコマンドで返される広告データがランダムに切り替えられます。mysql_connect
関数内のパスワードははご自分でお使いの値を設定してください。
<html> <head> <title>広告をランダムに取得する</title> </head> <body> <?php //データベースに接続する $conn = mysql_connect("localhost", "root", "********"); mysql_select_db("test", $conn); //行をランダム順で取得する $sql = "SELECT * FROM ad ORDER BY RAND() LIMIT 0, 1"; $res = mysql_query($sql, $conn); $row = mysql_fetch_array($res, MYSQL_ASSOC); echo mb_convert_encoding($row["adtext"], "SJIS", "EUC-JP"); mysql_close($conn) ?> </body> </html>
Amazonからランダムに商品情報を取得する
ファイルからランダムに行を取得したいこともあります。ここで紹介する例(PHP5でのみ動作)は、Amazon Webサービスを利用してランダムに商品情報を取得する例です。
Amazon Webサービスから商品情報を取得する場合、商品コード(ISBNやASIN)や検索キーワードなどのパラメータをサーバーに送信します。情報を取得したい商品がいくつかある場合、サーバーに商品コードリストを保存しておき、スクリプトの実行時にランダムにコードを取得することで、表示する商品情報をランダムに切り替えることができます。
この場合、データベースに商品コードを格納しておいても良いのですが、さほど多くの商品を対象としないならテキストファイルでも要が足ります。次の例では、商品コードリスト「asin.txt」に格納された商品コードをランダムに取得して、Amazonから商品情報を取得しています。まず、「asin.txt」をfile関数で配列に読み込み、shuffle
関数で配列の要素をシャッフルします。これにより、処理対象の商品をスクリプト実行時に切り替えています。
ただし、配列から取得した商品コードには改行文字が含まれ、そのままAsinSearchRequest
メソッドの実行パラメータに使用すると上手くいかないことがあるので、rtrim
関数で改行を削除しておいた方が良いでしょう。また、パラメータとして使う配列$params
内の「tag
」や「devtag
」はご自分でお使いの値を設定してください。また、mb_convert_encoding
関数の文字コード指定もお使いの文字コードに合わせて変更してください。
<html> <head> <title>Amazonからランダムに商品情報を取得する</title> </head> <body> <?php //商品コードをランダムに取得 $data = file("asin.txt"); shuffle($data); $asin = rtrim($data[0]); //Amazon Webサービスに接続する $sc = new SOAPClient ("http://soap.amazon.co.jp/schemas3/AmazonWebServices.wsdl"); $params = array( "asin" => $asin, "tag" => "********", "devtag" => "********", "type" => "lite", "locale" => "jp" ); //AsinSearchRequestメソッドを実行して商品名を表示する $result = $sc->AsinSearchRequest($params); $productName = $result->Details[0]->ProductName; echo mb_convert_encoding($productName, "SJIS", "UTF-8"); ?> </body> </html>
まとめ
本稿では、コンテンツのランダム取得に関して次のようなポイントを説明しました。必要に応じて振り返ってください。
- 数値のランダム取得には
mt_rand
関数を使う shuffle
関数を使うと配列値がシャッフルされる- MySQLでは「
ORDER BY RAND()
」によって取得データがランダム化される file
関数とshuffle
関数でテキストファイルから任意の行を取得できる
参考資料
- 『PHP辞典』 西沢直木 著、翔泳社、2005年1月
- 『PHPによるWebアプリケーションスーパーサンプル』 西沢直木 著、ソフトバンクパブリッシング、2002年9月