\r\n\r\n\r\n\r\n\r\n**【post.php】画像とコメントを受け取って、データベースに反映するファイルです。**\r\n\r\n0){\r\n\t\tif($gazou['size']>1000000){\r\n\t\t\techo '画像サイズが大きすぎます。';\r\n\t\t}else{\r\n\t\t\tmove_uploaded_file($gazou['tmp_name'],'./images/'.$gazou['name']);\r\n\t\t\t$dsn = 'mysql:dbname=********;host=localhost';\r\n\t\t\t$user ='root';\r\n\t\t\t$password ='********';\r\n\t\t\t$dbh = new PDO($dsn,$user,$password);\r\n\t\t\t$dbh->query('SET NAMES utf8');\r\n\t\t\t$sql='INSERT INTO ********(image) VALUES(?)';\r\n\t\t\t$stmt=$dbh->prepare($sql);\r\n\t\t\t$gazou[]=$gazou['name'];\r\n\t\t\t$stmt->execute($data);\t\r\n\t\t}\r\n\t}\r\n\t$dbh=null;\r\n}catch(Exception $e){\r\n\tprint 'ただいま障害により大変ご迷惑をお掛けしております。';\r\n\texit();\r\n}\r\n?>\r\nquery('SET NAMES utf8');\r\n\t$sql='INSERT INTO ********(contents) VALUES(?)';\r\n\t$stmt=$dbh->prepare($sql);\r\n\t$data[]=$contents;\r\n\t$stmt->execute($data);\t\r\n\t$dbh=null;\r\n}catch(Exception $e){\r\n\tprint 'ただいま障害により大変ご迷惑をお掛けしております。';\r\n\texit();\r\n}\r\n?>\r\n\r\n**【comment_get.php】コメントを取得して、jsonで返しています。**\r\n\r\n query('SET NAMES utf8');\r\n\t$sql= 'SELECT * FROM ******** WHERE 1 ORDER BY time DESC';\r\n\t$stmt=$dbh->prepare($sql);\r\n\t$stmt->execute();\r\n\t\r\n\t$dbh=null;\r\n\t\r\n\twhile ($rec = $stmt->fetchObject()\t){\r\n\t\tif($rec==false){\r\n\t\t\tbreak;\r\n\t\t}\r\n $users[] = array(\r\n\t\t\t'id'=> $rec->id,\r\n 'name' => $rec->contents\r\n );\r\n }\r\n\theader('Content-Type: application/json');\r\n\techo json_encode($users); // JSON出力\r\n}catch(Exception $e){\r\n\tprint 'ただいま障害により大変ご迷惑をお掛けしております。';\r\n\texit();\r\n}\r\n?>\r\n\r\n以上です。\r\nお力添えをお願いいたします。","answerCount":2,"upvoteCount":0,"datePublished":"2015-07-25T14:14:39.240Z","dateModified":"2015-07-25T14:16:33.135Z","acceptedAnswer":{"@type":"Answer","text":"普通にajaxで送っても、ファイルは送信されません。\r\nなぜなら、\r\n```javascript\r\n { \r\n 'gazou': $('input[name=gazou]').val(), \r\n 'contents': $('input[name=contents]').val(), \r\n }\r\n```\r\nの部分、`$('input[name=gazou]').val()`の戻り値が何か考えてみましょう。\r\n\r\n答えはファイル名です。\r\nというよりファイル名かどうかはどうでもいいのですが、JQuery.val() メソッドの戻り値は string 型の値です。\r\nつまり文字列を送信しているのです。\r\n\r\nではどうするか。こちらをご覧ください。\r\nhttp://blog.asial.co.jp/1260\r\n\r\n私も試したことがないのですが、(Android 捨てるのはちょっと)\r\ndataに対して、独自定義のオブジェクトではなく FormData クラスのインスタンスを渡すということです。\r\n\r\nこれで非同期でファイル送信可能ですが、実は古くからあるある古典的な方法を使用すると、古い実装でも問題なく動く (場合が多い、という程度かもしれませんが・・・) 方法があります。\r\n\r\nその方法は、ajax リクエストすら使用しません。\r\nform をそのまま submit します。\r\nただしそれでは画面遷移が行われてしまいます。\r\nしかし画面遷移には回避策があります。\r\n\r\nこちらをご覧ください。\r\nhttp://blog.yuhiisk.com/archive/2014/12/16/seamless-file-upload.html\r\n\r\n要は、遷移しているけど、メインフレームじゃない見えないところでやっているから遷移していないように見えるということです。\r\n---\r\nリンク先で少し言及していますが、コールバックの方法を補足します。\r\nこの場合レスポンスはJSONではなくHTMLになります。\r\nただのフレームなので。\r\nでもHTMLということはscriptタグも使えます。Same-Origin Policy的に問題なければ、親子フレーム間で関数を呼び合うことは可能なのでコールバックできます。\r\n\r\n```html\r\n\r\n```\r\nこんなHTMLが返れば、frameElement.callback が実行されます。\r\n本来 data-result は html としておよび json としてエスケープしてくださいね。\r\n\r\nframeElement.callback は自分で定義します。\r\n親フレーム側で、submit 時にはセットされているように。form の`submit`イベントで送信の前処理ができます。\r\n```javascript\r\nvar frame = $(\"iframe\").get(0);\r\nframe.callback = function(responseObject){\r\n responseObject.abc;// →\"ここにレスポンスJSON\"\r\n delete frame.callback; // 何かの間違いで2度実行されないようコールバックは消す\r\n}\r\n```\r\n親フレームから見た、子フレーム(つまりiframe要素`$(\"iframe\").get(0)`または`document.getElementById(\"iframeのID\")`)と、\r\n子フレームから見た、グローバル変数`frameElement`は同一のオブジェクトで、メンバーを共有しています。\r\n\r\nもうひとつ、ただのフレームなので、通信失敗時の処理が苦手です。\r\nHTML なのでどんなにおかしなレスポンスが返されようとエラーは発生しません。\r\nただ、コールバックを呼んでくれないだけです。\r\nリンク先でタイムアウトを設定といっているのはそういうことです。\r\nsubmit したときから callback 関数が一定時間呼ばれなかったらもう失敗したものとして扱っていいとおもいます。","dateModified":"2015-07-25T16:58:47.349Z","datePublished":"2015-07-25T16:55:13.608Z","upvoteCount":1,"url":"https://teratail.com/questions/13438#reply-20393"},"suggestedAnswer":[{"@type":"Answer","text":"お返事が遅くなってしまい、申し訳ございませんでした。\r\n\r\n初の質問でしたが、こんなに丁寧に返信していただるとは思いませんでした。\r\n本当にありがとうございます。\r\n\r\n実装はまだできていませんが、いただいた参考URLとtozjp様の助言をもとに進めることができそうです。\r\nわかりやすいご回答、ありがとうございました。","dateModified":"2015-07-31T04:50:06.264Z","datePublished":"2015-07-31T04:50:06.264Z","upvoteCount":0,"url":"https://teratail.com/questions/13438#reply-21050","comment":[]}],"breadcrumb":{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"トップ","url":"https://teratail.com"},{"@type":"ListItem","position":2,"name":"MySQLに関する質問","url":"https://teratail.com/tags/MySQL"},{"@type":"ListItem","position":3,"name":"MySQL","url":"https://teratail.com/tags/MySQL"}]}}}
質問するログイン新規登録
MySQL

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

PHP

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

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

Q&A

解決済

2回答

6719閲覧

ajaxを使った画面遷移なし、画像ありの掲示板(Twitterの簡易版のようなものです)

ssk

総合スコア332

MySQL

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

PHP

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

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Ajax

Ajaxとは、Webブラウザ内で搭載されているJavaScriptのHTTP通信機能を使って非同期通信を利用し、インターフェイスの構築などを行う技術の総称です。XMLドキュメントを指定したURLから読み込み、画面描画やユーザの操作などと並行してサーバと非同期に通信するWebアプリケーションを実現することができます。

0グッド

0クリップ

投稿2015/07/25 14:14

編集2015/07/25 14:16

0

0

プログラミング初心者です。
PHPの入門書を購入後、掲示板作成(PHPとMySQLを使ったもの)まで終わりました。

その後、レベルアップのために掲示板のクオリティを上げている最中で
入門書などを参考に色々と機能を追加したのですが、画像の取り扱いで困っています。

【できていること】
・ajaxを使って、画面遷移なしでデータベースにテキストを反映
・データベースにあるテキストをHTMLに反映

【できていないこと、やりたいこと】
・HTMLファイルから画像をデータベースにアップ(画面遷移なし)
・その画像をテキストと一緒に出力

http://qiita.com/yugokitajima/items/b2fb29f5bc9af8a6bf8e
↑こちらのサイトを参考に作成しています。

【sample.html】画像を添付し、コメントを入力するHTMLです。ajaxもここにあります。

<!doctype html> <html lang="ja"> <head> <meta charset="UTF-8"> <title>Document</title> </head> <body> <form enctype="multipart/form-data"> 画像<input type="file" name="gazou"><br /> コメント<input type="text" name="contents" value="" placeholder="入力必須"><br /> <input type="button" id="send-comment" value="送信"><span style="color: red;" id="send-comment-error"></span> </form> <!--{* コメントがある場合はここにセットされる *}--> </div> <ul id="content"></ul> </body> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> <script> // コメント一覧受信・表示 $(document).ready(function(){ // 送信ボタンを押したら sendComment() を実行 $('input#send-comment').click(function(){ sendComment(); }); // 既存のコメントを読み込んで表示 getComment(); }); function sendComment() { // 未入力チェック if (!$('input[name=contents]').val()) { $('#send-comment-error').text('名前を入力して下さい。'); return false; }
$.post( 'post.php', { 'gazou': $('input[name=gazou]').val(), 'contents': $('input[name=contents]').val(), }, function(data){ // 書き込みが完了したら再度コメント一覧を読み込む location.reload(getComment()); } );

}
function getComment() {
$.ajax({
type: "GET",
url: "comment_get.php",
dataType: "json",
/**
* Ajax通信が成功した場合に呼び出されるメソッド
*/
success: function(data, dataType)
{
//結果が0件の場合
if(data == null) alert('データが0件でした');

//返ってきたデータの表示 var $content = $('#content'); for (var i =0; i<data.length; i++) { $content.append("<li>" + data[i].name + "</li>"); } }, }); }
</script> </html>

【post.php】画像とコメントを受け取って、データベースに反映するファイルです。

<?php //画像をテーブルへ try{ $gazou=$_FILES['gazou']; if($gazou['size']>0){ if($gazou['size']>1000000){ echo '画像サイズが大きすぎます。'; }else{ move_uploaded_file($gazou['tmp_name'],'./images/'.$gazou['name']); $dsn = 'mysql:dbname=********;host=localhost'; $user ='root'; $password ='********'; $dbh = new PDO($dsn,$user,$password); $dbh->query('SET NAMES utf8'); $sql='INSERT INTO ********(image) VALUES(?)'; $stmt=$dbh->prepare($sql); $gazou[]=$gazou['name']; $stmt->execute($data); } } $dbh=null; }catch(Exception $e){ print 'ただいま障害により大変ご迷惑をお掛けしております。'; exit(); } ?> <?php //コメントをテーブルへ try{ $contents=$_POST['contents']; $contents=htmlspecialchars($contents); $dsn = 'mysql:dbname=********;host=localhost'; $user ='root'; $password ='********'; $dbh = new PDO($dsn,$user,$password); $dbh->query('SET NAMES utf8'); $sql='INSERT INTO ********(contents) VALUES(?)'; $stmt=$dbh->prepare($sql); $data[]=$contents; $stmt->execute($data); $dbh=null; }catch(Exception $e){ print 'ただいま障害により大変ご迷惑をお掛けしております。'; exit(); } ?>

【comment_get.php】コメントを取得して、jsonで返しています。

<?php try{ $users = null; $dsn = 'mysql:dbname=********;host=localhost'; $user ='root'; $password ='********'; $dbh = new PDO($dsn,$user,$password); $dbh->query('SET NAMES utf8'); $sql= 'SELECT * FROM ******** WHERE 1 ORDER BY time DESC'; $stmt=$dbh->prepare($sql); $stmt->execute(); $dbh=null; while ($rec = $stmt->fetchObject() ){ if($rec==false){ break; } $users[] = array( 'id'=> $rec->id, 'name' => $rec->contents ); } header('Content-Type: application/json'); echo json_encode($users); // JSON出力 }catch(Exception $e){ print 'ただいま障害により大変ご迷惑をお掛けしております。'; exit(); } ?>

以上です。
お力添えをお願いいたします。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

普通にajaxで送っても、ファイルは送信されません。
なぜなら、

javascript

1 { 2 'gazou': $('input[name=gazou]').val(), 3 'contents': $('input[name=contents]').val(), 4 }

の部分、$('input[name=gazou]').val()の戻り値が何か考えてみましょう。

答えはファイル名です。
というよりファイル名かどうかはどうでもいいのですが、JQuery.val() メソッドの戻り値は string 型の値です。
つまり文字列を送信しているのです。

ではどうするか。こちらをご覧ください。
http://blog.asial.co.jp/1260

私も試したことがないのですが、(Android 捨てるのはちょっと)
dataに対して、独自定義のオブジェクトではなく FormData クラスのインスタンスを渡すということです。

これで非同期でファイル送信可能ですが、実は古くからあるある古典的な方法を使用すると、古い実装でも問題なく動く (場合が多い、という程度かもしれませんが・・・) 方法があります。

その方法は、ajax リクエストすら使用しません。
form をそのまま submit します。
ただしそれでは画面遷移が行われてしまいます。
しかし画面遷移には回避策があります。

こちらをご覧ください。
http://blog.yuhiisk.com/archive/2014/12/16/seamless-file-upload.html

要は、遷移しているけど、メインフレームじゃない見えないところでやっているから遷移していないように見えるということです。

リンク先で少し言及していますが、コールバックの方法を補足します。
この場合レスポンスはJSONではなくHTMLになります。
ただのフレームなので。
でもHTMLということはscriptタグも使えます。Same-Origin Policy的に問題なければ、親子フレーム間で関数を呼び合うことは可能なのでコールバックできます。

html

1<script id="res" data-result='{"abc": "ここにレスポンスJSON"}'> 2 var responseObject = JSON.parse(document.getElementById("res").dataset.result); 3 frameElement.callback(responseObject); 4</script>

こんなHTMLが返れば、frameElement.callback が実行されます。
本来 data-result は html としておよび json としてエスケープしてくださいね。

frameElement.callback は自分で定義します。
親フレーム側で、submit 時にはセットされているように。form のsubmitイベントで送信の前処理ができます。

javascript

1var frame = $("iframe").get(0); 2frame.callback = function(responseObject){ 3 responseObject.abc;// →"ここにレスポンスJSON" 4 delete frame.callback; // 何かの間違いで2度実行されないようコールバックは消す 5}

親フレームから見た、子フレーム(つまりiframe要素$("iframe").get(0)またはdocument.getElementById("iframeのID"))と、
子フレームから見た、グローバル変数frameElementは同一のオブジェクトで、メンバーを共有しています。

もうひとつ、ただのフレームなので、通信失敗時の処理が苦手です。
HTML なのでどんなにおかしなレスポンスが返されようとエラーは発生しません。
ただ、コールバックを呼んでくれないだけです。
リンク先でタイムアウトを設定といっているのはそういうことです。
submit したときから callback 関数が一定時間呼ばれなかったらもう失敗したものとして扱っていいとおもいます。

投稿2015/07/25 16:55

編集2015/07/25 16:58
tozjp

総合スコア790

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

お返事が遅くなってしまい、申し訳ございませんでした。

初の質問でしたが、こんなに丁寧に返信していただるとは思いませんでした。
本当にありがとうございます。

実装はまだできていませんが、いただいた参考URLとtozjp様の助言をもとに進めることができそうです。
わかりやすいご回答、ありがとうございました。

投稿2015/07/31 04:50

ssk

総合スコア332

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.29%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問