質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.12%

PHPで画面遷移が遅い

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,429

Kobi0927i

score 4

PHP+JAVASCRIPTでプログラムを書いていますが
画面の遷移が遅くて困っています。

テキストボックスに入力した値を、JAVASCRIPTで拾い
JAVASCRIPTからPHPでデータベースに書き込む処理をしていますが

上記の画面で何もしないで、別の画面に遷移させると
問題なく直ちに遷移しますが

上記の画面でテキストボックスに値を入れ
画面を遷移させると、1分ぐらいしてから
画面が遷移されています。
裏で動いているJAVASCRIPTに問題があるか
分かりませんが、ご教授お願いします。

ちなみに開発環境では、遅延は無く
本番環境(XSERVER)のみ発生しております。

追記
サーバー環境
OS
本番:CentOS Linux release 7.3.1611 (Core)
開発:CentOS Linux release 7.3.1611 (Core)

PHP
本番:PHP Version 7.0.18
開発:PHP Version 7.1.8

MySql
本番:mysql Ver 15.1 Distrib 5.5.52-MariaDB, for Linux (x86_64) using readline 5.1
開発:mysql Ver 14.14 Distrib 5.7.19, for Linux (x86_64) using EditLine wrapper

プログラム(抜粋)

プログラムは3本の構成となっておりまして
inq_phpは、データベースで検索した結果を表示して、
画面からの入力を行います。
入力された時に、inp.jsが呼び出され
inp.jsから、upd.phpを呼び出し
データベースの更新を行います。

1.inq.php
<header>
<script src="./inp.js"></script>
</header>
<body>
<input type="number" onchange="isRegNum(this)"  id=<?php echo htmlspecialchars($row['id']); ?> 
name=<?php echo htmlspecialchars("pages|".$i); ?>      
style ="background-color: #77c1e8;text-align:right;width:60px;"
type="textbox" value="<?php echo htmlspecialchars($row['pages'] ,ENT_QUOTES,'UTF-8'); ?>">
</input> 
</body>

2.inp.js
function isRegNum(obj){

var obj_value=obj.value;    /* 入力値 */
var obj_name=obj.name;      /* 更新カラム名 */
var obj_id=obj.id;          /* DB側の更新行番号 */

result = obj_name.indexOf( "|" );
obj_names = obj_name.substr(0,result);           /* DB側の更新カラム名*/
table_rows=Number(obj_name.substr(result+1));    /* 画面側の更新行番号*/

console.log(obj_value);
console.log(obj_names);
console.log(obj_id);

// 入力値のチェック
// 0から9 又は .(46)
// 

var obj_value = obj_value.replace( /,/g ,"" ) ; /* カンマが入力されていたら抜き取る*/
if (obj_names !="spec") {
for(var i=0 ; i<obj_value.length; i++){
var code=obj_value.charCodeAt(i);
if ((48>code || code>57) ){
if (code != 46) {
/* 数値(0-9)と (.)以外の文字コード範囲 */
swal({
title: "エラー",
text: "半角数字とピリオド以外の文字が入力されています。"
});

//
obj.value="";
return false;
}
}
}
}

$.ajax({
type : "POST",
url:"upd.php",
datatype:"json",
data: {
arg1:obj_value,
arg2:obj_names,
arg3:obj_id
},
}) .done(function(data){

/* 計算値をカンマ付きにさせる。 */
var tables = document.getElementById("cost_tbl");
var shipping_fee_blk = Number(data[0]['shipping_fee_blk']);
var price1 = Number(data[0]['price1']);
var price2 = Number(data[0]['price2']);
var price3 = Number(data[0]['price3']);
var price4 = Number(data[0]['price4']);
var price5 = Number(data[0]['price5']);

/* 計算値を表示させる。 */
tables.rows[table_rows].cells[12].innerText=String(shipping_fee_blk).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,');
tables.rows[table_rows].cells[16].innerText=String(price1).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,');
tables.rows[table_rows].cells[17].innerText=String(price2).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,');
tables.rows[table_rows].cells[18].innerText=String(price3).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,');
tables.rows[table_rows].cells[19].innerText=String(price4).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,');
tables.rows[table_rows].cells[20].innerText=String(price4).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,');

/* 
入力された値にもカンマを付けて再表示させる。 
注意:ここは
*/
var values = String(obj_value).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,');

switch (obj_names){
case "exchange":
tables.rows[table_rows].cells[9].value=values;
break;
case "ratio":
tables.rows[table_rows].cells[10].value=values;
break;
case "carriage":
tables.rows[table_rows].cells[11].value=values;
break;
case "rate":
tables.rows[table_rows].cells[13].value=values;
break;
case "lic_fee":
tables.rows[table_rows].cells[14].value=values;
break;
case "adjust":
tables.rows[table_rows].cells[15].value=values;
break;
case "retail_price":
tables.rows[table_rows].cells[21].value=values;
break;
}

})
.fail(function(jqXHR, textStatus, errorThrown) {
$("#XMLHttpRequest").html("XMLHttpRequest : " + jqXHR.status);
$("#textStatus").html("textStatus : " + textStatus);
$("#errorThrown").html("errorThrown : " + errorThrown);
})

}

3.upd.php
<?php
// ------------------------------------------------------------------
// テキストボックスよりマウスが離れたときの処理

//
// Ajax通信ではなく、直接URLを叩かれた場合はエラーメッセージを表示
// ------------------------------------------------------------------

/* 本番サーバーではJSONが使えないので、代替えソースで対応する。  */

if (!function_exists('json_encode')) {
// JSON.phpを読み込んで
require_once './js/JSON.php';
// json_encode()関数を定義する
function json_encode($words) {
$s = new Services_JSON();
return $s->encodeUnsafe($words);
}
// json_decode()関数を定義する
function json_decode($json, $assoc = false) {
$s = new Services_JSON($assoc ? SERVICES_JSON_LOOSE_TYPE : 0);
return $s->decode($json);
}
}

if (
!(isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest') 
&& (!empty($_SERVER['SCRIPT_FILENAME']) && 'json.php' === basename($_SERVER['SCRIPT_FILENAME']))

{
die ('このページは直接ロードしないでください。');
}

include "./common/db/define.php";
include "./common/db/db_function.php";

try
{

// 入力情報を取得する。
$item_value = $_POST['arg1'];   // 登録値
$item_col = $_POST['arg2'];     // カラム名
$item_id = $_POST['arg3'];      // 更新行番号
$item_value=mb_convert_kana($item_value, 'a');

//DBに接続
try {
$dbh = new PDO('mysql:host='.$db['host'].';dbname='.$db['dbname'].';charset=utf8',$db['user'],$db['pass'],array(PDO::ATTR_EMULATE_PREPARES => false));
} catch (PDOException $e) {
echo "データベースへの接続に失敗しました。<br>";
die;
}

try{
if ($item_col =='pages'){
$sql="UPDATE mst_item SET ".$item_col." = :str WHERE id=:id";
}else{
$sql="UPDATE mst_item_price SET ".$item_col." = :str WHERE id=:id";
}
$stmt  = $dbh->prepare($sql);

if ($debug_flag ==1){
sys_log_write($db,"upd_cost","3","販売強化表","SQL",$sql,"");
}

$stmt -> execute( array(':str'=>$item_value , ':id'=>$item_id ));
}catch (PDOException $e) {
echo "例外キャッチ:", $e->getMessage(), "<br>";
}    

//
//  パッケージをコールし、計算値をセットする。
// 
$sql = 'call update_cost(?,@value)';
$stmt = $dbh->prepare($sql);
$stmt -> bindValue(1, $item_id, PDO::PARAM_INT);
$stmt->execute();

$dbh=null;
$stmt=null;

// 計算値を取得する。
$sql='SELECT round(shipping_fee_blk,0) AS shipping_fee_blk,round(price1,0) AS price1,round(price2,0) AS price2,round(price3,0) AS price3,round(price4,0) AS price4,round(price5,0) AS price5 FROM mst_item_price WHERE id =:id';

$stmt = $dbh->prepare('SELECT round(shipping_fee_blk,0) AS shipping_fee_blk,round(price1,0) AS price1,round(price2,0) AS price2,round(price3,0) AS price3,round(price4,0) AS price4,round(price5,0) AS price5 FROM mst_item_price WHERE id =:id');

$stmt -> execute( array(':id'=>$item_id ));

// execute the stored procedure
while($row = $stmt -> fetch(PDO::FETCH_ASSOC)) {
$rows[]=$row;
}
$dbh=null;
$stmt=null;

//JSON形式で出力する
header('Content-Type: application/json');
echo json_encode($rows);

}
catch (PDOException $e)
{
//例外処理
sys_log_write($db,"upd_cost","3","","エラー",$e->getMessage,"");
}

?>

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • m.ts10806

    2017/09/12 09:01

    ソースコードをご提示願います。現在の内容だけでは検証材料が全くありません。あと、開発環境と本番環境の環境情報も開示可能な範囲でいただけると助かります。

    キャンセル

  • asahina1979

    2017/09/12 09:39

    ソースコードはマークダウン対応してください

    キャンセル

  • m.ts10806

    2017/09/12 09:50

    プログラムコード(およびエラーメッセージ)は```で囲ってください。(わからなければ質問編集画面でコード部分を選択し<code>ボタンを押してください)

    キャンセル

回答 3

+2

<input>のHTMLの書式が正しくないのできちんと下記のように書きます。

  <input type="number" onchange="isRegNum(this)" id="<?php 
echo htmlspecialchars($row['id']); ?>" name="<?php 
echo htmlspecialchars("pages|".$i); ?>" style="background-color: #77c1e8;text-align:right;width:60px;" value="<?php 
echo htmlspecialchars($row['pages'] ,ENT_QUOTES,'UTF-8'); ?>">

JavaScriptは下記なので、テキストボックスの値を変更する度にupd.phpにPOSTしています。POST先のPHPではDB UPDATESELECTしているので、その処理時間分だけ待たなければいけません。特に連続して変更した場合は負荷がかなり高くなると思われます。
ですので、JavaScriptのイベントonChangeではなく、ボタンを設置してonClickなどに変更したほうが良いと思います。

本番環境(XSERVER)のみ発生しております。

本番環境のパフォーマンスがよくないため発生している問題だと思います。本番環境ではデーターの数が多い可能性もあるかと思います。(件数を見ていないので何とも言えませんが)また、JSON処理も高負荷になっていると予想されます。

function isRegNum(obj) 
{
    var obj_value = obj.value; /* 入力値 */
    var obj_name = obj.name; /* 更新カラム名 */
    var obj_id = obj.id; /* DB側の更新行番号 */

    result = obj_name.indexOf("|");
    obj_names = obj_name.substr(0, result); /* DB側の更新カラム名*/
    table_rows = Number(obj_name.substr(result + 1)); /* 画面側の更新行番号*/

    console.log(obj_value);
    console.log(obj_names);
    console.log(obj_id);

    // 入力値のチェック
    // 0から9 又は .(46)

    /* カンマが入力されていたら抜き取る*/
    var obj_value = obj_value.replace(/,/g, "");

    if (obj_names != "spec") {
        for (var i = 0; i < obj_value.length; i++) {
            var code = obj_value.charCodeAt(i);
            if ((48 > code || code > 57)) {
                if (code != 46) {
                    /* 数値(0-9)と (.)以外の文字コード範囲 */
                    swal({
                        title: "エラー",
                        text: "半角数字とピリオド以外の文字が入力されています。"
                    });
                    //
                    obj.value = "";
                    return false;
                }
            }
        }
    }

    $.ajax({
        type: "POST",
        url: "upd.php",
        datatype: "json",
        data: {
            arg1: obj_value,
            arg2: obj_names,
            arg3: obj_id
        },
    })
    .done(function(data) {
        /* 計算値をカンマ付きにさせる。 */
        var tables = document.getElementById("cost_tbl");
        var shipping_fee_blk = Number(data[0]['shipping_fee_blk']);
        var price1 = Number(data[0]['price1']);
        var price2 = Number(data[0]['price2']);
        var price3 = Number(data[0]['price3']);
        var price4 = Number(data[0]['price4']);
        var price5 = Number(data[0]['price5']);

        /* 計算値を表示させる。 */
        tables.rows[table_rows].cells[12].innerText = String(shipping_fee_blk).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,');
        tables.rows[table_rows].cells[16].innerText = String(price1).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,');
        tables.rows[table_rows].cells[17].innerText = String(price2).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,');
        tables.rows[table_rows].cells[18].innerText = String(price3).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,');
        tables.rows[table_rows].cells[19].innerText = String(price4).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,');
        tables.rows[table_rows].cells[20].innerText = String(price4).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,');

        /* 
        入力された値にもカンマを付けて再表示させる。 
        注意:ここは
        */
        var values = String(obj_value).replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,');

        switch (obj_names) {
            case "exchange":
                tables.rows[table_rows].cells[9].value = values;
                break;
            case "ratio":
                tables.rows[table_rows].cells[10].value = values;
                break;
            case "carriage":
                tables.rows[table_rows].cells[11].value = values;
                break;
            case "rate":
                tables.rows[table_rows].cells[13].value = values;
                break;
            case "lic_fee":
                tables.rows[table_rows].cells[14].value = values;
                break;
            case "adjust":
                tables.rows[table_rows].cells[15].value = values;
                break;
            case "retail_price":
                tables.rows[table_rows].cells[21].value = values;
                break;
        }
    })
    .fail(function(jqXHR, textStatus, errorThrown) {
        $("#XMLHttpRequest").html("XMLHttpRequest : " + jqXHR.status);
        $("#textStatus").html("textStatus : " + textStatus);
        $("#errorThrown").html("errorThrown : " + errorThrown);
    });
}
<?php
// ------------------------------------------------------------------
// テキストボックスよりマウスが離れたときの処理
//
// Ajax通信ではなく、直接URLを叩かれた場合はエラーメッセージを表示
// ------------------------------------------------------------------

/* 本番サーバーではJSONが使えないので、代替えソースで対応する。  */

if (!function_exists('json_encode')) {
    // JSON.phpを読み込んで
    require_once './js/JSON.php';
    // json_encode()関数を定義する
    function json_encode($words)
    {
        $s = new Services_JSON();
        return $s->encodeUnsafe($words);
    }
    // json_decode()関数を定義する
    function json_decode($json, $assoc = false)
    {
        $s = new Services_JSON($assoc ? SERVICES_JSON_LOOSE_TYPE : 0);
        return $s->decode($json);
    }
}

if (!(isset($_SERVER['HTTP_X_REQUESTED_WITH']) && 
    strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) === 'xmlhttprequest') && 
    (!empty($_SERVER['SCRIPT_FILENAME']) && 'json.php' === basename($_SERVER['SCRIPT_FILENAME']))) 
{
    die('このページは直接ロードしないでください。');
}

include "./common/db/define.php";
include "./common/db/db_function.php";

try {
    // 入力情報を取得する。
    $item_value = $_POST['arg1']; // 登録値
    $item_col   = $_POST['arg2']; // カラム名
    $item_id    = $_POST['arg3']; // 更新行番号
    $item_value = mb_convert_kana($item_value, 'a');

    //DBに接続
    try {
        $dbh = new PDO('mysql:host='.$db['host'].';dbname='.$db['dbname'].';charset=utf8', $db['user'], $db['pass'], array(
            PDO::ATTR_EMULATE_PREPARES => false
        ));
    }
    catch (PDOException $e) {
        echo "データベースへの接続に失敗しました。<br>";
        die;
    }

    try {
        if ($item_col == 'pages') {
            $sql = "UPDATE mst_item SET " . $item_col . " = :str WHERE id=:id";
        } else {
            $sql = "UPDATE mst_item_price SET " . $item_col . " = :str WHERE id=:id";
        }

        $stmt = $dbh->prepare($sql);

        if ($debug_flag == 1) {
            sys_log_write($db, "upd_cost", "3", "販売強化表", "SQL", $sql, "");
        }

        $stmt->execute(array(
            ':str' => $item_value,
            ':id' => $item_id
        ));
    }
    catch (PDOException $e) {
        echo "例外キャッチ:", $e->getMessage(), "<br>";
    }

    //
    //  パッケージをコールし、計算値をセットする。
    //
    $sql  = 'call update_cost(?,@value)';
    $stmt = $dbh->prepare($sql);
    $stmt->bindValue(1, $item_id, PDO::PARAM_INT);
    $stmt->execute();

    $dbh  = null;
    $stmt = null;

    // 計算値を取得する。
    $sql = 'SELECT round(shipping_fee_blk,0) AS shipping_fee_blk,round(price1,0) AS price1,round(price2,0) AS price2,round(price3,0) AS price3,round(price4,0) AS price4,round(price5,0) AS price5 FROM mst_item_price WHERE id =:id';

    $stmt = $dbh->prepare('SELECT round(shipping_fee_blk,0) AS shipping_fee_blk,round(price1,0) AS price1,round(price2,0) AS price2,round(price3,0) AS price3,round(price4,0) AS price4,round(price5,0) AS price5 FROM mst_item_price WHERE id =:id');

    $stmt->execute(array(
        ':id' => $item_id
    ));

    // execute the stored procedure
    while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
        $rows[] = $row;
    }

    $dbh  = null;
    $stmt = null;

    //JSON形式で出力する
    header('Content-Type: application/json');
    echo json_encode($rows);
}
catch (PDOException $e) {
    //例外処理
    sys_log_write($db, "upd_cost", "3", "", "エラー", $e->getMessage, "");
}
?>

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

check解決した方法

0

回答ありがとう御座いました。

結論としてJSONを使って更新を行うのは辞めました。

途中まで調べましたら、upd.phpの戻りが60秒ほど掛かっているのが
分かりましたが、その先がわかりませんでしたので
更新ボタンを付けるように変更しております。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

ソースをほとんど読んでいませんが、同じソースで挙動がことなるなら環境の問題の可能性が高いです。

たとえば、DB接続とか。
ただ、コメント見ると

/* 本番サーバーではJSONが使えないので、代替えソースで対応する。  */

とあったので、こちらが怪しい感じます。
この部分を変更して遅延がなくなれば、問題箇所は代替えソースかと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.12%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる