1

私は個人的なプロジェクトに取り組んでいます-phpを使用してMySQLからデータをフェッチし、それをJSON形式(列を含む)にエンコードしてから、視覚化のためにAjaxを介してGoogleデータテーブルにロードします。

プロジェクトはうまくいきましたが、php で純粋な文字列操作によって JSON エンコーディングを行いました。ほんの一部の SQL と php 関数を使用して、チャート用の複数のデータ ソースを作成します。

これが必要だと感じた理由は、1 つの悪い理由と 2 つの本当の理由です。

  • 私はJavascriptがかなり新しいです
  • JSON_ENCODE (php 関数) は、日付値に必要な間違ったフォーマットを生成するように見えました。
    • 日付(および日時)を「2013-01-01 01:00:00」として出力します
    • Google のドキュメントでは、「Date(2013,1,1,0,0,0)」が必要なようでした。
  • また、JSON_Encode は、必要な列の出力を生成しませんでした (MySQL の結果データ型に基づくデータ型の割り当てを含む)。

質問:

JSON の日付形式と列出力 (結果に基づくデータ型を含む) に関連して、純粋な文字列操作よりもはるかに簡単にこれらを解決できたでしょうか?

以下に自分のコードを掲載しました。何らかの理由で私が実際に何か良いことをした場合、コミュニティはそれを使用することを歓迎します.

これは 3 つの php ファイルです (ただし、最後のファイルはおそらく html である必要があります)。最初のファイルは、2 ページ目で使用されるカスタム関数で満たされています。

2 番目の php ファイルは、My_SQL (echo DATA;) からのデータを JSON/GoogleChart 形式でダンプします。

最後のファイル/ページでは、ajax を使用して 2 ページ目からデータを取得し、注釈付きのタイムラインに挿入します。Jquery のセットアップは 3 ページ目、MySQL 接続は 1 ページ目、SQL は 2 ページ目にあります。

<?php
// First Page/File: mysql_gc_functions.php
function mysql_loadresult($sql, $type){

// $sql - a string containing SQL to run against database
// $type - 0 for standard array load, 1 for JSON formatted string

$debug = false;

$result = mysql_query($sql) or die(mysql_error());
$numfields = mysql_num_fields($result);
$numrows = mysql_num_rows($result);
$br = '</br>';

$arr; // Array to Load Data Into where first index will contain headers
      // Where x is the column and y is the row
      // Row '0' contains Header Names

$datatypes; // Array to Load in Data Types

// Standard Array Loading

// Load Field Names
for ($x=0; $x < $numfields; $x++){
    $arr[$x][0] = mysql_field_name($result,$x);
    $datatypes[$x] = mysql_field_type($result,$x);
    if($debug == true){echo 'data type for ' . $arr[$x][0] . ': ' . $datatypes[$x] . '</br>';}
}

$y = 0; // Row Index
while ($data = mysql_fetch_array($result, MYSQL_NUM)) {// For Each Row
    $y++;
    for ($x=0; $x<$numfields; $x++){ // For Each Field
        $arr[$x][$y] = $data[$x]; // Load Query into php array
    }
}

// JSON formatted string
if ($type == 1) {
    /* JSON Format Example
    {
      "cols": [
            {"label":"Topping","type":"string"},
            {"label":"Slices","type":"number"}
          ],
      "rows": [
            {"c":[{"v":"Mushrooms"},{"v":3},
            {"c":[{"v":"Onions"},{"v":1}]},
            {"c":[{"v":"Olives"},{"v":1}]},
            {"c":[{"v":"Zucchini"},{"v":1}]},
            {"c":[{"v":"Pepperoni"},{"v":2}]}
          ]
    }

    mysql data type / google field type / Json value example:

        date:               date:           "Date(2012,12,1)"
        datetime:           datetime:       "Date(2012,12,1,23,59,59)"  <- Y,M,D,H,M,S - can do milliseconds as well (but not built)
        number:             int/real:       123456
        everything else:    string:         "EXAMPLE TEXT"

    */      
    $sColJason = '{"cols":[';
    $eColJason = '],';
    $ColExprS = '{"label":"';
    $ColExprE = '","type":"XXX"}';
    $colbuild = '';

    // Build Column Structure for JSON
    for ($x=0;$x<$numfields;$x++){

        if ($datatypes[$x] == 'date'){
            $tvar = str_replace('XXX', 'date', $ColExprE);
        } else if ($datatypes[$x] == 'int' OR $datatypes[$x] == 'real'){
            $tvar = str_replace('XXX','number',$ColExprE);
        } else if ($datatypes[$x] == 'datetime'){
            $tvar = str_replace('XXX','datetime',$ColExprE);
        } else {
            $tvar = str_replace('XXX','string',$ColExprE);
        }

        $str = $ColExprS . $arr[$x][0] . $tvar;
        if ($x != ($numfields - 1)){
            $str = $str . ",";
        }
        $colbuild = $colbuild . $str;
    }

    if($debug == true){echo $sColJason . $colbuild . $eColJason . '</br>';}

    $sRowJason = '"rows": [';
    $eRowJason = ']}';
    $RowExpr = '{"v":"XXX"}';
    $RowStart = '{"c":[';
    $RowEnd = ']}';
    $RowBuild = '';

    // Build Row Structure for JSON
    for ($y = 1; $y<$numrows;$y++){
        // build each column of row (field of record)
        $RowFieldBuild = '';
        for ($x=0;$x<$numfields;$x++){  
            $var = $arr[$x][$y];

            // assess how the data type needs to be treated
            if ($datatypes[$x] == 'date'){
                $var = mysql_googledate($var);
            } else if ($datatypes[$x] == 'int' OR $datatypes[$x] == 'real'){
                $var = $var;
            } else if ($datatypes[$x] == 'datetime') {
                $var = mysql_googleDtTm($var);
            } else {
                $var = '"' . $var . '"';
            }

            // concatenate the row string with populated values
            $RowFieldBuild = $RowFieldBuild . str_replace('"XXX"',$var,$RowExpr);
            if ($x != ($numfields-1)){
                $RowFieldBuild = $RowFieldBuild . ',';
            }
        }
        // Encapsulate the Record
        $RowBuild = $RowBuild . $RowStart . $RowFieldBuild . $RowEnd;
        if($y != ($numrows-1)){
            $RowBuild = $RowBuild . ',';
        }
    }
    // Encapsulate Entire Row Data
    $RowBuild = $sRowJason . $RowBuild . $eRowJason;
    if($debug == true){echo $RowBuild . '</br>';}

    return ($sColJason . $colbuild . $eColJason . $RowBuild);

} else { // Return Standard Array of Table Data
    return $arr;
}
}

function mysql_googledate($var){
$arr = preg_split("/-/",$var);
$month = intval($arr[1]);
$newStr = '"Date(' . $arr[0] . ',' . $month . ',' . $arr[2] . ')"';
return $newStr;
}
function mysql_googleDtTm($var){
$arr = preg_split("/-/",$var);
$tmArr = preg_split("/:/",$arr[2]);
$cm = ',';

$yr = intval($arr[0]);
$mon = intval($arr[1]);
$day = intval(substr($arr[2],0,2));

$hr = intval(substr($tmArr[0],-2));
$min = intval($tmArr[1]);
$sec = intval($tmArr[2]);

$newStr = '"Date(' . $yr . $cm . $mon . $cm . $day . $cm . $hr . $cm . $min . $cm . $sec . ')"';
return $newStr;
}

function mysql_localcon(){
$con = mysql_connect("localhost","root","1234");
if (!$con)  {
    die('Could not connect: ' . mysql_error());
}
return $con;
}

?>

<?php
// Second Page/File: data_ATL.php
Include('mysql_gc_functions.php');
  $sql = 'SELECT DATE_FIELD, VALUE_FIELD FROM DATABASE.TABLE';
  $con=mysql_localcon();
  $dataJason = mysql_loadresult($sql, 1);
  echo $dataJason;
?>

// THIS IS THE FINAL (3rd) OUTPUT FILE/PAGE - DISPLAYS ANNOTATED TIME LINE
<html>  
<head>   
<script type='text/javascript' src='http://www.google.com/jsapi'></script>
<script type="text/javascript" src="jquery.js"></script>  
<script type='text/javascript'>    
    google.load('visualization', '1', {'packages':['annotatedtimeline']});  
    google.setOnLoadCallback(drawChart);   
    function drawChart() {
        var jsonData = $.ajax({
            url: "data_ATL.php",
            dataType:"json",
            async: false
            }).responseText;

        var data = new google.visualization.DataTable(jsonData);    
        var chart = new google.visualization.AnnotatedTimeLine(document.getElementById('chart_div'));    
        chart.draw(data, 
            {
                displayAnnotations: true,
                annotationsWidth: 20,
                scaleType: 'maximized'      
            }
        );
    }
</script>  
</head>
<body>  
<div id='chart_div' style='width: 700px; height: 240px;'></div> 
</body>
</html>
4

1 に答える 1

1

私は最近、これとまったく同じタスクを実行し、MySQL クエリによって返されたデータに基づいて Google データ テーブルを生成する関数を作成することができました。json_encode()のみを使用して JSON ペイロードを構築します。特定の文字列操作はありません。mysql の代わりに mysqli を使用したため、以下のいくつかは mysql と若干異なる場合があることに注意してください。

あまり目立たない側面を次に示します。

  • Google DataTable 列の「タイプ」を決定するために、 mysqli_fetch_fields() (http://php.net/manual/en/mysqli-result.fetch-fields.php)によって返される配列の「タイプ」値を使用しました。. 次に、この mysqli タイプを Google の DataTable API の同等のものに一致させる小さな関数を作成しました。たとえば、mysqli_fetch_fields() が以下を返した場合:

    [0] => stdClass Object
    (
        [name] => Date
        [orgname] => date
        [table] => c
        [orgtable] => users
        [def] => 
        [db] => main
        [catalog] => def
        [max_length] => 10
        [length] => 10
        [charsetnr] => 63
        [flags] => 20617
        [type] => 10
        [decimals] => 0
    )
    

    MYSQLI_TYPE_DATEに対応するtype値が 10 であることがわかります。タイプの定数の完全なリストは、http: //php.net/manual/en/mysqli.constants.phpにあります。

  • JSONはJavascript Dateオブジェクトをサポートしていないため、日付型にはいくつかの操作が必要でした(しかし、GoogleのAPIはあなたが指摘したように「Date(Y、m、d、[h、i、s])」をサポートしています。注意すべきことの1つは、Javascript Date オブジェクトは月 0 から始まるため、MySQL 日付の月パラメーターは 1 減らす必要があります。日付を抽出するために、次のように使用しました。

    $mysql_date = explode("-", $row[$i]);
    $mysql_date[1] = $mysql_date[1] - 1;
    if ($mysql_date[1] < 0) $mysql_date[1] = 11;
    $mysql_date = implode(",", $mysql_date);
    $value = "Date(" . $mysql_date . ")";
    array_push($c, array("v" => $value));
    

    preg_splitは問題なく動作しますが、速度が遅いことに注意してください (これは、非常に大きなデータ セットがある場合にのみ問題になります)。詳細はこちら: http://micro-optimization.com/explode-vs-preg_split

  • これまでのところ、文字列操作は日付の処理のみで、それ以外はすべて PHP 配列に格納されています。すべてのデータが収集されたら、json_encode() を呼び出すことができます。これに関する問題は、Google テーブルの「数値」として定義された列の場合、json_encode() が二重引用符で囲まれた数値を返す傾向があることです。数値を強制的にそのように扱うために、単純な正規表現を使用しました:

    $json = json_encode($j);
    $json = preg_replace('/"(-?\d+\.?\d*)"/', '$1', $json);
    

お役に立てれば!

于 2013-01-25T10:56:22.350 に答える