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

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

ただいまの
回答率

90.51%

  • PHP

    20352questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

  • MySQL

    5854questions

    MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

  • Zend Framework

    72questions

    Zend Frameworkは、PHP5で記述されたWebアプリケーションフレームワークです。Zend Frameworkには守らなければならない開発の規定というものは存在せず、MVCなどの複数のコンポーネントを提供しています。

更新処理が行われた場合だけ、リクエストパラメータを保存する仕組みを作りたい

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 523

soich

score 147

現状の問題を以下に箇条書きでまとめさせていただきました。
何卒ご一読いただけますと幸いです。

環境

PHP 5.3
Zend Framework 1.11.14
MySQL 5.6.14

やりたいこと

DBの更新処理を行った時だけグローバル変数の$_REQUESTをMySQLに履歴として保存したい
→更新処理を行ったアクション限定でDB保存処理を行いたい
(各アクションにDB登録処理を書くのではなく、親クラスで更新処理を行ったことを判定して$_REQUEST登録処理を行いたい)

現状把握・問題

更新処理を行ったアクションが統一されていない(registActionだったりupdateActionだったりする)

思いついた案

  • HTTPメソッドがPOSTで送られるもので絞り込んで登録
    →indexActionやconfirmActionでPOSTされているので、ホワイトリストで絞り込みが必要
    →ホワイトリストの管理運用が必要になるので、できればやりたくない

  • アクションでホワイトリストを作成して絞り込んで登録
    →ホワイトリストの管理運用が必要になるので、できればやりたくない

  • 保存する各アクションにフラグを設定する
    →現存のアクションがあまりに多く、今後追加が必要になることもあり、できればやりたくない

これができれば実現できそうだと思うもの

  • PHPのプロセス内でUPDATE文を実行したことを検知してDBに登録する

これぐらいしか案が思いつかず、途方に暮れております・・・

ソースで書くとこんなイメージです。

  • 子クラスその1
class Ko_First extends Oya{
        public function indexAction()
        {
        //ここの$_REQUESTは登録しない(HTTPメソッドがPOST)
    }

    public function registAction()
    {
        //ここの$_REQUESTは登録したい(HTTPメソッドがPOST)
    }
}
  • 子クラスその2
class Ko_Second extends Oya{
        public function indexAction()
        {
        //ここは登録しない
    }

    public function confirmAction()
    {
        //ここの$_REQUESTは登録しない(HTTPメソッドがPOST)
    }

    public function updateAction()
    {
        //ここの$_REQUESTは登録したい(HTTPメソッドがPOST)
    }
}
  • 親クラス
class Oya{
    ・・・

    public function postDispatch()
        // $_REQUESTをDBに登録する処理
    }
}


postDispatch()はAction後に行われるメソッドです。

参考になればどんな内容でもいいので、アドバイス頂けましたら幸いです。
よろしくお願いいたします。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

checkベストアンサー

0

全体的に意味がわからないのですが、
UPDATE文をPHPから発行するなら、発行後にrow_count()などして
影響があったかどうか確認しますね
それが「$_REQUESTをMySQLに履歴として保存したい」にどうつながるのでしょうか?
更新を検知してそれを元に更新したらまた更新が検知されて無限ループですよね?
また$_REQUEST=パラメータ全部をどう登録したいのかもよくわかりません。

むしろ$_REQUESTの値をつかってUPDATE文を発行して、影響がなければすなわち
$_REQUESTを投入しないし、影響があればUPDATEされるのだから
単にUPDATE文を1回発行するだけで良い話のような気がします

 trigger sample

データ用テーブルAと履歴用テーブルB
テーブルAのaidは主キーだが履歴を取る場合Bの主キーにはナリえないのでBに新たに
主キーbidを設定し、更新された日時も別途保存することとする

create table tblA(aid int primary key,val1 int,val2 int,val3 int);
create table tblB(bid int primary key auto_increment,aid int ,val1 int,val2 int,val3 int,modified datetime);


トリガー作成

drop trigger if exists a_to_b;
delimiter //
create trigger a_to_b after update on `tblA`
for each row begin
insert into tblB SET aid=old.aid,val1=old.val1,val2=old.val2,val3=old.val3,modified=now();
end;
//
delimiter ;


(1)データ投入

insert into tblA values(1,101,201,301),(2,102,202,302),(3,103,203,303);


tblAにはデータが新規投入されるが、tblBには投入されない

(2)更新データを投入

insert into tblA values(2,112,212,312),(4,104,204,304) on duplicate key update val1=values(val1),val2=values(val2),val3=values(val3);


id=2は更新されるのでtblBに古いデータが投入される、id=4は新規なので無視

(3)更新データを投入

insert into tblA values(2,122,222,322),(4,104,204,304) on duplicate key update val1=values(val1),val2=values(val2),val3=values(val3);


id=2は更新されるのでtblBに古いデータが投入される
(tblBのidはダブっているのが確認できる)
id=4は全てのvalが元のデータと一緒なので更新がかからないので無視

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2017/04/13 11:48

    コメントありがとうございます。
    わかりづらい文章だったかもしれません。すみません

    Aテーブルーデータを保存するテーブル
    BテーブルーAテーブルの更新履歴を残すテーブル
    としてお話いたします。

    >更新を検知してそれを元に更新したらまた更新が検知されて無限ループですよね?
    <?php
    class A extends B{

    public function updateAction(){
    // UPDATE文(Aテーブルに対して)
    }
    }

    class B{
    public function postDispach(){
    if([UPDATEが行われたかの判定]){
    //update文(Bテーブルに対して)
    }
    }
    }
    $a = new A();
    $a->updateAction(); //実際は画面からupdateActionを叩く想定
    ?>

    このような流れで処理を行おうと思っているのですが、これでは無限ループにはならないと思っています。

    >「$_REQUESTをMySQLに履歴として保存したい」にどうつながるのでしょうか?
    ご説明いただいている通り、UPDATE文で$_REQUESTのデータをAテーブルに保存しますがUPDATEがされる為、AテーブルのUPDATE前のデータは消えてしまうと認識しています。
    その履歴をBテーブルに別途保存したいと考えています。バックアップ的な意味合いで更新履歴を残しておきたいのです。

    >また$_REQUEST=パラメータ全部をどう登録したいのかもよくわかりません。
    $_REQUESTはjson形式の文字列にして一つのカラムに保存するつもりです。

    >発行後にrow_count()などして影響があったかどうか確認しますね
    認識が間違っていたら申し訳ないのですが、updateの場合は既存の行の値を変更するだけなのでrow_countの数字は変わらないと思うのですがいかがでしょうか?

    以上を踏まえて何か解決策がありましたら、よろしくお願いいたします。

    キャンセル

  • 2017/04/13 12:08 編集

    Aテーブルが上書き更新される際にBテーブルに退避させるのであれば
    トリガーで処理すればいいと思います。(トリガーのサンプル追記しときました)

    キャンセル

  • 2017/04/13 22:42

    トリガーという方法があるのですね。
    実際に導入可能か検証してみます。
    ご回答ありがとうございました。

    キャンセル

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

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

関連した質問

  • 解決済

    PHP Mysql

    下記のようなエラー出てしまって解決できません、誰かが教えていただけません? Mysqlのバージョンの問題のようには思いましたが解決できませんでした。 1)Strict Stand

  • 解決済

    MySQLでUPDATEが実行できない

    前提・実現したいこと PHPとMySQLで記事を「投稿」「編集」「削除」するシステムを作っています。   投稿と削除は完成したのですが、UPDATE文で実装しようと思っている編

  • 解決済

    FulePHPでController名を自由に変える

    FuelPHPで以下のルーティングを定義しました。 return [ '_root_' => 'welcome/index', // The default ro

  • 解決済

    PHPでのSQL文の書き方について

    PHP、MySQLでWebシステムを作成中の独学初心者です。 自分の中で、出来るだけHTMLとSQL文を混ぜたくないという思いがあります。 この考えが合っているのかは分かり

  • 解決済

    SQL prepareコールの外部クラス化について

    外部からprepareCallのクラスをリクエスト毎にnewすると、 同じ変数に代入した際に返り値が上書きされてしまいます。 どのように記述すれば上書きされず、別オブジェク

  • 解決済

    CakePHP2:テーブルモデルの共有は可能?

    接頭辞のみが異なる、まったく同じテーブル構成のテーブル[接頭辞]_applesがあります。 これらのテーブルで同じテーブルモデルの共有は可能でしょうか? 現在、以下のように

  • 解決済

    クエリの再利用について

    前提・実現したいこと PHP5.6とMYSQLで、あるテーブルの全レコード数を取得し、取得した全レコード数を同じページのいろいろな関数で何度か再利用がしたいです。 下記思い

  • 解決済

    Laravel5 - フォームから受け取ったデータでModelのSQLを実行させる方法

    最近Laravelを使い始めました。 初歩的な質問で恐縮なのですが、ご教授願います。 まず、viewの入力フォームからデータをいくつか受け取ります。 それらのデータを既存

同じタグがついた質問を見る

  • PHP

    20352questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

  • MySQL

    5854questions

    MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

  • Zend Framework

    72questions

    Zend Frameworkは、PHP5で記述されたWebアプリケーションフレームワークです。Zend Frameworkには守らなければならない開発の規定というものは存在せず、MVCなどの複数のコンポーネントを提供しています。