サポート » 使い方全般 » 入力フォームでデータ連携(SQL)する場合のシンプルな記述方法

  • いつもお世話になっております。
    現在、色々な方からご指導頂き(http://ja.forums.wordpress.org/topic/11236?replies=6#post-40931)下記の動作を確認することができました。
    本当にありがとうございます。

    • 入力ページを開いたとき、登録済みの内容を呼び出す
    • 入力ページで内容を更新または新規登録できる
    • 登録する内容は、ワードプレスとは別のデータベース(memberdb)テーブル(member)を使用する

    現在、下記2つの内容が気になっています。

    1.固定ページに記載する内容を最小限に抑える方法はありますか?
    (例えば、SQLが記載されているphpの内容は外部ファイルを呼び出すなど)
    
    2.セキュリティ的に問題がありそうな点がありますか?
    (例えば、入力フォームにSQL文を直接記載してデータベースのデータを抜き取られるなど)
    ※自身でわかる範囲で対策を行ったつもりです。

    もしあるようであれば、どのようにすればよいのかご指導頂けないでしょうか?
    よろしくお願いします。

    <?php
       mysql_connect('localhost', 'root', '') or die(mysql_error());
       mysql_select_db('memberdb');
       mysql_query('SET NAMES UTF8');
    
       $sql=sprintf("SELECT * FROM member WHERE user_id = %s",user_id);
       $recordSet = mysql_query($sql);
       $data = mysql_fetch_assoc($recordSet);
    ?>
    
    <form id="form" method="post" action='<?php echo get_permalink();?>'>
       <table>
    
          <label for="cname">名前*</label>
          <input type="text" id="cname" name="cname"
          value="<?php print(htmlspecialchars( $data['cname'],
                                                   ENT_QUOTES )); ?>" />
    
          <label for="user_id"></label>
          <input type="text" id="user_id" name="user_id"
          value="<?php print(htmlspecialchars( $data['user_id'],
                                                   ENT_QUOTES )); ?>" />
    
          <input type="submit" value="送信" />
    
       </table>
    </form>
    
    <?php
       if($_POST['cname']){
    
          mysql_connect('localhost', 'root', '') or die(mysql_error());
          mysql_select_db('memberdb');
          mysql_query('SET NAMES UTF8');
    
          $sql2 = sprintf("INSERT INTO company VALUES
                              ('$_POST[user_id]','$_POST[cname]')
          ON DUPLICATE KEY UPDATE cname = '$_POST[cname]'");
    
          $recordSet = mysql_query($sql2);
          $data = mysql_fetch_assoc($recordSet);
       };
    ?>
4件の返信を表示中 - 1 - 4件目 (全4件中)
  • モデレーター jim912

    (@jim912)

    zin-さん、こんにちは。

    $sql=sprintf("SELECT * FROM member WHERE user_id = %s",user_id);

    user_id の出所はどうなっていますか?それから変数ですか?

    if($_POST['cname']){
     ...

    送信元のデータが正当なもの(この固定ページから送信されたかどうか)を判定していないため、外部からのPOSTデータも受け付けて、不正なデータのINSERTが可能です。

    $sql2 = sprintf("INSERT INTO company VALUES
                              ('$_POST[user_id]','$_POST[cname]')
          ON DUPLICATE KEY UPDATE cname = '$_POST[cname]'");

    companyテーブルにinsertなのでしょうか?また、フォームの表示後に更新ロジックがあるため、送信ボタンクリック後の表示では、変更が反映されないのではないかと思いますがいかがでしょう。

    こんにちは、

    もうすでに、提示されているコードの大半は、PHPで、ワードプレスの関数は、get_permalink()だけのコードになっています。
    これだったら、ワードプレスにはフォームだけ置いて、データベースも別にしたほうがいいかも、、、

    セキュリティ的に問題がありそうな点がありますか?

    不安になるのは無理もないと思います。
    私は、公開画面でのPOSTは、簡単に出来るよ。といいましたが、
    セキュリティの必要な部分で、(例えば管理画面で)ワードプレスがこのような簡単なポストのやり方で動作しているかといえば、そうではありません。

    一例を示します ローカルにhtmlを1枚作ってみて、あなたのフォームのあるページと、ワードプレスのログイン画面のページをiframeで表示してみてください。:)

    <!DOCTYPE html>
    
    	<head>
    	<meta charset=utf-8>
    	<title>即席 html5</title>
    	<!--[if IE]>
    	<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
    	<![endif]-->
    	<link rel="stylesheet" href="http://html5resetcss.googlecode.com/files/html5-reset-1.4.css" media="all">
    	</head>
    	<body>
    
    	<header class="bar">
    	<h1>html5 Template</h1>
    	</header> 
    
    	<article>
    	<h2>Example</h2>
    	<iframe src="http://example.com/your-wp/wp-login.php"> </iframe>
    	<iframe src="http://example.com/your-wp/your-form.php"> </iframe>
    
    	</article> 
    
    	<footer class="bar">
    	<address>
    	http://d.hatena.ne.jp/tenman/
    	</address>
    	</footer>
    
    </body>
    </html>

    ブラウザにもよるかもしれませんが、ログイン画面の方は、何も表示されないと思います。

    じゃ、ワードプレス流ならどうするのがいいのか?

    kzさんのヒントは、的を得ていると思いますよ

    トピック投稿者 zin-

    (@zin-)

    皆様、ご連絡ありがとうございます。

    何を質問すればよいのかがだんだんわかってきました。
    まず大まかなやりたいことは下記となります。

    1.ユーザーはフォームに入力を行う。
     (約8入力項目/1ページを合計8ページ位=約60項目)
    
    2.管理側(私)はそれぞれのユーザーの入力内容を
    定型フォーマットに反映させ文章を確認できるようにする。
    
    3.ユーザー(user_id)はWelcartで管理し、出来上がった
    文章を購入してもらう。
     (※Welcart専用のIDが付与されます。)

    尚、kzさんとnobitaさんからご推薦頂いたカスタム投稿タイプについてですが、まずカスタム投稿タイプをもう一度、手持ちの書籍で調べてみました。
    管理者側が記事を投稿する際に一定のフォームを事前に設けておいて、それに沿って記入することで毎回決まった形(レイアウト)で記事を作る方法と理解しました。

    今回は記事の中にフォームを作成し、ユーザー側からデータを入力してもらうという動きを実現したいのでカスタム投稿タイプではちょっと難しいのかなぁと思っています。

    最後に補足となりますが、ContactForm7とContactForm7 Database Extensionの使用を検討したのですが、XML保存形式だと1カラムあたりのデータ量が大きくなってしまうのとXMLの取り出し方などが知識不足でわからなかったため使用しないことにしました。。。
    (今考えるとContactForm7で作成した方が簡単にセキュリティもあまり気にしなくてできあがるのかな?もしそうなら推薦頂けると助かります。)

    以上、よろしくお願いします。

    トピック投稿者 zin-

    (@zin-)

    jim912さん、ご指摘ありがとうございます。

    ①user_idについてですが、コードの変換で失敗していました。
    今回はWelcartを使用しているため下記が正しいコードとなります。

    $sql=sprintf("SELECT * FROM member WHERE user_id = %s",usces_memberinfo('ID','return'));

    送信元のデータが正当なもの(この固定ページから送信されたかどうか)を判定していない

    ですね。。。言われてみるとわかるのですが確かに問題が起こる可能性が高いですね。
    送信元のデータが正当なものかどうかを判断するのはget_pageといった関数を使えば実現できるのでしょうか?

    ③すいません。memberテーブルでした。ごめんなさい。
    ご指摘の通り、変更したはずなのに以前のデータが表示されてしまいます。
    ただデータベース上では反映されています。
    データベースおよびページ内で変更後のデータを表示するやり方はどのようにすればいいのでしょうか?
    Headerに現ページのURLを送るなど検討してみましたが、現実的ではないなぁと思い、情報収集中です。

4件の返信を表示中 - 1 - 4件目 (全4件中)
  • トピック「入力フォームでデータ連携(SQL)する場合のシンプルな記述方法」には新たに返信することはできません。