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

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

新規登録して質問してみよう
ただいま回答率
85.50%
PHP

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

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

2回答

2458閲覧

DBへの登録の際、セッションに配列として保存しておいた値を取り出したい

earnest_gay

総合スコア615

PHP

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

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2016/06/20 00:56

編集2016/06/20 01:46

まず、下記記述の確認をお願いします。
全部記述すると膨大な量になるので一部をシンプルにして記述します。

↓input.php

追加を2回押して
計6フォームを入力したとして、
6フォーム分の値をセッションに保存して
次ページ(確認ページ)にいきます。

<?php session_start(); if(!empty($_POST)){ $_SESSION['join2'] = $_POST; header('Location: preview.php'); } ?> <script type="text/javascript"> /*スキルエリアのセレクトボックスセットのクローン*/ function skill_selectAdd(){ var get = document.getElementById("skill_select"); var set = get.cloneNode(true); var target = document.getElementById("skill_selectAdd"); var btn_delete = document.getElementById("skill_select_btnDel"); set.id= "test" + target.children.length;//idの重複を防ぐため、連番をつけておく target.parentNode.insertBefore(set, target); btn_delete.disabled = false; } /*スキルエリアのセレクトボックスセットの削除*/ function skill_selectDel(){ var targets = document.getElementsByClassName("skill_select"); var btn_delete = document.getElementById("skill_select_btnDel"); if (targets.length === 2) { btn_delete.disabled = true; } targets[1].parentNode.removeChild(targets[targets.length - 1]);//最後の要素を削除 } </script> <form action="" method="post"> <tr id="skill_select" class="skill_select"> <td> <select name="programs1_[]"> <?php echo Programmerskill::getSkill(); ?> </select> </td> <td> <select name="programs_year1_[]"> <?php echo Skillyear::getYear(); ?> </select> </td> </tr> <tr id="skill_selectAdd"> <td colspan="2"> <input type="button" value="追加" onClick="skill_selectAdd()"> <input type="button" value="削除" onClick="skill_selectDel()" id="skill_select_btnDel" disabled="true"> </td> </tr> <input type="submit" name="submit" value="プレビュー"> </form>

↓preview.php

セレクトボックスで選択した3セット分(6件)の内容が表示されます。

<?php session_start(); ?> ・ ・ ・ <form action="thanks.php" method="post"> <tr> <td> <?php $arr = $_SESSION['join2']['programs1_']; for($i=0;$i < count($arr);$i++ ) { echo h($arr[$i]).'<br />'; } ?> </td> <td> <?php $arr = $_SESSION['join2']['programs_year1']; for($i=0;$i < count($arr);$i++ ) { echo h($arr[$i]).'<br />'; } ?> </td> </tr> <input type="submit" name="submit" value="確定"> </form>

↓thanks.php

DBへ登録します。

<?php session_start(); $dsn = 'mysql:dbname=test;host=localhost;charset=utf8'; $user = 'root'; $password = ''; $option = array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION); $dbh = new PDO($dsn, $user, $password, $option); $stmt = $pdo->prepare("INSERT INTO user_skill() VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"); $stmt->execute([ $_SEESION['join2']['programs1_1'], $_SEESION['join2']['programs_year1_1'], $_SEESION['join2']['programs1_2'], $_SEESION['join2']['programs_year1_2'], $_SEESION['join2']['programs1_3'], $_SEESION['join2']['programs_year1_3'], $_SEESION['join2']['programs1_4'], $_SEESION['join2']['programs_year1_4'], $_SEESION['join2']['programs1_5'], $_SEESION['join2']['programs_year1_5'], $_SEESION['join2']['programs1_6'], $_SEESION['join2']['programs_year1_6'] ]); session_destroy(); ?>

execute内に記述してますが、なんか違う気がします。

preview.phpでは
$arr = $SESSION['join2']['programs1'];
としてループさせているから記述量がすくないのですが、
echo $_SEESION['jion2']['programs1_1'];
echo $_SEESION['jion2']['programs_year1_1'];










とやろうと思えばできます。

でも、追加がどれくらい押されるか分からないので
「ある分」だけを表示させています。

これはthanks.phpにも同じことがいえて、
「ある分」だけを登録するようにしたい(そうすることで記述もスマートになる?)
のですが、どうすればよろしいでしょうか?

すいません、なんかごっちゃになってきて
確認画面では確認だから「ある分」だけを表示させればいいんですが
DB登録処理はあるない関わらず、「ない分」も用意しておかないといけませんね...

というのは、ユーザーがもう一個追加を押したら確認画面には追加分も表示されるでしょうが、
DB登録処理には
$_SEESION['join2']['programs1_7'],
$_SEESION['join2']['programs_year1_7']
を追加しなくてはなりませんから
そういう意味で「ない分」も記述しておく必要がありそうですね...

素人思考だと、
「ない分」を記述しておくのは非常に気持ち悪くて
それなら、preview.phpみたいに
$arr = $SESSION['join2']['programs1'];
というふうにしてせめてスマートな記述にしたいなと思って質問してみたのですが今回は無理がありそうですかね...?

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

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

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

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

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

masaya_ohashi

2016/06/20 01:19

user_skillのテーブル構成はどうなっているんですか?見た限りクエリの「?」の数とパラメータの数があっていませんが…
earnest_gay

2016/06/20 01:20

修正しました! お手数かけてすいません。 12個です。
masaya_ohashi

2016/06/20 01:22

これは最大で6スキル(スキル名と日付で12カラム)というテーブルという認識で正しいですか?
earnest_gay

2016/06/20 01:30

実際はかなりありますが、この質問では最大で6スキル(スキル名と日付で12カラム)というテーブルで正しいです。
masaya_ohashi

2016/06/20 01:50

カラムは必ず「スキル名」「日付」「スキル名」「日付」…の順で並んでいるという認識で正しいですか?あと、これスキルのテーブルにユーザIDが保存されていないので、あとから「これ誰のスキル表だよ」となりそうな気がしますが…
earnest_gay

2016/06/20 02:01

user_idというカラムはAIで設定しています。 厳密には user_id skill1 year1 skill2 year2 ・ ・ ・ ・ ・ ・ というテーブル構成にしています。 全体を話すと本質問内容が大きくなるので割愛しましたが 勿論、名前や住所の入力ページもあります。 user_data user_skill user_qualification user_pr 各4つのテーブルを用意していてユーザーデータを分類しています。 user_dataではAI付きのidを用意しているので user_skillもuser_qualificationもuser_prもuser_idは user_dataのidと紐つけられて だれのスキル だれの資格 だれのPR文 等の情報は識別できると思います。 本質問はその延長線上の質問です。
guest

回答2

0

ベストアンサー

テーブル構成等を考慮して、とりあえずのコードを書いてみました。テーブルのカラムが足りる分にはこれでどれだけ追加されても動くと思います。

「INSERT時にuser_idが入っていない」「全てのカラムのデータを渡すわけではないのでカラム名指定なしではINSERTできない」という問題もついでに直しています。ちなみに一度もテストしていないので正しく動く保証はありません。

PHP

1// executeに渡すためのパラメータ 2$inputParameters = array($user_id);// $user_idには登録するユーザのIDが入っているのものとする 3 4// SQL文でカラム名を列挙するための配列 5$columns = array("user_id"); 6 7// POSTされたprograms1_の数だけ繰り返す 8for($i=0;$i<count($_SEESION['join2']['programs1_']);$i++) { 9 10 // カラム名にスキル名、年を追加 11 $columns[] = "skill" . ($i+1); 12 $columns[] = "year" . ($i+1); 13 14 // パラメータにスキル名、年を追加 15 $inputParameters[] = $_SEESION['join2']['programs1_'][$i]; 16 $inputParameters[] = $_SEESION['join2']['programs_year1_'][$i]; 17} 18 19// パラメータの数だけ?を並べる 20$questions = str_repeat("?,", count($inputParameters)); 21// 末尾に,が残ってしまっているので削除 22$questions = substr($questions, 0, strlen($questions)-1); 23 24// SQL実行 25$stmt = $pdo->prepare("INSERT INTO user_skill(".implode(",", $columns).") VALUES (".$questions.")"); 26$stmt->execute($inpuiutParameters);

投稿2016/06/20 02:16

masaya_ohashi

総合スコア9206

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

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

masaya_ohashi

2016/06/20 02:18

こう書きましたが、そもそもuser_skillはuser_id,skill,yearの3カラムのレコードを複数持つ1:nのテーブル構成にすべきです。1件のユーザデータに対し、スキルデータはn件持つことができる仕様になっているので、カラム数で解決するのではなく、レコード数で解決すべきです。
earnest_gay

2016/06/20 02:22

そんなことまでできるなんて... これは理解するのに時間かかってしまいそうなので、 ゆっくり時間とれるときに試してみたいと思います! 記述いただきありがとうございます! また質問させてもらうかもしれませんが、 お時間ありましたらお付き合い頂けると幸いです。
earnest_gay

2016/06/20 02:28

>>1件のユーザデータに対し、スキルデータはn件持つことができる仕様になっているので、カラム数で解決するのではなく、レコード数で解決すべきです。 ということは、user_skillには skill1 year1 skill2 year2 ・ ・ ・ ・ ・ というように複数用意するのではなく、単純に user_id skill year でいいのでしょうか? 1 PHP 2年 JAVA 2年 JavaScript 3年 というような構造ではなく 1 PHP 2年 1 JAVA 2年 1 JavaScript 3年 というような感じでしょうか?
masaya_ohashi

2016/06/20 02:52

そう!そうです。その形であれば、たとえ100件のスキルがあってもカラムが200個になって管理がめんどくさくなることはないですよね?そして、1件しかスキルがない人が無駄に198個のカラムを空で持っている必要もないですよね?それがデータベースの正しい使い方です。1:nやn:nのテーブルが組めるようになれば初心者離脱です。
earnest_gay

2016/06/20 04:20 編集

なるほどです! でも それだと、「user_dataテーブルのid」と「user_skillテーブルでのuser_id」はどうやって紐づけるんです? 私がはじめに提案した 1 PHP 2年 JAVA 2年 JavaScript 3年 のような構造でしたら 登録された順にオートインクリメントで 「user_dataテーブルのid」と「user_skillテーブルでのuser_id」が紐づけられますが、 1 PHP 2年 1 JAVA 2年 1 JavaScript 3年 のような構造だった場合、 「user_skillテーブルでのuser_id」は オートインクリメントにしていたら ユニークな値ではなくなりますし、どうやって JAVA 2年 JavaScript 3年 もuser_idが1の人のスキルってわかるようにするんですか? 説明が下手ですが、1のような数字を毎回手入力で管理するほど面倒なことはないですよね?
masaya_ohashi

2016/06/20 04:38

もしかしてなんですが、各テーブルに全て同時にレコードを追加することでuser_idを一致させようとしていませんか? それは全くの間違いです。マスターとなるuser_dataテーブルのuser_idはオートインクリメントでよいですが、他のテーブルのuser_idは、user_data上の「誰のデータを指すか」を表すIDであり、各テーブルのオートインクリメントで済ませてよいものではありません。 仮にこのような順番で追加されたら整合性が取れませんよね? ・Aさんがuser_dataに追加(user_dataのオートインクリメントでuser_id=1) ・Bさんがuser_dataに追加(user_dataのオートインクリメントでuser_id=2) ・Bさんがuser_skillに追加(user_skillのオートインクリメントでuser_id=1) ・Aさんがuser_skillに追加(user_skillのオートインクリメントでuser_id=2) これだとAさんとBさんのスキルが逆になってしまいますよね? input.phpには本来「誰のスキルを入力するのか」というuser_idが渡されていなければなりません。そして、それをフォームのhiddenパラメータ等でpreview.php、thanks.phpに渡して、thanks.phpのINSERT処理に使うuser_idは、「誰のデータなのか」を示すために渡されたuser_idを使わなければなりません。
earnest_gay

2016/06/20 05:04 編集

>>各テーブルに全て同時にレコードを追加することでuser_idを一致させようとしていませんか? はい。当初はその様に考えていました。 本質問をして 1 PHP 2年 1 JAVA 2年 1 JavaScript 3年 のように1:nのような構造にするべきだということは理解しました。 この質問では登録フォームの記述はしていませんが、最終的には 下記のようにしてDBへ登録することになります。 $stmt = $pdo->prepare("INSERT INTO user_skill() VALUES (?, ?, ?, ?)"); $stmt->execute([ $_SEESION['jion2']['programs1_1'],//←PHPが入っている $_SEESION['jion2']['programs_year1_1'],//←1年が入ってる $_SEESION['jion2']['programs1_2'],//←JAVAが入ってる $_SEESION['jion2']['programs_year1_2'],//←2年が入ってる ]); ? PHP 1年 ? JAVA 2年 こうなると思います。 DBへ登録する際に「user_skillテーブルでのuser_id」を1にするためには どういう工夫というか、 どうすれば自動で「user_skillテーブルでのuser_id」を登録することができるのでしょうか? 「user_dataテーブルのid」にはオートインクリメントで自動的に数字が入っていきますが、 $stmt = $pdo->prepare("INSERT INTO user_skill() VALUES (?, ?, ?, ?)"); $stmt->execute([ $_SEESION['jion2']['programs1_1'],//←PHPが入っている $_SEESION['jion2']['programs_year1_1'],//←1年が入ってる $_SEESION['jion2']['programs1_2'],//←JAVAが入ってる $_SEESION['jion2']['programs_year1_2'],//←2年が入ってる ]); で登録したテーブルの各user_idを「user_dataテーブルのid」にするにはどうしたらいいのでしょうか? $stmt = $pdo->prepare("INSERT INTO user_skill() VALUES (?, ?, ?, ?)"); $stmt->execute([ $_SEESION['join1']['user_id'],//←登録しようとしている人のID $_SEESION['jion2']['programs1_1'],//←PHPが入っている $_SEESION['jion2']['programs_year1_1'],//←1年が入ってる $_SEESION['jion2']['programs1_2'],//←JAVAが入ってる $_SEESION['jion2']['programs_year1_2'],//←2年が入ってる ]); で登録しようとしたら 1 PHP 1年 JAVA 2年 というようになる気がするのですが $stmt = $pdo->prepare("INSERT INTO user_skill() VALUES (?, ?, ?, ?)"); $stmt->execute([ $_SEESION['join1']['user_id'],//←登録しようとしている人のID $_SEESION['jion2']['programs1_1'],//←PHPが入っている $_SEESION['jion2']['programs_year1_1'],//←1年が入ってる ]); $stmt = $pdo->prepare("INSERT INTO user_skill() VALUES (?, ?, ?, ?)"); $stmt->execute([ $_SEESION['join1']['user_id'],//←登録しようとしている人のID $_SEESION['jion2']['programs1_2'],//←JAVAが入ってる $_SEESION['jion2']['programs_year1_2'],//←2年が入ってる ]); と分割すればレコードを分けることができますか? 1 PHP 1年 1 JAVA 2年
earnest_gay

2016/06/20 07:57

出来るかどうかは分かりませんが、 思いつく方法としては下記が思いつきました。 $stmt = $pdo->prepare("INSERT INTO user_skill(user_id,skill,year) VALUES (?, ?, ?)"); $stmt->execute([ user_dataテーブルの一番新しい(番号が古い)id + 1, $_SESSION['jion2']['programs1_1'], $_SESSION['jion2']['programs_year1_1'], ]); $stmt = $pdo->prepare("INSERT INTO user_skill(user_id,skill,year) VALUES (?, ?, ?)"); $stmt->execute([ user_dataテーブルの一番新しい(番号が古い)id + 1, $_SESSION['jion2']['programs1_2'], $_SESSION['jion2']['programs_year1_2'], ]); $stmt = $pdo->prepare("INSERT INTO user_skill(user_id,skill,year) VALUES (?, ?, ?)"); $stmt->execute([ user_dataテーブルの一番新しい(番号が古い)id + 1, $_SESSION['jion2']['programs1_3'], $_SESSION['jion2']['programs_year1_3'], ]); これができれば常に 「user_skillテーブルでのuser_id」=「user_dataテーブルのid」 にできるのですが...
masaya_ohashi

2016/06/20 08:11 編集

2つ前のコメントにあるように、$_SESSIONの中にuser_idが入っているならそれを使うべきです。ちゃんと「?」とパラメータの数は一致させたうえで、ですが。
earnest_gay

2016/06/20 08:15

$_SESSIONの中にuser_idは入っていないです。 あると仮定して記述しています。
earnest_gay

2016/06/21 02:43

今朝の質問でこちらの質問も解決できました。 ありがとうございます!
guest

0

preview.phpの省略されている部分の中で$_SESSION['join2']に値を保存していることを前提でお話するとすれば、thanks.phpで参照しているのが**'jion2'**というスペルミスなので参照できていないのだと思います。

投稿2016/06/20 01:10

masaya_ohashi

総合スコア9206

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

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

earnest_gay

2016/06/20 01:11

すいません! 行き違いで質問内容大幅に変更させてもらいました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問