[PHP] たくさんのキーワードからn個(n行)をランダムに選択する(抽出する)

Webサービス作っていると、いくつかのアイテムから n個をランダムに選択したいときがあります。たとえば、人気のキーワードは日に数千あるけれど、上位10個を表示するだけだとランキング上位のキーワードが確固たる地位を築いてしまうだけで、おもしろくなかったりします。そんなときは上位1000個から10個のキーワードをランダムに選択して表示するようにすると、ユーザーもちょっとおもしろい気づきが得られたりするかもしれません。

たとえば、キーワードとその検索頻度を1行に並べた(csv形式やtsv形式)1,000キーワード(1,000行)からなるファイルが入力としてあるとしましょう。PHPで作るなら、

<?
// number of output lines
$max=intval($argv[1]);

// open standard input
$h=fopen('php://stdin','r');
if (!$h) { die('stdin open error'); }

// put all lines into an array
$lines=array();
while(!feof($h)) {
  $lines[]=fgets($h);
}

fclose($h);

// shuffle the array of lines
shuffle($lines);

// output selected lines
for($i=0;$i<$max;$i++) {
  echo $lines[$i];
}
?>

のようなコードで、標準入力から読み込んだキーワードから、指定した n個をランダムに選択(抽出)することができます。たとえば、これを extract_n_randomly.php として保存し、

% php -q extract_n_randomly.php 10 < keywords.tsv

とすれば、実行するたびに異なる 10個 のキーワードを得ることができます。

ポイントは shuffle() ( cf. PHP: shuffle - Manual ) で、配列をランダムに並べ替えてくれます。

[apache] 複数ドメインで同じディレクトリを参照させるには

SeverAlias を使えばいいんですね。参考: ServerAlias Directive @apache.org

たとえば name based virtual host 設定していて、example.com と www.example.com および w.example.com で /var/www/example.com を参照させたい場合、

<VirtualHost *:80>
    ServerName example.com
    ServerAlias www.example.com w.example.com
    DocumentRoot /var/www/example.com
    ....
</VirtualHost>

のように設定すれば、設定が1カ所で済むわけですね。

さらに、RewriteRule を設定しておくと、すべてを example.com に集約したりすることができますね。

 RewriteCond %{HTTP_HOST} .*\.example\.com
 RewriteRule ^(.*)$ http://example.com/$1 [R=301]