UE4でLAMP(Nginx)にアカウントを作ってログインし、データを保存してGETする

UE4でサーバーにログインする場合、そのままではできないのでC++でノードを作ってHTTP/HTTPSで通信するんですが、フリーのプラグインでこれを実現するものがあったのでこれを使って実装してみる。

VaRestって言うプラグイン。標準では入ってないのでこちらからDLする。

DLはEpicのランチャーが起動し、これからDLしてインストールする。インストールし終わったらEnabledにチェックを入れてUE4を再起動ボタンを押す

説明(英語)を読むとC++で構築する必要はなく、これだけでHTTP/HTTPS通信ができるとのこと。

それではこれでHTTP/HTTPS通信のテストをしてみます。

まず、サーバー側に次のphpファイルを用意します。

<?php
$user = "user";
$pass = "pass";
//this script path
$script_php=$_SERVER['SCRIPT_NAME'];
if ($_SERVER["REQUEST_METHOD"]=="POST"){
    if ($_POST['user']==$user && $_POST['pass']==$pass){
        echo $user."で、パスワード".$pass."にてログインしました\n";
    }
}else{
//テーブルタグ
echo ("
    <form method=\"POST\" action=\" $script_php \">
    <table cellpadding=\"4\" cellspacing=\"1\" border=\"0\" width=\"800\"
        align=\"center\" bgcolor=\"#336666\">
        <tbody>
            <tr>
            <td height=\"100\" valign=\"middle\" align=\"center\" bgcolor=\"#ffffff\">
            USERを入力してください。<br><br>
            USER:<input type=\"text\" name=\"user\">
            <br><br>
            パスワード:<input type=\"password\" name=\"pass\">
            <br><input type=\"submit\" value=\"ログイン\">
            </td>
            </tr>
       </tbody>
    </table>
</form>
");
}

GETは簡単なので割愛します。まず、POSTが行われたらPOSTを検知してUSER名とパスワードを確認して正しければPOSTされたユーザー名とパスワードを出力します。
POSTされてないとフォームを出力しますがこれは動作確認用です。設置したらまずPCから動作確認しましょう。

post.phpという名前で設置しました。こんな感じで出力されます。

ではUE4側の処理です。Zキーを押すとPOSTされて出力をUE4で受け取る処理です。

まず、適当にProjectを作ってレベルBPで構築します。

こんな感じです。UE4.24.3+VaRestです。

解説

まず、VaRestプラグインをEnableにします。で、キーボードイベントでZキーイベントを置きます。で、ConstractJsonRequestを配置し、VerbをPOSTにして、ContentTypeをRequestBodyにしてRequestをサーバーに投げるようにします。

VaRestRequestJson型の変数を作ってそこにRequestを格納します。

OnRequestCompleteにイベントをバインドして変数からRequestObujectを取り出しアカウント情報をセットします。

最後にphpスクリプトにPOSTして呼びます。

Zキーを押すとサーバーにログインしてデータを受け取ります。

次はこれでログインしてアカウントの作成とアカウントがある場合はログインしてSQLからデータを得るものを作成しますね

Download CounterをWPプラグイン、PHP:Mysql、ファイル 形式で作成する[第六回]

第五回でほぼ全て実装しましたので今回はSql命令文を使って集計させます

おばけが付近にいるか検索するAndroidアプリ「JivaGooAR」
↑別サーバーにジャンプさせてカウントを取るサンプル

<html>
<head>
	<title>JivaGooAR</title>
	<meta http-equiv="content-type" content="text/html; charset=Shift_JIS">
	<script>
		location.href = "https://play.google.com/store/apps/details?id=jp.dip.wspri.jivagoo ";
	</script>
</head>
<body>
</body>

SAKURA(楽曲:mp3)
↑カウントテスト用(mp3ファイルをDL)

sql_counterのスクリプト圧縮ファイル
↑からmysqlDLカウンターPHPがDLできます。ダウンロード状況は以下で確認できます。:パスワードはwspri

DL状況

解説

ダウンロードされたファイルを集計して棒グラフで表示させるために以下のSql命令文を追加して実行させています
                        $count_files = "SELECT filename, COUNT( filename ) FROM $tb_name GROUP BY filename";
                        $count_files=$db->query($count_files);
                        $all="select count(id) from $tb_name";
                        $all=$db->query($all);
                        foreach($all as $all_row){$all = $all_row[0];}

SELECT filename, COUNT( filename ) FROM $tb_name GROUP BY filenameでダウンロードされたファイル名とそのカウント数を得ています。

select count(id) from $tb_nameは全体のカウントを得ています。で、実行結果はオブジェクトで返ってきますのでループでカウントを抜き出しています。オブジェクトなのでそのままでは使えません。
全体のカウントを得たらDLファイル毎のカウントを割って全体の割合を出してグラフに反映させています。このやり方ならDL数が大きくなってもはみ出るようなことはありませんね。

                        //ファイル毎の集計を表示で出力
                        //テーブルタグHEADER
                        echo ("
                            <table cellpadding=\"4\" cellspacing=\"1\" border=\"0\" width=\"800\"
                            align=\"center\" bgcolor=\"#336666\">
                            <tbody>
                            <tr id=\"count_f\" style=\"display:''\">
                            <td valign=\"middle\" align=\"center\" bgcolor=\"#2f4f4f\"><div style=\"font-size:10pt;color:#ffffff;\">ダウウンロードファイル名</div></td>
                            <td valign=\"middle\" align=\"center\" bgcolor=\"#2f4f4f\"><div style=\"font-size:10pt;color:#ffffff;\">DL数</div></td>
                            <td valign=\"middle\" align=\"center\" bgcolor=\"#2f4f4f\"><div style=\"font-size:10pt;color:#ffffff;\">グラフ(全体の割合)</div></td></tr>
                        ");
                        foreach($count_files as $count_row){
                            echo("
                            <tr id=\"count_f\" style=\"display:''\">
                            <td valign=\"middle\" align=\"left\" bgcolor=\"#ffffff\" width=\"200px\"><div style=\"font-size:10pt;\">".$count_row[0]."</div></td>
                            <td valign=\"middle\" align=\"left\" bgcolor=\"#ffffff\" width=\"50px\"><div style=\"font-size:10pt;\">".$count_row[1]."</div></td>
                            <td valign=\"middle\" align=\"left\" bgcolor=\"#ffffff\"><div style=\"background-color: blue; width: ".($count_row[1]/$all*100)."%; font-size: 10px;\">&nbsp;</div></td></tr>
                            ");
                        }
                        echo ("</tbody>
                        </table>");

で、出力ですが、集計結果は消す必要がないのでそのまま一番上に出力しています。ファイル数が何百とかになるならその下の処理同様にCSSで送ることができますね。こんなもんでどうですか。次は最終回、WPプラグイン化しますね。

Download CounterをWPプラグイン、PHP:Mysql、ファイル 形式で作成する[第五回]

では、第四回でSQLサーバに記録できるようになりましたので応用して記録して読み出すものを作成します。
今回は集計せずSQLデータベースにあるレコードを読み込んで一覧表示させます。

sql_counterのスクリプト圧縮ファイル

↑からmysqlDLカウンターPHPがDLできる。ダウンロード状況は以下で確認できます。:パスワードはwspri

DL状況

使い方は以前と同様に以下のようにタグを埋め込む。

<a href="http://plusload.dip.jp/sql_counter.php?fname=sql_counter.zip&dir=DL">sql_counterのスクリプト圧縮ファイル</a>

解説

mysqlなどのsqlサーバがインストールされていてユーザー名とパスワードが設定されていて、データベースの作成権限がある事が前提です。

sql_counter.zipがDownloadファイル名。
DLがディレクトリ名(省略するとカレントからファイルを検索します)

第四回にdlcount.phpみ実装したファイルのダウンロードと新たにレコードの読み込みを追加しただけです。

新たに追加したレコードの読み込み表示部

//Sql DataBase が存在するか確認する
try{
    //Sql connect
    $db = new PDO($host,$user,$pass);

    //view databases
    $sql = 'SHOW DATABASES';
    $results = $db->query($sql);

    //array loop
    while ($result = $results->fetch(PDO::FETCH_NUM)){
        //Does the database exist
        if($result[0]==$db_name){
            $exist=true;
        }
    }
    if($exist){
        $sql = 'use '.$db_name;
        if($db->query($sql)){
            $sql = "SELECT * FROM count_table";
            $sql=$db->query($sql);
            foreach($sql as $row){
                echo "<tr><td valign=\"middle\" align=\"center\" bgcolor=\"#ffffff\"><div style=\"font-size:10pt;\">".$row['id']."</div></td>
                      <td valign=\"middle\" align=\"center\" bgcolor=\"#ffffff\"><div style=\"font-size:10pt;\">".$row['ip']."</div></td>
                      <td valign=\"middle\" align=\"center\" bgcolor=\"#ffffff\"><div style=\"font-size:10pt;\">".$row['filename']."</div></td>
                      <td valign=\"middle\" align=\"center\" bgcolor=\"#ffffff\"><div style=\"font-size:10pt;\">".date("Y年m月d日 H時i分s秒",$row['dt'])."</div></td></tr>\n";
            }
        }
    }else{
        //テーブルタグ
        echo ("
                </tbody>
            </table>
            <table cellpadding=\"4\" cellspacing=\"1\" border=\"0\" width=\"800\"
                align=\"center\" bgcolor=\"#ff0000\">
            <tbody>
            <tr>
                <td height=\"100\" valign=\"middle\" align=\"center\" bgcolor=\"#ffffff\">
                    <div style=\"font-size:24pt;color:#ff0000;\">Sql DataBase が存在しません!</div>
                </td>
            </tr>
            </tbody>
            </table>
        ");


    }
    //connect close
    $db = null;
}catch(PDOException $e){
    echo "DB connect failure..." . PHP_EOL;
    echo $e->getMessage();
    exit;
}

sqlへの書き込み時にUNIXタイムスタンプを得てそのまま書き込むようにしましたので読み込み時に成型しています。

ダウンロードされた回数だけtrを一旦出力してCSSで表示数を制御する方法を実装しています。

//pageview
$pageview = 5;

$pageviewに設定した値で表示数が変わります。ここでは5に設定してますが、実際には20-50位が妥当かな。

if($exist){
    $sql = 'use '.$db_name;
    if($db->query($sql)){
        $sql = "SELECT * FROM count_table";
        $sql=$db->query($sql);
        $i=0;
        foreach($sql as $row){
            $rows[$i]="<tr id=".$i." style=\"display:none\"><td valign=\"middle\" align=\"center\" bgcolor=\"#ffffff\"><div style=\"font-size:10pt;\">".$row['id']."</div></td>
                <td valign=\"middle\" align=\"center\" bgcolor=\"#ffffff\"><div style=\"font-size:10pt;\">".$row['ip']."</div></td>
                <td valign=\"middle\" align=\"center\" bgcolor=\"#ffffff\"><div style=\"font-size:10pt;\">".$row['filename']."</div></td>
                <td valign=\"middle\" align=\"center\" bgcolor=\"#ffffff\"><div style=\"font-size:10pt;\">".date("Y年m月d日 H時i分s秒",$row['dt'])."</div></td></tr>\n";
             $i++;
        }
    }
    $page = $i / $pageview;
    if($page<1){
        foreach($rows as $table){
            echo $table;
        }
        echo ("<script>
            for(i=0;i<".$pageview.";i++){
                obj = document.getElementById(i);
                obj.style.display = (obj.style.display == 'none') ? '' : 'none';
            }
        </script>");
    }else{
        echo ("
            <script>
            var obj;
            var i=0;
            var ol=0;
            function first(ii){
                //表示したものは消しときます
                for(i=ol;i<ii;i++){
                    obj = document.getElementById(i);
                    obj.style.display = 'none';
                }

                //表示します
                for(i=ii;i<".$pageview."+ii;i++){
                    obj = document.getElementById(i);
                    obj.style.display = (obj.style.display == 'none') ? '' : 'none';
                }
                ol=ii;
            }

            </script>
            <center><p><button onclick=\"first(i);\">next</button>&nbsp;|&nbsp;<button onclick=\"first(0);\">reset</button></p></center>\n
        ");
        foreach($rows as $table){
             echo $table;
        }
        echo "<script>i=0;first(i);</script>";
    }
}

表示・非表示はCSSのdisplayで行っています。最初にすべてのtrタグの中身をdisplay=’none’にしておいてすべて出力して、$pageview数だけ”にしています。また、表示した$pageviewのtrは次の表示の前に’none’にしています。
まあ、CSSなので表示が早いのが特徴です。なんせすべて最初に出力してますから…

また、集計結果もみられるように次はしようかと思いますが、それはphp側の処理ですので次の第六回にしようと思います。

 

Download CounterをWPプラグイン、PHP:Mysql、ファイル 形式で作成する[第四回]

第三回で作った(改造した)DLカウンターをMySql(Sql)対応にしてみます。
DLしたIPとDLファイル名、時間を記録してPHPで集計表示します。

まずはPHPでMySqlに接続してDATABASE一覧を得ます。

<?php
$host = 'mysql:host=localhost';
$user = 'root';
$pass = 'yourpassword';

try{
    //Sql connect
    $db = new PDO($host,$user,$pass);

    //view databases
    $sql = 'SHOW DATABASES';
    $results = $db->query($sql);

    //$results array echos
    while ($result = $results->fetch(PDO::FETCH_NUM)){
        echo $result[0]."<br>";
    }

    //connect close
    $db = null;
}catch(PDOException $e){
    echo "DB connect failure..." . PHP_EOL;
    echo $e->getMessage();
    exit;
}

ちなみにMySqlがインストールされている事が前提です。
これでDB一覧が得られます。

次にこれの応用で一覧の中に設定したDBが既にあるか判定します。
これは一覧を得るところに指定のものがあったらフラグを立てるという仕様にします

    //array loop
    while ($result = $results->fetch(PDO::FETCH_NUM)){
        //Does the database exist
        if($result[0]==$db_name){
            $exist=true;
        }
    }

これで判定できました。
ではDBが見つかった場合は追記。なかった場合はDBを追加し、テーブルを作ります。
ただ、ここでポイントはINSERT文などに直接変数を入れて実行させることができないのでひと手間必要です。
次のコードを見てください。

    //main
    if($exist){
        $sql = 'use '.$db_name;
        if($db->query($sql)){
            $sql = 'INSERT INTO count_table (ip,filename,dt) VALUES (:ip,:file,:time)';
            $sql = $db->prepare($sql);
            $param = array(':ip'=>$get_ip,':file'=>$get_filename,':time'=>$get_timestamp);
            $sql->execute($param);	
        }else{
            echo "Donot use detabase....";
        }
    }else{
        //create database
        $sql = 'CREATE DATABASE '.$db_name;
        if($db->query($sql)){
            $sql = 'use '.$db_name;
                if($db->query($sql)){
                    $sql = 'create table '.$tb_name.' (id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,ip varchar(32),filename varchar(2048),dt int(10))';
                    if($db->query($sql)){
                        $sql = 'INSERT INTO count_table (ip,filename,dt) VALUES (:ip,:file,:time)';
                        $sql = $db->prepare($sql);
                        $param = array(':ip'=>$get_ip,':file'=>$get_filename,':time'=>$get_timestamp);
                        $sql->execute($param);
                    }else{
                        echo "Donot create table...";
                    }
                }else{
                    echo "Donot use detabase....";
                }
            }else{
                echo 'Donot create database....';
            }
        }

‘INSERT INTO count_table (ip,filename,dt) VALUES (:ip,:file,:time)’を見てください。
INSERT文を作っているのですが何か変ですよね?:ipって何だ?
これは変数を入れる位置を示した空の値をここでは代入してINSERT文を作ります。
で、array(‘:ip’=>$get_ip,’:file’=>$get_filename,’:time’=>$get_timestamp);で配列を作って後から変数を代入しないとダメなんです。
う~ん。難しい。

ここまでのコード

<?php
////////////////////////////////////////////////
//File DownLoad Counter
//(c)2020 WSPRI J.Amano
//
//https://wspri.dip.jp/
////////////////////////////////////////////////

//変更可能箇所//////////////////////////////////

//password
$pass = "wspri";
//LogoType
$logoType= "https://wspri.dip.jp/wordpress/wp-content/uploads/2020/05/rogo_l.jpg";
//database name
$db_name="dlcount_db";
//table name
$tb_name="count_table";
//sql info
$host = 'mysql:host=localhost';
$user = 'root';
$pass = 'yourpass';

//以下は変更しないでください////////////////////
$exist= false;
$get_ip=$_SERVER["REMOTE_ADDR"];
$get_filename="test";
$get_timestamp=time();
try{
    //Sql connect
    $db = new PDO($host,$user,$pass);

    //view databases
    $sql = 'SHOW DATABASES';
    $results = $db->query($sql);

    //array loop
    while ($result = $results->fetch(PDO::FETCH_NUM)){
        //Does the database exist
        if($result[0]==$db_name){
            $exist=true;
        }
    }
    //main
    if($exist){
        $sql = 'use '.$db_name;
        if($db->query($sql)){
            $sql = 'INSERT INTO count_table (ip,filename,dt) VALUES (:ip,:file,:time)';
            $sql = $db->prepare($sql);
            $param = array(':ip'=>$get_ip,':file'=>$get_filename,':time'=>$get_timestamp);
            $sql->execute($param);
        }else{
            echo "Donot use detabase....";
        }
    }else{
        //create database
        $sql = 'CREATE DATABASE '.$db_name;
        if($db->query($sql)){
            $sql = 'use '.$db_name;
            if($db->query($sql)){
                $sql = 'create table '.$tb_name.' (id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,ip varchar(32),filename varchar(2048),dt int(10))';
                if($db->query($sql)){
                    $sql = 'INSERT INTO count_table (ip,filename,dt) VALUES (:ip,:file,:time)';
                    $sql = $db->prepare($sql);
                    $param = array(':ip'=>$get_ip,':file'=>$get_filename,':time'=>$get_timestamp);
                    $sql->execute($param);
                }else{
                    echo "Donot create table...";
                }
            }else{
                echo "Donot use detabase....";
            }
        }else{
            echo 'Donot create database....';
        }
    }

    //connect close
    $db = null;
}catch(PDOException $e){
    echo "DB connect failure..." . PHP_EOL;
    echo $e->getMessage();
    exit;
}

Download CounterをWPプラグイン、PHP:Mysql、ファイル 形式で作成する[第三回]

まずはMySqlを使わないWPプラグインではないPHPのDLカウンターの巻

これは以前WSPRIで配布していたPHPサンプルをちょっと改造。
以外に良くできてた( ´艸`)

dlcountのスクリプト圧縮ファイル

↑からDLカウンターPHPがDLできる。ダウンロード状況は以下で確認できます。:パスワードはwspri

DL状況

使い方は以下のようにタグを埋め込む。

<a href="http://plusload.dip.jp/dlcount.php?fname=dlcount.zip&dir=./">dlcountのスクリプト圧縮ファイル</a>

解説:
http://plusload.dip.jp/dlcount.php
はdlcounter.phpまでのパスを指定。
fname=dlcount.zip
はDLさせるファイル名
※*.htmlもしくは*.htmも指定できます。その場合アクセスカウンタとしても使う事ができますよ。
dir=./
はDLさせるファイルが格納されているdlcount.phpから見たディレクトリ名を指定
この場合はカレントにあるので指定しなくてもしてもOK
※実際にDLされるのはDLディレクトリ内にあるdlcount2.zipです。

で、DL数を見るには

<a href="http://plusload.dip.jp/dlcount.php>DL状況</a>

にアクセスするとパスワードを求めるので入力すると見られる。

次回はこれをMySqlに書き込む仕様に変更するよ。

Download CounterをWPプラグイン、PHP:Mysql、ファイル 形式で作成する[第二回]

ダウンロードカウンターで検索してこられる人が結構いるので今回は①WPプラグイン形式、②PHPスクリプトでMysql形式で記録閲覧、③PHPスクリプトでファイルで記録閲覧という3つのダウンロードカウンターを作ってみることにする

【実装】

まず、Anonymous(匿名)でのダウンロードとアカウント(登録制)を切り替えられるようにするため、WPの認証機能を使います。※いらねーかな

require_once('./wp-load.php');

これを書くとWPのユーザーが今誰かを見ることができるようになります。_oneceなので一回だけって意味です。

あとは

/*オブジェクトを生成*/
new dlcounter;

というオブジェクトを作成して

/*dlcounterクラスを定義*/
class dlcounter {
    /*コンストラクタだから一回だけ:UE4Blueprintの場合はEventBiginPlay*/
    function __construct() {
        /*wordpressから自身のMySQLへ接続するインスタンスを呼ぶ*/
        global $wpdb;
        add_action('admin_menu', array($this, 'add_admin'));//管理者メニューに追加する準備
    }
 
    /*管理メニューの設定*/
    function add_admin() {
        if(substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2)=="ja"){
            $menuname="DLカウンター";
        }else{
            $menuname="DLCounter;
        }
        //level_8から10が管理者
        add_menu_page($nenuname,$menuname,'level_9', __FILE__, array($this,'dl_counter'));
    }

として以降に

function dl_counter(){

}

を書きます

Download CounterをWPプラグイン、PHP:Mysql、ファイル 形式で作成する[第一回]

ダウンロードカウンターで検索してこられる人が結構いるので今回は①WPプラグイン形式、②PHPスクリプトでMysql形式で記録閲覧、③PHPスクリプトでファイルで記録閲覧という3つのダウンロードカウンターを作ってみることにする

【設計】

①WPプラグイン形式で作成する

まずはワードプレスのPluginで作成してみる事にする

    • ダウンロードリンクにプラグインを指定することでIPとタイムスタンプを記録する
    • Anonymous(匿名)でのダウンロードとアカウント(登録制)を切り替えられる
    • 申請はアカウント登録のない場合は申請可能にする
    • メール登録型で申請メールに認証URLが送られ認証するとアカウントが承認される

※認証はいらねーかな。

といったチョット商用可能な感じのものにします。
WPプラグイン、PHPスクリプトも同じ仕様にします。

【ヘッダ】

<?php
/*
Plugin Name: WSPRI Download Counter
Plugin URI: https://wspri.dip.jp
Description: ダウンロードカウンタープラグイン
Author: j.amano
Version: 1.0
Author URI:https://wspri.dip.jp
*/
//user control
require_once('./wp-load.php');

WPのMySqlデータベースを読み込み表示CSVでダウンロードするWPプラグインを登録申請しました

WPプラグインの申請にはreadme.txtを作成してzipに同梱する必要があります。

また、プラグインを使える管理者のチェックとサニタイズが必須みたいです。なのでこれらを修正して再びレビューに出しました。

=== Plugin Name ===
Contributors: (this should be a list of wordpress.org userid's)
Donate link: http://example.com/
Tags: comments, spam
Requires at least: 3.0.1
Tested up to: 3.4
Requires PHP: 5.2.4
Stable tag: 4.3
License: GPLv2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html

Here is a short description of the plugin. This should be no more than 150 characters. No markup here.

Plugin Name:プラグインの名前をここに記入します。

Contributors:作者のニックネームを記入します

Donate link:寄付の先をURLで記載します

Tags:検索用のタグなのかな?

Requires at least:バージョンナンバーを記入します(1.0とか)

Tested up to:テストしたWPのバージョンを記入します

Requires PHP:phpのバージョンを記載します

License:ライセンスのバージョンを記載します

License URI:ライセンスのURLを記載します

Here is a short description of the plugin. This should be no more than 150 characters. No markup here.

以降にプラグインの詳細を記載します。

== Description ==

プラグインの説明

= Main function =

特徴

= Premium Add-ons =

これ以上の情報がどこにあるか

= Translation =

言語対応状況

== Installation ==

インストールの方法

全て英語で記載します。終わったらzipに圧縮して次のページを読んでレビュー申請します。

ワードプレスプラグイン開発者ページ

申請したらレビューコメントが戻ってくるまで待ちましょう。

【exsample:readme.txt】

===Select table and column and output in CSV===
Contributors:powcyan
Donate link:https://wspri.dip.jp
Tags:Analysis, Database, CSV
Requires at least:4.9.8
Tested up to:4.9.8
Stable tag:1.0

== Description ==
Plugin that selects columns from all wordpress. 
* Databases, displays their contents, and outputs them in CSV format.

= Main function =
* Read and display all WordPress databases and their columns, and output them as CSV

= Premium Add-ons =
For a list of available extensions, see [Web site] (https://wspri.dip.jp).

= Translation =
This plug-in will display Japanese if the browser is set to Japanese, and will display English if it is any other language.

== Installation ==
1. In WordPress Administrator, select Plugins> Add New.
2. Search Select table and column and output in CSV.
3. Click ** Install Now ** under Select table and column and output in CSV to activate the plug-in.
Select table and column and output in CSV

【コード全般】

<?php
/*
Plugin Name: Select table and column and output in CSV.
Plugin URI: https://wspri.dip.jp/?p=194
Description: 全てのwordpress.*データベースからカラムを選択して、その内容を表示し、CSV出力するプラグイン:Plugin that selects columns from all wordpress. * Databases, displays their contents, and outputs them in CSV format.
Author: jack.Amano
Version: 1.0
Author URI:https://wspri.dip.jp
*/

//Create object
new showtables;

//Create CLASS
class showtables{
    //Constrructer
    function__construct(){
        add_action('admin_menu', array($this, 'add_admin'));//Preparing to Add to the Administrator Menu
    }
    //Add menu fanction
    functionadd_admin(){
        //Are using Japanese or another language?
        if(substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2)=="ja"){
            $menuname="DB一覧表示";
        }else{
            $menuname="DB list display";
        }
        //level_8-10 is Admin
        add_menu_page($nenuname,$menuname,'level_9', __FILE__, array($this,'show_DB'));
    }
    //View table and column.And selected table and column.Output CSV
    function show_DB(){
        //Post table and column array
        if(isset($_POST['table_name']) && isset($_POST['colum_name'])){
            //Are using Japanese or another language?
            if(substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2)=="ja"){
                $massage02="テーブルのカラムが送信されないとカラムの内容を読み込めません。ここに表示されているテーブル名のカラムか確認してから[Read Table & Columns]ボタンを押してください。";
                $selecter200="最新の200レコード";
                $selecter500="最新の500レコード";
                $selecter1000="最新の1000レコード";
                $selecterall="全てのレコード";
            }else{
                $massage02="If the table column is not sent, the contents of the column can not be read. Confirm that the table name column is displayed here, and then click the [Read Table & Columns] button.";
                $selecter200="200row from the latest";
                $selecter500="500row from the latest";
                $selecter1000="1000row from the latest";
                $selecterall="All";
            }
            //Get table_name
            $table_mono=sanitize_text_field($_POST['table_name']);
            //Get column array
            $colum_array=$_POST['colum_name'];
            echo<<<FORM
            <h1>Show WordPress Table & Columns</h1>
            {$massage02}
            <hr width="98%">
            <form method="post" action="" >
            <input type="checkbox" name="createCSV" value="DL">DownloadCSV | row count:<select name="CSVrow">
            <option value="200">{$selecter200}</option>
            <option value="500">{$selecter500}</option>
            <option value="1000">{$selecter1000}</option>
            <option value="all">{$selecterall}</option>
            </select>
            <h2>TABLE NAME:<input type="text" name="post_tablename" value="{$table_mono}" style='font-size:20px;font-weight:900;'></h2>
FORM;
            for ($i=0;$i<count($colum_array);$i++){
                //This is column No
                $c=$i+1;
                //sanitaize
                $columns=sanitize_text_field($colum_array[$i]);
                //Echo text form
                echo"<h4>&raquo; COLUMN{$c}:<input type='text' name='post_columname[]' value='{$columns}'></h4>";
            }
            echo<<<FORM
            <input type="submit" value="Read Table & Columns">
            </form>
FORM;

            //$this->readDB();//will be able to reselected
            //If the POSTed data of selected table names and columns.
        }else if(isset($_POST['post_tablename']) && isset($_POST['post_columname'])){
            //Are using Japanese or another language?
            if(substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2)=="ja"){
                $errormsg1="POSTしたTABLEのカラムは存在していません!";
                $errormsg2="不正なテーブル情報がPOSTされています。";
                $massage03="POSTしたTABLEのカラムの内容を表示しています。";
            }else{
                $errormsg1="The column of TABLE that has been posted does not exist!";
                $errormsg2="Incorrect table information has been POSTed.";
                $massage03="Displays the contents of the posted TABLE column.";
            }
            //Get table name
            $get_table=sanitize_text_field($_POST['post_tablename']);
            //Get column array
            $get_columns=$_POST['post_columname'];
            //When there are multiple arrays
            if(count($get_columns)>1){
                $get_column=implode(",",$_POST['post_columname']);//Separate the array with "," to make it a string
            }else{//If the array is one
                $get_column=$get_columns[0];
            }
            //sanitaize
            $get_column=sanitize_text_field($get_column);
            //SELECT a column from the table
            global$wpdb;//Call WP instance and login
            $reading=$wpdb->get_results("SELECT$get_columnFROM$get_table");
            $matchtitle=$wpdb->get_results("SELECTguid,post_title FROM wp_posts");
            //Failed to SELECT
            if(!$reading){
                echo<<<TABLE
                <h1>SQL COMMAND : SELECT {$get_column} FROM {$get_table}</h1>
                <h2 style="color:red;">{$errormsg1}</h2>
                <hr width='98%'>
                {$errormsg2}
TABLE;
            }else{//Success to SELECT
                /*Create if there is no csv primary storage directory*/
                $directory_path = "./tmp";//directory name is tmp
                if(!file_exists($directory_path)){
                    /*Processing when there is not exist: If there is not, create with 0777*/
                    mkdir($directory_path, 0777);
                /*Processing when there is a tmp directory*/
                }else{
                    /*Search *.csv if there is a tmp directory, it's array: If not, it will be an empty array*/
                    $csv = glob('*.csv');
                    /*Processing when array is not empty*/
                    if(empty($csv)){
                        /*Look inside wp-admin / tmp and read all files with * .csv extension*/
                        foreach(glob('tmp/{*csv}',GLOB_BRACE) as $file){
                            /*Process if $file is a file*/
                            if(is_file($file)){
                                /*Process if Unix timestamp of file is older than the current time*/
                                if(filemtime($file) < time()){
                                    /*delete*/
                                    unlink($file);
                                }
                            }
                        }
                    }
                }
                echo<<<TABLE
                <h1>SQL COMMAND : SELECT {$get_column} FROM {$get_table}</h1>
                {$massage03}
                <hr width='98%'>
                <table border='1' cellpadding='5' bordercolor='#ffffff' width='98%'>
                <tr>
TABLE;
                //export CSV 1at session
                $columnamearray=[];
                //Here is the name of the column
                for($r=0;$r<count($get_columns);$r++){
                    //If do not convert variables to characters, can not use them.
                    $name=strval($get_columns[$r]);
                    echo"<td width='10%' bgcolor='#EEcccc'>".$name."</td>";
                    //export CSV 1st session
                    $columnamearray[$r]=$name;//push colum name
                }
                echo"</tr>";
                //export CSV 2nd session
                $rowarray[-1]=$columnamearray;//push row onece. Why is it [-1]? Because the count starts with [0].
                //echo use
                $rowarray2=[];
                $columdataarray=[];
                //Because it is OBUJECT, first, it repeats by the number of array of $reading.
                for($i=0;$i<count($reading);$i++){
                    //echo "<tr>";
                    //Next, repeat the number of columns and extract the columns
                    for($c=0;$c<count($get_columns);$c++){
                        //If do not convert variables to characters, can not use them.
                        $name=strval($get_columns[$c]);//to string
                        $data=$reading[$i]->$name;
                        if($name=='dt'||$name=='dt_out'){
                             $data=date('Y/m/d H:i:s', $data);//convert unixtimestamp
                        }
                        if($name=='resource'){
                            /*Repeat by $matchtitle array*/
                            for($b = 0 ; $b < count($matchtitle) ; $b++){
                                /*if $matchtitle[$b]->guid is $data*/
                                if(strpos($matchtitle[$b]->guid,$data) !== false){
                                    /*"/"is top pagge*/
                                    if($matchtitle[$b]->guid=='/'){
                                        $data = 'TopPage';
                                    }else{
                                        /*$matchtitle[$b]->post_title is $data,$post_title is $data*/
                                        $data = $matchtitle[$b]->post_title;
                                    }
                                /*no $data*/
                                }
                            }
                        }
                      //echo "<td width='10%' bgcolor='#eeeeee'>".$data."</td>";
                      $columdataarray[$c]=$data;
                    }
                    //echo "</tr>";
                    $rowarray[$i]=$columdataarray;
                    //echo use
                    $rowarray2[$i]=$columdataarray;
                }
                //echo "</table>";
                $i=0;
                $ii=0;
                if(isset($_POST['CSVrow']) && $_POST['CSVrow']=="all"){
                    $counts=count($rowarray);
                }else{
                    $counts=intval(sanitize_text_field($_POST['CSVrow']));
                    rsort($rowarray);//from the latest
                    rsort($rowarray2);//from the latest
                }
                //echo count($rowarray)."<br>";
                foreach ($rowarray2 as $fields2) {
                    if($ii>=$counts){
                        break;
                    }
                    echo"<tr>";
                    foreach ($fields2 as $values2) {
                        echo"<td width='10%' bgcolor='#eeeeee'>".$values2."</td>";
                    }
                    $ii++;
                    echo"</tr>";
                }
                if(isset($_POST['createCSV']) && $_POST['createCSV']=="DL"){
                    /*Create CSV */
                    mb_convert_encoding($rowarray,"SJIS", "UTF-8");
                    //var_dump($rowarray);
                    $csvFileName = 'tmp/tablecolumdata_'.time().'.csv';//CSV file path
                    $fp = fopen($csvFileName, 'w');
                    if(!$fp){
                        print_r('CSV output failed');
                    }
                    foreach ($rowarray as $fields) {
                        if($i>=$counts){
                            break;
                        }
                        /*Put to csv file*/
                        fputcsv($fp, $fields);
                        $i++;
                    }
                    /*Closed: Be careful, because if you forget to close it, you won't be able to proceed.*/
                    fclose($fp);
                    /*Make a path of server*/
                    $server_path = (empty($_SERVER["HTTPS"]) ? "http://" : "https://").$_SERVER["HTTP_HOST"]."/wp-admin/" ;
                    /*Download*/
                    print_r("<META HTTP-EQUIV='Refresh' CONTENT='0;URL=".$server_path.$csvFileName."'>");
                    /*Create CSV */
                }
                echo"</table>";
            }
        }else{
            //Confirming administrator access
            if(current_user_can('administrator')){
                $this->readDB();//Call private fubction
            }else{
                echo <<<NONADMIN
                <script type="text/javascript">aleat("You are no admin!");</script>
NONADMIN;
            }
        }
    }
    privatefunctionreadDB(){
        //Are using Japanese or another language?
        if(substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2)=="ja"){
            $massage01="テーブル選択のラジオボタンをオンにして、そのテーブルのカラムを選択します。確認できたら[Set Form]ボタンを押してください。<br>テーブルまたはカラム名だけ送信することはできません。ラジオボタンがオフになっているテーブルのカラムを送信するとエラーになります。";
        }else{
            $massage01="Select the table selection radio button and select the columns for that table. After confirmation, please press the [Set Form] button. <br>You can not send only table or column names. It is an error to send a table column where the radio button is off.";
        }
        global$wpdb;//Call WP instance and login
        $tables=$wpdb->get_results("SHOW TABLES FROM wordpress ");
        echo<<<TITLE
        <h1>Show WordPress All Tables</h1>
        {$massage01}
        <hr width="98%">
        <form method="post" name="form1" action="" >
TITLE;
        for ($i=0;$i<count($tables);$i++){//Disassemble array while counting up
            $tablename[$i]=$tables[$i]->Tables_in_wordpress;
            echo<<<ORITATAMI
            <div onclick="obj=document.getElementById('menu{$i}').style; obj.display=(obj.display=='none')?'block':'none';">
            <h2><input type="radio" name="table_name" value="{$tablename[$i]}">{$tablename[$i]}</h2>
            </div>
            <div id="menu{$i}" style="display:none;clear:both;">
ORITATAMI;
            $colum_search = $wpdb->get_results("SHOW COLUMNS FROM $tablename[$i] ");
            for($c=0;$c<count($colum_search);$c++){
                echo<<<ORITATAMI
                <div>
                <h3>
                &raquo; <input type="checkbox" name="colum_name[]" value="{$colum_search[$c]->Field}">{$colum_search[$c]->Field}</h3></div>
ORITATAMI;
            }
            echo"</div>";
        }
        echo"<input type='submit' value='Set Form'></form>";
    }
}

サニタイズ(POSTされたデータからタグやその他のhtmlやscriptタグを取り除く作業)処理とadminしか使えないように修正しました。配列はそのままではサニタイズできないので分解した時にサニタイズしています。

 //Get table_name
 $table_mono=sanitize_text_field($_POST['table_name']);

↑POSTしたテーブル名をサニタイズしてる

 //Get column
 array $colum_array=$_POST['colum_name'];
(中略)
 //sanitaize
 $columns=sanitize_text_field($colum_array[$i]); 

↑POSTしたカラムの配列はそのまま受け取り、使う前にサニタイズしてる

 //Confirming administrator access
 if(current_user_can('administrator')){
     $this->readDB();//Call private fubction
 }else{
     echo <<<NONADMIN
     <script type="text/javascript">aleat("You are no admin!");</script> 
NONADMIN;
 }

↑管理者かどうか判別し、管理者だったら関数を呼んでいる

 

こちらからインストールできます。

【改造解説】

まず、表示、生成するCSVのレコード数を変える場合の改造点

 //Are using Japanese or another language?
if(substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2)=="ja"){
    $massage02="テーブルのカラムが送信されないとカラムの内容を読み込めません。ここに表示されているテーブル名のカラムか確認してから[Read Table & Columns]ボタンを押してください。";
    $selecter200="最新の200レコード";
    $selecter500="最新の500レコード";
    $selecter1000="最新の1000レコード";
    $selecterall="全てのレコード";
}else{
    $massage02="If the table column is not sent, the contents of the column can not be read. Confirm that the table name column is displayed here, and then click the [Read Table & Columns] button.";
    $selecter200="200row from the latest";
    $selecter500="500row from the latest";
    $selecter1000="1000row from the latest";
    $selecterall="All";
}
(中略)
<input type="checkbox" name="createCSV" value="DL">DownloadCSV | row count:<select name="CSVrow">
<option value="200">{$selecter200}</option>
<option value="500">{$selecter500}</option>
<option value="1000">{$selecter1000}</option>
<option value="all">{$selecterall}</option>
</select>

この中のoption value=”200″を表示または出力したいCSVのレコード数に変えます。セレクターにしてますがPOSTする数値を受け取っていますのでinput type=textにして数値を入力してもOKです。allの時は逆順でソートしません

各国語対応拡張改造点

//Are using Japanese or another language?
if(substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2)=="ja"){
    $menuname="DB一覧表示";
}else{
    $menuname="DB list display";
}
こんな判定が4箇所出てきますのでelseの所をelse if(substr($_SERVER[‘HTTP_ACCEPT_LANGUAGE’], 0, 2)==”cn”)にすると中国語を判定しますのでこの中に中国語訳を記載します。

サーバーの設定でカレントが”/”でない場合の改造点
カレントの設定は”/”で作っています。なのでカレントが“wordpress”などの場合はパスが通らずエラーになります。そんな時は以下の箇所(240行)の/wp-admin//wordpresss/wp-admin/に変更してください。httpかhttpsかは判断しています。
/*Make a path of server*/
$server_path = (empty($_SERVER["HTTPS"]) ? "http://" : "https://").$_SERVER["HTTP_HOST"]."/wp-admin/" ;
作られたCSVファイルをサーバーに全て残しておく場合の改造点
/*Create if there is no csv primary storage directory*/
$directory_path = "./tmp";//directory name is tmp
if(!file_exists($directory_path)){
    /*Processing when there is not exist: If there is not, create with 0777*/
    mkdir($directory_path, 0777);
    /*Processing when there is a tmp directory*/
}else{
    /*Search *.csv if there is a tmp directory, it's array: If not, it will be an empty array*/
    //$csv = glob('*.csv');
    /*Processing when array is not empty*/
    //if(empty($csv)){
        /*Look inside wp-admin / tmp and read all files with * .csv extension*/
        //foreach(glob('tmp/{*csv}',GLOB_BRACE) as $file){
            /*Process if $file is a file*/
            //if(is_file($file)){
                /*Process if Unix timestamp of file is older than the current time*/
                //if(filemtime($file) < time()){
                    /*delete*/
                    //unlink($file);
                //}
            //}
        //}
    //}
}
一時保管用CSVは新しいCSVファイルが作られると古いCSVファイルを削除するように作られています。なので↑のように121行目136行目をコメントアウトすると削除されなくなります。

という感じですか。

WordPressプラグインを作ってみる:第五回

【第五回WordPressの機能を追加するものにプラグインがありますが今回はこのプラグインの作り方を解説します。

第四回ではテーブル名とカラム名配列をサーバーに送って受け取る処理の解説をしましたが、今回は受け取ったテーブル名とカラム名配列で実際にデーターベースにアクセスして読み込んでみようかと思います。

【必要な事項】

①テーブル名とカラム名配列を受け取ったらデーターベースにSELECT命令を出す

②テーブルにカラム名が存在していたら読み込んで表示

③テーブルにカラム名が存在していない場合はエラー

以上になるかと思います。

        //POSTされたデータが選ばれたテーブル名とカラムの配列だったら
        }else if(isset($_POST['post_tablename']) && isset($_POST['post_columname'])){

            //で、テーブル名をゲットしとく
            $get_table=$_POST['post_tablename'];

            //まず、post_columnameの配列分の変数を作っておく
            $get_columns=$_POST['post_columname'];

            //配列が複数だった場合
            if(count($get_columns)>1){
                $get_column=implode(",",$_POST['post_columname']);//配列を,で区切って文字列にする
            }else{//配列が一つだった場合
                $get_column=$get_columns[0];
            }

            //じゃ、テーブルからカラムをSELECTする
            global $wpdb;//インスタンスを呼んでログイン
            $reading=$wpdb->get_results("SELECT $get_column FROM $get_table");

            if(!$reading){
                echo <<<TABLE
                <h1>SQL COMMAND : SELECT {$get_column} FROM {$get_table}</h1>
                <h2 style="color:red;">POSTしたTABLEのカラムは存在していません!</h2>
                <hr width='98%'>
                不正なテーブル情報がPOSTされています。
TABLE;
            }else{
                echo <<<TABLE
                <h1>SQL COMMAND : SELECT {$get_column} FROM {$get_table}</h1>
                POSTしたTABLEのカラムの内容を表示しています。
                <hr width='98%'>
                <table  border='1' cellpadding='5' bordercolor='#ffffff' width='98%'>
                <tr>
TABLE;

                //こっちはカラムの名前を表示
                for($r=0;$r<count($get_columns);$r++){
                    //変数を文字に変換しとかないとダメなもよう
                    $name=strval($get_columns[$r]);
                    echo "<td width='10%' bgcolor='#EEcccc'>".$name."</td>";
                }
                echo "</tr>";
                //OBUJECTなのでまず、$readingの配列数だけ繰り返す
                for($i=0;$i<count($reading);$i++){
                    echo "<tr>";
                    //次にカラム数だけ繰り返してカラムを抜き出す
                    for($c=0;$c<count($get_columns);$c++){
                        //変数を文字に変換しとかないとダメなもよう
                        $name=strval($get_columns[$c]);
                        echo "<td width='10%' bgcolor='#eeeeee'>".$reading[$i]->$name."</td>";
                    }
                    echo "</tr>";
                }
                echo "</table>";
            }

POSTされたカラム名が2つ以上の場合は配列を,で区切って文字に変換しています。1つしかない場合は最初の配列を入れています。また、カラムの変数は文字に変換しないとそのままではOBUJECTから抜き出せませんので注意です。

これでSELECT {$get_column} FROM {$get_table}のSQLコマンドを送信できます。$reading=$wpdb->get_results(“SELECT $get_column FROM $get_table”);してみましょう。

ちゃんと読み込めましたね。これでデータベースの内容を把握することができるようになりました。データベースの中身を覗いてみましょう。

【コード全般】

<?php
/*
Plugin Name: Show WordPress DataBase
Plugin URI: https://wspri.dip.jp/?p=155
Description: wordpress.*データベースを読んで一覧を表示するプラグイン
Author: jack.Amano
Version: 0.0
Author URI:https://wspri.dip.jp
*/

//オブジェクトを作成
new showtables;

//クラスを作る
class showtables{
    //コンストラクタ
    function __construct(){
        add_action('admin_menu', array($this, 'add_admin'));//管理者メニューに追加する準備
    }
    //メニューを追加する関数
    function add_admin(){
        if(substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2)=="ja"){
            $menuname="DB一覧表示";
        }else{
            $menuname="DB list display";
        }
        //level_8から10が管理者
        add_menu_page($nenuname,$menuname,'level_9', __FILE__, array($this,'show_DB'));
    }

    //DBを表示する関数
    function show_DB(){
        //non post
        if(isset($_POST['table_name']) && isset($_POST['colum_name'])){
            if(substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2)=="ja"){
                $massage02="テーブルのカラムが送信されないとカラムの内容を読み込めません。ここに表示されているテーブル名のカラムか確認してから[Read Table & Columns]ボタンを押してください。";
            }else{
                $massage02="If the table column is not sent, the contents of the column can not be read. Confirm that the table name column is displayed here, and then click the [Read Table & Columns] button.";
            }
            $table_mono=$_POST['table_name'];
            $colum_array=$_POST['colum_name'];
            echo <<<FORM
            <h1>Show WordPress Table & Columns</h1>
            {$massage02}
            <hr width="98%">
            <form method="post" action="" >
            <h2>TABLE NAME:<input type="text" name="post_tablename" value="{$table_mono}" style='font-size:20px;font-weight:900;'></h2>
FORM;

            for ($i=0;$i<count($colum_array);$i++){
                $c=$i+1;
                echo "<h4>&raquo; COLUMN{$c}:<input type='text' name='post_columname[]' value='{$colum_array[$i]}'></h4>";
            }
            echo <<<FORM
            <input type="submit" value="Read Table & Columns">
            </form>
FORM;
            $this->readDB();//選びなおせるようにしますね
        //POSTされたデータが選ばれたテーブル名とカラムの配列だったら
        }else if(isset($_POST['post_tablename']) && isset($_POST['post_columname'])){
            if(substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2)=="ja"){
                $errormsg1="POSTしたTABLEのカラムは存在していません!";
                $errormsg2="不正なテーブル情報がPOSTされています。";
                $massage03="POSTしたTABLEのカラムの内容を表示しています。";
            }else{
                $errormsg1="The column of TABLE that has been posted does not exist!";
                $errormsg2="Incorrect table information has been POSTed.";
                $massage03="Displays the contents of the posted TABLE column.";
            }
            //で、テーブル名をゲットしとく
            $get_table=$_POST['post_tablename'];
            //まず、post_columnameの配列分の変数を作っておく
            $get_columns=$_POST['post_columname'];
            //配列が複数だった場合
            if(count($get_columns)>1){
                $get_column=implode(",",$_POST['post_columname']);//配列を,で区切って文字列にする
            }else{//配列が一つだった場合
                $get_column=$get_columns[0];
            }
            //じゃ、テーブルからカラムをSELECTする
            global $wpdb;//インスタンスを呼んでログイン
            $reading=$wpdb->get_results("SELECT $get_column FROM $get_table");
            if(!$reading){
                echo <<<TABLE
                <h1>SQL COMMAND : SELECT {$get_column} FROM {$get_table}</h1>
                <h2 style="color:red;">{$errormsg1}</h2>
                <hr width='98%'>
                {$errormsg2}
TABLE;
            }else{
                echo <<<TABLE
                <h1>SQL COMMAND : SELECT {$get_column} FROM {$get_table}</h1>
                {$massage03}
                <hr width='98%'>
                <table  border='1' cellpadding='5' bordercolor='#ffffff' width='98%'>
                <tr>
TABLE;
                //こっちはカラムの名前を表示
                for($r=0;$r<count($get_columns);$r++){
                    //変数を文字に変換しとかないとダメなもよう
                    $name=strval($get_columns[$r]);
                    echo "<td width='10%' bgcolor='#EEcccc'>".$name."</td>";
                }
                echo "</tr>";
                //OBUJECTなのでまず、$readingの配列数だけ繰り返す
                for($i=0;$i<count($reading);$i++){
                    echo "<tr>";
                    //次にカラム数だけ繰り返してカラムを抜き出す
                    for($c=0;$c<count($get_columns);$c++){
                        //変数を文字に変換しとかないとダメなもよう
                        $name=strval($get_columns[$c]);
                        echo "<td width='10%' bgcolor='#eeeeee'>".$reading[$i]->$name."</td>";
                    }
                    echo "</tr>";
                }
                echo "</table>";
            }
        }else{
            $this->readDB();//このクラス内の関数を呼びます
        }
    }
    private function readDB(){
        if(substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2)=="ja"){
            $massage01="テーブル選択のラジオボタンをオンにして、そのテーブルのカラムを選択します。確認できたら[Set Form]ボタンを押してください。<br>テーブルまたはカラム名だけ送信することはできません。ラジオボタンがオフになっているテーブルのカラムを送信するとエラーになります。";
        }else{
            $massage01="Select the table selection radio button and select the columns for that table. After confirmation, please press the [Set Form] button. <br>You can not send only table or column names. It is an error to send a table column where the radio button is off.";
        }
        global $wpdb;//インスタンスを呼んでログイン
        $tables=$wpdb->get_results("SHOW TABLES FROM wordpress ");
        echo <<<TITLE
        <h1>Show WordPress All Tables</h1>
        {$massage01}
        <hr width="98%">
        <form method="post" name="form1" action="" >
TITLE;
        for ($i=0;$i<count($tables);$i++){//カウントアップしながら配列を分解
            $tablename[$i]=$tables[$i]->Tables_in_wordpress;
            echo <<<ORITATAMI
            <div onclick="obj=document.getElementById('menu{$i}').style; obj.display=(obj.display=='none')?'block':'none';">
            <h2><input type="radio" name="table_name" value="{$tablename[$i]}">{$tablename[$i]}</h2>
            </div>
            <div id="menu{$i}" style="display:none;clear:both;">
ORITATAMI;
            $colum_search = $wpdb->get_results("SHOW COLUMNS FROM $tablename[$i] ");
            for($c=0;$c<count($colum_search);$c++){
                echo <<<ORITATAMI
                <div>
                <h3>
                &raquo; <input type="checkbox" name="colum_name[]" value="{$colum_search[$c]->Field}">{$colum_search[$c]->Field}</h3></div>
ORITATAMI;
            }
            echo "</div>";
        }
        echo "<input type='submit' value='Set Form'></form>";
    }
}

 

こんな感じです。日本語環境でない場合は英語になります。このプラグインは更にCSV出力機能などを付けてWordPressプラグインとして配布しますので(そのうち)使ってみてくださいね。

このプラグインを使ってみる。(日本語設定でない場合は英語表示)

ダウンロードしたzipファイルをプラグインページからインストールして有効化するとあなたのwordpressのMysqlデータベース一覧が見え、カラムの内容が所得できます。

 

WordPressプラグインを作ってみる:第三回

【第三回】WordPressの機能を追加するものにプラグインがありますが今回はこのプラグインの作り方を解説します。

第二回ではテーブルを指定してカラムを読み込むショートコードを解説しましたが、第一回でプラグインに実装したテーブルを全て読み込むコードにカラムを読み込む実装をしようかと思います。

【まず実装コード】

<?php
/*
Plugin Name: Show WordPress DataBase
Plugin URI: https://wspri.dip.jp/?p=155
Description: wordpress.*データベースを読んで一覧を表示するプラグイン
Author: jack.Amano
Version: 0.0
Author URI:https://wspri.dip.jp
*/

//オブジェクトを作成
new showtables;

//クラスを作る
class showtables{
    //コンストラクタ
    function __construct(){
        global $wpdb;//インスタンスを呼んでログイン
        $this->tables=$wpdb->get_results("SHOW TABLES FROM wordpress ");//テーブルを呼び出して$thisの中に格納しとく
        add_action('admin_menu', array($this, 'add_admin'));//管理者メニューに追加する準備
    }
    //メニューを追加する関数
    function add_admin(){
        //level_8から10が管理者
        add_menu_page('DB一覧表示','DB一覧表示','level_9', __FILE__, array($this,'show_DB'));
    }
    //DBを表示する関数
    function show_DB(){
        $tables=$this->tables;//$thisからテーブルを取り出しておく
        global $wpdb;//インスタンスを呼んで再びログイン
        echo <<<TITLE
        <h1>Show WordPress All Table<h1>
        <hr width="98%">
        <ol>
TITLE;
        for ($i=0;$i<count($tables);$i++){//カウントアップしながら配列を分解
            $tablename=$tables[$i]->Tables_in_wordpress;
            echo <<<ORITATAMI
            <div onclick="obj=document.getElementById('menu{$i}').style; obj.display=(obj.display=='none')?'block':'none';">
            <h5><li type="1"><a style="cursor:pointer;">{$tablename}</a></li></h5>
            </div>
            <div id="menu{$i}" style="display:none;clear:both;">
            <ol>
ORITATAMI;
            $colum_search = $wpdb->get_results("SHOW COLUMNS FROM $tablename ");
            for($c=0;$c<count($colum_search);$c++){
                echo "<div><h6><li type='circle'>".$colum_search[$c]->Field."</li></h6></div>";
            }
            echo "</ol></div>";
        }
        echo "</ol>";
    }
}

↑という感じで実装しました。

↑こんな感じに見えます。テーブルの中身(カラム)は折りたたんでいるのでテーブル名をクリックするとカラム一覧が表示されます。

【解説】

そのまま表示すると膨大な行数になっちゃうのでテーブル名に折りたたみました。なのでテーブル名をクリックするとそのテーブルのカラム一覧が表示されます。また、コンストラクタでインスタンスを呼ばなくても関数の中でどうせ呼ぶんだからいいかと思いますがここでは修正しませんでした。( ̄∀ ̄)

    for ($i=0;$i<count($tables);$i++){//カウントアップしながら配列を分解
        $tablename=$tables[$i]->Tables_in_wordpress;
        echo <<<ORITATAMI
        <div onclick="obj=document.getElementById('menu{$i}').style; obj.display=(obj.display=='none')?'block':'none';">
        <h5><li type="1"><a style="cursor:pointer;">{$tablename}</a></li></h5>
        </div>
        <div id="menu{$i}" style="display:none;clear:both;">
        <ol>
ORITATAMI;
        $colum_search = $wpdb->get_results("SHOW COLUMNS FROM $tablename ");//テーブルのloop中にカラムのオブジェクトを受け取る
            for($c=0;$c<count($colum_search);$c++){//テーブルのカラムの分ループして書き出す
                echo "<div><h6><li type='circle'>".$colum_search[$c]->Field."</li></h6></div>";
            }
            echo "</ol></div>";
    }
    echo "</ol>";
}

↑折りたたみ部位。CSSの折りたたみを使っています。

まず、テーブル名をループしながら分解して書き出しています。またその際にカラムのオブジェクトも受け取って分解して書き出しています。

すごい簡単でしたね。これでテーブル一覧とそのカラム一覧が受け取れました。あとは応用するといろんな事ができます。まあ、プラグインでphpMyAdminみたいなこともできますね。(工数かかるけど…)

当然ですがカラム名をクリックすると値が見れるという実装も出来ますよ。またそれをCSVに書き出すってのも出来ます。(//∇//)

取りあえずこのプラグインをインストールして動作を見てみる

リンクをクリックするとこのプラグインをダウンロードできます。ダウンロードしたら[プラグイン]>[新規追加]>[プラグインのアップロード]>showDB.zipを選択>[今すぐインストール]でインストールできますのでインストールしたら[有効にする]にしてください。

左メニューにDB一覧表示があるはずです。動かしてみましょう。