fbpx

メニュー

wpdb道場 (10) 〜ユーザーのダミーデータを大量に用意しよう〜

高橋文樹 高橋文樹

この投稿は 9年半 前に公開されました。いまではもう無効になった内容を含んでいるかもしれないことをご了承ください。

さて、いままでは「フォローする/される」というUIを1人のユーザーの視点から作ってみました。

ですが、注意しなくてはいけない点として、2, 3人をフォローして、それを前提にしながらしょぼいUI作って「よし……」と自信満々にリリースしてしまうことですね。僕もよくありますが。

せっかくなので、UIを設計するまえにユーザーをたくさん登録して、相互にフォローしあったりしあわなかったりする状況を作りましょう。要するに、テスト用データを用意するんですね。

データの入手と加工

ユーザーを作るんで、実際に人間っぽいデータを入手しましょう。幸い、こうしたWebサービスが存在します。疑似個人情報データ生成サービスです。ドメインかっこいいですね。

こちらで「生成を開始」をクリックしたら、CSVを取得しましょう。下のスクリーンショットのように、ローマ字と「姓と名を別項目として出力」をオンにしたら、生成開始です。

ローマ字はユーザーログインに変換するために必要
ローマ字はユーザーログインに変換するために必要

インポートプラグインの入手

ではこのデータをインポートするのですが、プラグインを探しましょう。そうすると、Import Users From CSVというそのまんまのプラグインが見つかりました。インストール&有効化。

有効化後、メニューはどこやねんと探してみると、「ツール」配下ではなく、「ユーザー」配下にあります。さっそくこのページにアクセス!

エラー。XDebugを有効にしてると詳しくエラーが出ますよ。
エラー。XDebugを有効にしてると詳しくエラーが出ますよ。

すごいエラーだ! といっても、Strictエラー(上書きしたメソッドの引数リストが親クラスのメソッドと一致してない等)が大半なので、WordPressプラグインスタンダードとしてはよくあること。僕もよくやります。

とはいえ、このままでは動かないので、wp-config.phpに以下のデバッグ設定記載。エラーを画面に出力せず、エラーログ(wp-content/debug.log)に書き込みます。

/**
 * 開発者へ: WordPress デバッグモード
 *
 * この値を true にすると、開発中に注意 (notice) を表示します。
 * テーマおよびプラグインの開発者には、その開発環境においてこの WP_DEBUG を使用することを強く推奨します。
 */
define('WP_DEBUG', true);
define("WP_DEBUG_LOG", true);
define('WP_DEBUG_DISPLAY', false);

個人的には画面にエラーが出ている方が嬉しいので、後で戻すのを忘れないようにしましょう。

データの加工

それでは、さっそくインポート……と思いましたが、ダミーデータがこのインポートプラグインの求めるCSVの形式になるよう変換しないといけないですね。CSVのサンプルはインポート画面にありました。

Import User From CSVのサンプルはこの画面に
Import User From CSVのサンプルはこの画面に

そのためのスクリプトをPHPで書きましたのが、以下になります。既存のCSVを別の名前にして保存しているだけです。一応、Excelで内容を確認できるように、Shift_JISに文字コードを変換したバージョンも作ります。

<?php
// 元CSV
$orig_handle = fopen('./personal_infomation_orig.csv', 'r');
// 新ファイル名
$new_file = './personal_information_ready.csv';
// すでにあったら消す
if( file_exists($new_file) ){
     unlink($new_file);
}
// 新しいファイポインタを作成
$new_handle = fopen($new_file, 'w');
// ヘッダ書き込み
fputcsv($new_handle, array(
     'user_login',
     'user_email',
     'user_pass',
     'display_name',
     'nickname',
     'first_name',
     'last_name',
     'tel',
     'sex',
     'role',
));
// 各行を処理
$line_count = 0;
while( false !== ($line = fgetcsv($orig_handle)) ){
     if( $line_count ){
          fputcsv($new_handle, array(
               strtolower($line[5].'_'.$line[6]),
               $line[9],
               'tweeterjp',
               $line[1].' '.$line[2],
               $line[3].' '.$line[4],
               $line[2],
               $line[1],
               $line[8],
               '男' == $line[7] ? '1' : '0',
               'subscriber',
          ));
          echo '+';
     }
     $line_count++;
}
fclose($orig_handle);
fclose($new_handle);
// Excelでの確認用にShift_JIS版を作成
$output = file_get_contents($new_file);
file_put_contents('./personal_information_sjis.csv',
     mb_convert_encoding($output, 'sjis-win', 'utf-8'));
exit;

元のCSVにないものとして、パスワード(全員同じtweeterjp)と、権限(全員購読者 subscriber)があるので、それを追加。今回やってませんが、user_metaにimported_as=dammyとしておくと、あとで一括削除できるようになって便利ですね。

これをコマンドラインから実行します。CSVを保存したディレクトリに、converter.phpとして上記のコードを保存。その後、ターミナルから実行。

cd path/to/directory
php converter.php

面倒くさい人はこのリンクからダウンロードできるので、それを使ってください。が、開発においてデータの収集や用意というのは避けて通れないので、やったことない人は実際に手を動かしましょう。

それでは、いざ、インポート。

インポートされたユーザー
インポートされたユーザー

僕の環境(Nginx)だとTimeoutエラーで止まっちゃいました……。Apacheならおそらくですが、止まらずに全部入るんじゃないでしょうか。僕の場合は1,000人分入りました。まあ、これぐらい用意すれば十分でしょう。

ユーザー同士をフォローさせる

それでは、続いて、お互いをめちゃくちゃにフォローさせてみましょう。なるべく偏りがでるようにします。こんな感じにするとリアルなんじゃないでしょうか。

  • 10%はだれもフォローしていない(初心者)
  • 80%は5%から30%のユーザーをフォローしている(普通)
  • 10%は全体の90%以上をフォローしている(キチガイヘビーユーザー)

もっとも、これはフォローする側の視点でしかないので、実際のtwitterでは「たくさんフォローされているが、自分からはフォローしていない」という状況のアルファツイッタラー(浜崎あゆみなど)がいますね。これは今回考えないことにします。

WP-CLIの導入

では、そのためのコマンドを用意しましょう。せっかくなので、いまはやりのWP-CLIを使います。WP-CLIにはコミュニティコマンドという機能があって、プラグイン独自のコマンドを作成できます。

今回の用途は「登録したユーザー全員を一定のルールでフォローさせる」という、あまり汎用性のないものなのですが、せっかくなので作ってみましょう。

やることは簡単で、以下の2つ。

  1. WP_CLI_Commandを継承したクラスを作る
  2. WP-CLIが有効なときだけクラスをコマンドとして登録する

今回は名前空間を定義しているので、Freundschaft\Commands\Followというクラスを作成します。

<?php

namespace Freundschaft\Commands;
use Freundschaft\Models\Followers;

/**
 * Make user follow
 *
 * @package Freundschaft\Commands
 */
class Follow extends \WP_CLI_Command
{

     /**
      * Make random follow-relationships of each users
      *
      * ## OPTIONS
      *
      * This command has no option.
      *
      * ## EXAMPLES
      *
      *     wp follow
      *
      * @synopsis
      */
     public function __invoke( $args, $assoc_args ) {
          // モデルを取得。コードヒントが出るようにDOCも書く
          /** @var Followers $followers */
          $followers = Followers::getInstance();
          // コマンド開始
          \WP_CLI::line('すべてのユーザーを取得します.....');
          // WP_User_Queryだと制限があるので、直接クエリを発行。
          $query = <<<SQL
               SELECT ID FROM {$followers->db->users}
               ORDER BY RAND()
SQL;
          // get_colでuser_idの配列を取得
          $user_ids = $followers->get_col($query);
          // 総人数
          $total = count($user_ids);
          \WP_CLI::line(sprintf('%d人のユーザーを取得しました', $total));
          // まずは誰もフォローしない初心者ユーザーの人数(先頭の10%)
          $new_bee = floor($total / 10);
          // フォローしまくっている異常なユーザー(最後の10%)
          $crazy = count($user_ids) - $new_bee;
          // すべてのユーザーに対して処理
          foreach( $user_ids as $index => $user_id ){
               $followed = 0;
               if( $index < $new_bee ){
                    // 初心者(誰もフォローしない)
               }else{
                    if( $index >= $crazy ){
                         // キチガイ(90%以上をフォロー)
                         $amount = $total / 100 * rand(90, 100);
                    }else{
                         // 普通の人(5%〜30%をフォロー)
                         $amount = $total / 100 * rand(5, 30);
                    }
                    // ユーザーIDのインデックスをランダムにする
                    $keys = array_keys($user_ids);
                    shuffle($keys);
                    \WP_CLI::line('------------');
                    foreach( $keys as $key ){
                         $user_to_follow = $user_ids[$key];
                         if( $user_to_follow == $user_id ){
                              // 自分だったらスキップ
                              continue;
                         }
                         // フォローする
                         $followers->follow($user_id, $user_to_follow);
                         $followed++;
                         \WP_CLI::out('.');
                         // 規定数に達したらループ脱出
                         if( $followed >= $amount ){
                              break;
                         }
                    }
                    \WP_CLI::line('');
               }
               \WP_CLI::line(sprintf("ID:%d\tfollows\t%d", $user_id, $followed));
          }
          \WP_CLI::success('処理を完了しました');
     }

}

コミュニティコマンド用のクラスはコメントの書き方にルールがあって(参照: Commands Cookbook)、ちゃんと書いておかないと wp help follow とかやったときに説明が出ません。ちゃんと書きましょう。

で、WP-CLIが有効な時だけこのクラスを読み込みます。freundschaft.phpに書いてください。

/**
 * プラグイン読み込み完了後に実行
 */
add_action('plugins_loaded', function(){
     // Ajaxコントローラーを初期化
     Freundschaft\API\Ajax\Follow::getInstance();
     // WP-CLIのコマンドを登録
     if( defined('WP_CLI') && WP_CLI ){
          WP_CLI::add_command('follow', 'Freundschaft\\Commands\\Follow');
     }
});

さっそく実行してみましょう。WordPressのルートディレクトリに移動して、 wp help follow と入力します。そうすると、先ほど書いた説明が出てきます。

WP−CLIのAPIを使うと簡単にヘルプが作れる
WP−CLIのAPIを使うと簡単にヘルプが作れる

それでは、さっそく実行。ターミナルからwp followと実行してください。ズラーッと文字が出てきます。僕はこういうバルク処理のとき、なんとなく寂しくてピリオドなどを出力してしまうのですが、みなさんはどうでしょう。

コマンドの実行結果
コマンドの実行結果

これでデータベースを見てみると、大量にデータが登録されていますね。よかったよかった。

僕の場合は50,000件ぐらい登録
僕の場合は50,000件ぐらい登録 

まとめ

  • 開発にあたってデータを大量に用意してみた
  • WP-CLIのコマンドを書いてみた

以上です。それでは、次回からいよいよ自分のフォロワーを確認してみましょう! 「なかなかすすまねーな」と思ったそこのあなた! 開発なんてそんなもんですよ。

[429] [429] Client error: `POST https://webservices.amazon.co.jp/paapi5/getitems` resulted in a `429 Too Many Requests` response: {"__type":"com.amazon.paapi5#TooManyRequestsException","Errors":[{"Code":"TooManyRequests","Message":"The request was de (truncated...)

すべての投稿を見る

高橋文樹ニュースレター

高橋文樹が最近の活動報告、サイトでパブリックにできない情報などをお伝えするメーリングリストです。 滅多に送りませんので、ぜひご登録お願いいたします。 お得なダウンロードコンテンツなども計画中です。