サポート » 使い方全般 » 入力フォームからのページ自動生成

  • 解決済 yuya198979

    (@yuya198979)


    はじめまして。質問させていただきます。

    webページ(オークションサイトのようなもの)訪問者が入力ページより情報を入力し、その情報に基づくカスタム投稿ページを自動生成するものを作成中です。(できるだけ、プラグインは使わずに。)

    しかし、データベースに登録はできるのですが、カスタム投稿ページを生成することができません。
    間違っている箇所をご教示いただけますでしょうか。

    以下にコードの一部を示します。

    入力フォーム

    <form id="form" method="post" action='php/db_input1.php'>
    <table>
    
    <label for="user_name">名前</label>
    <input type="text" id="user_name" name="user_name" value="user_name" />
    
    <label for="item_name">商品名</label>
    <input type="text" id="" name="item_name" value="item_name" />
    
    <label for="comment">コメント</label>
    <input type="text" id="comment" name="comment" value="comment" />
    
    <input type="submit" value="送信" />
    
    </table>
    </form>

    db_input1.php

    $con = mysql_connect('127.0.0.1', '########', '#######');
    if (!$con) {
    	  exit('データベースに接続できませんでした。');
    }
    
    $result = mysql_select_db('wordpress', $con);
    if (!$result) {
    	  exit('データベースを選択できませんでした。');
    }
    
    $result = mysql_query('SET NAMES utf8', $con);
    if (!$result) {
    	  exit('文字コードを指定できませんでした。');
    }
    
    $u_name = $_REQUEST['user_name'];
    $i_name = $_REQUEST['item_name'];
    $com = $_REQUEST['comment'];
    if($_REQUEST['user_name']){
               $result = mysql_query("
    		INSERT INTO syuppin VALUES
    			(112345,'$u_name','$i_name','$com')");
               require_once locate_template('php/auto_upload.php');
    }
    else{
    	echo "user_name ERROR";
    }
    ?>

    どうやら、require_once locate_template(‘php/auto_upload.php’);がうまく動いてい内容です。どうぞよろしくお願い申し上げます。

10件の返信を表示中 - 1 - 10件目 (全10件中)
  • ページの自動生成は wp_insert_post 関数を使うのが定番だと思います。何か特別な理由があって mysql_query 関数を使っておられるのですか?

    トピック投稿者 yuya198979

    (@yuya198979)

    gblsm様

    お返事ありがとうございます。

    “auto_upload.php”のソース記載が抜けておりました。
    http://www.necozine.com/wordpress/posts-from-php/
    ↑こちらのサイトを参考にauto_upload.phpでは、wp_insert_post関数を用いております。

    mysql_query 関数を用いている理由としては、db_input1.php内では、$wpdbが使えなかったためです。(function.php内では$wpdbが使えるのですが、db_input1.php内では$wpdbがNULLとなってしまいました。)

    同様に、auto_upload.phpもfunction.php内では呼び出せるのですが、入力フォームから呼び出しているdb_input1.php内ではうまく動作しません。

    以上です。どうぞ宜しくお願いいたします。

    同様に、auto_upload.phpもfunction.php内では呼び出せるのですが、入力フォームから呼び出しているdb_input1.php内ではうまく動作しません。

    うまく動作しない、をもう少し具体的に示して頂かないとコメントしにくいですね。

    それから、そのサイトの説明では、WordPressのプラグインとして作成されているようですが、入力フォームや db_input1.php は自作プラグインなのですか?

    トピック投稿者 yuya198979

    (@yuya198979)

    gblsm様

    同様に、auto_upload.phpもfunction.php内では呼び出せるのですが、入力フォームから呼び出しているdb_input1.php内ではうまく動作しません。

    wp-config.phpにdefine(‘WP_DEBUG’, true);を記載して、エラーメッセージを出力するようにしているのですが、実行しても何も表示されずに自動投稿がされておりません。

    それから、そのサイトの説明では、WordPressのプラグインとして作成されているようですが、入力フォームや db_input1.php は自作プラグインなのですか?

    自作プラグインというものを十分に理解していないのですが、入力フォームや db_input1.php は自分で作成したコードです。function.phpにショートコードを書いて呼び出しております。

    以上です。どうぞ宜しくお願いいたします。

    syuppinテーブルにレコードがINSERTされているのは確認済みなのですよね。
    locate_templateの使い方が間違っていないでしょうか?

    トピック投稿者 yuya198979

    (@yuya198979)

    gblsm様

    はい、確認済です。
    私もlocate_templateが問題だと思うのですが、どのように変更すればよいのかわかりません。
    ちなみに、以下のようにfunction.phpからのショートコードで呼び出した場合は問題なく自動生成されております。

    function.php

    add_shortcode('test','test');
    function test(){
    	require_once locate_template('php/auto_upload.php');
    }

    失礼を承知で書きますが、お示しの方法はちょっと危ないので、設計を見直された方がいいと思います。「訪問者」ということですので、ユーザ登録をした人だけに表示される内容ではないようですし。危険な部分は、たとえば、次のようなところです。

    1. form に何の制限もないため、何度でも、何でも送信できる。
    2. その気になれば、別のサーバからも投稿できる。
    3. $_POST で送られてきた内容を生のまま SQL 文に使っているので、自由に書き換えることができる。

    このままだと、SQL インジェクションし放題、スパム送り放題になってしまうのではないかと心配になります。余計なお世話だったら、申し訳ありませんが…

    さて、それとは別に、なぜ locate_template() が動かないかですが、form から呼び出された db_input1.php は WordPress の情報を一切引き継がないので、WordPress の定数、変数、関数すべて使うことができません。これら、WordPress のオブジェクトの多くはグローバルな空間に存在しますが、db_input1.php は、それとは別のプロセス、空間で動作します。デバッグモードで試すと、undefined function と言われるはずです。

    WordPress の機能を使いたいという場合は、db_input1.php の冒頭で、

    require_once('absolute-path-to/wp-config.php');

    みたいなことをすれば、可能です。admin-ajax.php を紹介するブログ記事では、この手を使うことが多いようです。お勧めはしません。

    単に、db_input1.php の中で、auto-upload.php を呼びたい場合は、同じディレクトリにあるなら、

    require_once(dirname(__FILE__) . '/auto-upload.php');

    のような、PHP が持っている関数や定数を使う、または、絶対パスを使えばお望みのことができます。なお、ここでも、本当は、グローバルな関数に処理をさせるよりは、外部から直接実行できないようにカプセル化し、WordPress に備え付けの Ajax を使った方が安全ですし、何より、WordPress のオブジェクトを使うことができます。

    ただ、ちょっと残念なのは、WordPress の Ajax は基本的に、ダッシュボードで使うように設計されているのを、フロントエンドでも使えるようにしましたという感じなのと、Codex の記述がいまいちで、外部リンクに丸投げしてるところです。一応、参考まで: AJAX in Plugins

    あ、それから、mysql_* は、非推奨なので、mysqli ライブラリを使うほうが長く使えると思います。

    トピック投稿者 yuya198979

    (@yuya198979)

    kjmtsh様

    細部まで詳しくご教示下さり誠にありがとうございます。
    長文となりましたが、以下に返事をさせていただいております。

    1.form に何の制限もないため、何度でも、何でも送信できる。
    2.その気になれば、別のサーバからも投稿できる。
    3.$_POST で送られてきた内容を生のまま SQL 文に使っているので、自由に書き換えることができる。

    私自身、”3″に関してはSQLインジェクションの脅威を理解していたのですが、Webサーバ構築が初めてでセキュアなコードがどのようなものか今一つイメージができません。
    もしよろしければ、1~3の対策となるコードをどうすればよいかご教授いただけませんでしょうか。

    さて、それとは別に、なぜ locate_template() が動かないかですが、form から呼び出された db_input1.php は WordPress の情報を一切引き継がないので、WordPress の定数、変数、関数すべて使うことができません。これら、WordPress のオブジェクトの多くはグローバルな空間に存在しますが、db_input1.php は、それとは別のプロセス、空間で動作します。デバッグモードで試すと、undefined function と言われるはずです。

    wp-config.phpにdefine(‘WP_DEBUG’, true);を記載して、エラーメッセージを出力するようにしているのですが、”undefined function”と出力されません。デバッグモードはどのように設定すればよいのでしょうか。

    WordPress の機能を使いたいという場合は、db_input1.php の冒頭で、

    require_once(‘absolute-path-to/wp-config.php’);

    db_input1.phpの冒頭にこれを記述して実行したところ、フォーム入力後のページが白紙となり、データベースに追加もできなくなりました。

    単に、db_input1.php の中で、auto-upload.php を呼びたい場合は、同じディレクトリにあるなら、

    require_once(dirname(__FILE__) . ‘/auto-upload.php’);

    これもやってみたのですが、初期と同じくデータベースに追加はできるのですが、自動投稿はできません。

    以上です。大変お手数ですが、お返事いただければと思います。
    どうぞ宜しくお願い申し上げます。

    ええっと、

    require_once('absolute-path-to/wp-config.php');

    これをそのまま書いちゃいましたか?

    require_once('絶対パス/wp-config.php');

    これなら、意味が伝わるでしょうか? wp-config.php までの絶対パスを指定するということです。

    セキュアなコードがどのようなものか今一つイメージができません。

    現在のコードだと、たとえば、適当に user_name、item_name、comment フィールドを持ったフォームを作って、別のサーバから、直接 db_input1.php に向けて POST しても拒否されませんよね? Spammer は、フォームタグを見つけると、何でも見境なく送りつけようとしますので、データベースが広告で溢れちゃうんじゃないでしょうか? SQL インジェクションについては、ここでは書きませんので、検索してみてください。実際に可能だということはチェックしました。

    対策となるコード…

    数行追加すれば大丈夫、みたいなお手軽な方法はありません。私のお勧めは次のものです。

    1. プロに依頼する
    2. WordPress に制御を任せる
    3. プラグインを使う
    4. あきらめる

    プラグインはあまり使っていないので、よく知りません。入力からデータベース操作まで、WordPress の管轄下に置けば、それなりにセキュリティを担保できます。ログインユーザだけにアクセス可能な状態にするだけでも、外部からの攻撃には有効です。

    また、WP_DEBUG 定数については、

    をご覧ください。稼働中のサイトでは、迂闊なものをブラウザに表示するのは憚られる場合もあるでしょうから、ログを取るほうがお勧めです。

    モデレーター Takuro Hishikawa

    (@hissy)

    私もプラグインを使った方がいいと思いますねぇ。ちょっと調べてみても色々ありますし。

    https://wordpress.org/plugins/user-submitted-posts/

    とりあえず冒頭のコードは脆弱性のある危険なコードのお手本みたいな感じです。

10件の返信を表示中 - 1 - 10件目 (全10件中)
  • トピック「入力フォームからのページ自動生成」には新たに返信することはできません。