php5.5とAngularJSの質問です。

以下のページを参考にいろいろ試していますが、どうしても出来ないことがありますのでご助言いただければ幸いです。
http://qiita.com/naga3/items/cacb8182ad79dbbf6e64


1. サンプルのままだと、空白項目(入力しない項目)があると追加・更新ができません。
 補足に記したコードをphpファイルに追加すると追加更新できるのですが、inputタグが空白であるフィールドには0がセットされてしまいます。
 型がINT以外の型のフィールドnameやcommentを空白にして追加更新を試しても0がセットされます。
 入力しない項目に0がセットされず、かつ、入力しない項目があっても追加更新できる方法はありますか?


2. レコード追加のときにnameフィールドにはphpで取得したデフォルト値をセット表示させることは可能ですか?
 たぶんメチャメチャでしょうが雰囲気が伝わればと思い、試したコードは以下に添付しました。


文字数の関係で説明が足りないと思われる分や、試したコードは補足に書きました。
以上2点よろしくお願いします。

回答の条件
  • 1人1回まで
  • 13歳以上
  • 登録:2014/10/05 21:14:08
  • 終了:2014/10/07 11:35:19
id:wsapp

質問者から

wsapp2014/10/06 10:03:08

前回質問いたしまして、is_nullをセットすることでとりあえず更新できたのですが、その後いろいろ問題が生じました。
http://q.hatena.ne.jp/1411353627
それと前回の質問はフィールドを追加したことを伝えていませんで失礼いたしました。
今回はサンプルコードそのままです。
サンプルでは、更新や削除も読み込みも正常に動作します。
追加→更新の時だけ問題が生じます。



1. 入力しない項目に0がセットされず、かつ、入力しないでも追加更新できる方法はありますか?
で試したコード。
素人が調べた限りphp://inputではPOSTされたパラメーターを直接取得することはできないとどこかで見かけたので、インプットタグにセットされないパラメーターはnullで逃げたつもりでしたが、なぜか0がセットされます。

case 'PUT':
  // update
  $null_variable = NULL;
  $in = json_decode(file_get_contents('php://input'), true);
  $st = $pdo->prepare("UPDATE students SET name=:name,age=:age,comment=:comment WHERE id=:id");
  $st->bindParam(":name", $null_variable, PDO::PARAM_NULL);
  $st->bindParam(":age", $null_variable, PDO::PARAM_NULL);
  $st->bindParam(":comment", $null_variable, PDO::PARAM_NULL);
  @$st->execute($in);
  break;



2. レコード追加の際にデフォルト値をセットする
 本当にやりたいことは、例えば別なarea_idフィールドを設け、値をセットしたいのですが、とりあえずnameフィールドでテストしています。

case 'POST':
  // save
  $name = "massan";
//  $pdo->query("INSERT INTO students VALUES()");
  $pdo->query("INSERT INTO students (name) VALUES(:name)");
  $st->bindParam(':name', $name, PDO::PARAM_STR);
  $st = $pdo->query('SELECT LAST_INSERT_ID() AS id FROM students');
  echo json_encode($st->fetch(PDO::FETCH_ASSOC));
  break;

ベストアンサー

id:tobeoscontinue No.1

tobeoscontinue回答回数213ベストアンサー獲得回数522014/10/06 20:51:53

ポイント300pt

思うように動作しない場合、古いやりかたですが私は変数のデータがどうなっているかをvar_dumpやprint_rを使って調べるようにしています。ただ今回はechoなど標準出力が使えないのでファイルに出力するようにしました。
そのためローカルで開発していない場合、問題になるかもしれません。

<?php

$dfn = "log/debug.txt";

switch ($_SERVER['REQUEST_METHOD']) {
case 'GET':
  // query
  $st = $pdo->query("SELECT * FROM students");
  $json = json_encode($st->fetchAll(PDO::FETCH_ASSOC));
  file_put_contents($dfn, "query:".print_r($json, TRUE)."\n", FILE_APPEND);
  echo $json;
  break;
case 'POST':
  // save
  $name = 'massan';
  $pdo->query("INSERT INTO students (name) VALUES(\"".$name."\")");
//  $pdo->query("INSERT INTO students (name) VALUES(:name)");
  file_put_contents($dfn, "save:".implode('|', $pdo->errorInfo())."\n", FILE_APPEND);
  $st = $pdo->query('SELECT LAST_INSERT_ID() AS id, name, age, comment FROM students');
  $json = json_encode($st->fetch(PDO::FETCH_ASSOC));
  file_put_contents($dfn, "save:".print_r($json, TRUE)."\n", FILE_APPEND);
  echo $json;
  break;
case 'PUT':
  // update
  $in = json_decode(file_get_contents('php://input'), true);
  file_put_contents($dfn, "update:".print_r($in, TRUE)."\n", FILE_APPEND);
  $age = null;
  $st = $pdo->prepare("UPDATE students SET name=:name,age=:age,comment=:comment WHERE id=:id");
  $st->execute($in);
  file_put_contents($dfn, "update:".implode('|', $st->errorInfo())."\n", FILE_APPEND);
  break;
case 'DELETE':
  // delete
  $st = $pdo->prepare("DELETE FROM students WHERE id=?");
  $st->execute(array($_GET['id']));
  break;
}

$dfnは出力用のファイル名で適当なものを設定してください。logディレクトリーは書き込み権限が必要です。
file_put_contents($dfn, "内容", FILE_APPEND);で内容を書き込みます。
print_r($変数, TRUE)でTRUEを付加すると$変数の内容を文字列で受け取ることができます。

追加ボタンを押すとsave()が実行されstudents.phpのcase 'POST':の部分が実行されることになります。
デフォルト値を設定する場合はINSERT文のVALUES()で設定します。
index.html上で空白の一行が追加されますがidの部分に数字が出ない場合はstudents.phpのmysqlが動いていません。
$st = $pdo->query('SELECT LAST_INSERT_ID() AS id, name, age, comment FROM students');
でmysqlに追加されたものが返されるのですがオリジナルではidだけなのでnameにデフォルト値を設定しても反映されません。
name, age, commentを必要に応じて追加する必要があります。

更新ボタンを押すとupdate()が実行されstudents.phpのcase 'PUT':の部分が実行されることになります。
index.html上で変更された値はphp://inputを経由してmysqlへと反映されるのですがそのmysqlの値を返していないのでindex.html上とmysqlで値が異なる(ageに関して)ことになっています。(index.html上でageを空にしてもmysqlでは0になっている)
mysqlでageはINTとなっているので一度設定されてしまうとnullにはならないのではないでしょうか。
json上で"age":nullであればindex.htmlで0とはならないようです。


>2. レコード追加のときにnameフィールドにはphpで取得したデフォルト値をセット表示させることは可能ですか?
デフォルト値をセットする方法としてmysqlのCREATE TABLEのDEFAULT、students.php、controller.jsが考えられますが
wsappさんのようにstudents.phpでするのが融通がきくように思います。
ただ$pdo->query("INSERT INTO students (name) VALUES(:name)");
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ':name)' at line 1
のように:nameは使えないので
"INSERT INTO students (name) VALUES(\"".$name."\")"

"INSERT INTO students (name) VALUES(\"massan\")"
とする必要があります。

他1件のコメントを見る
id:tobeoscontinue

>前者の書き方は他のところで何か所も使っていますが問題なく動いています。
問題なく動いているように見えているだけで実際はmysql側は動いていないはずです。
$pdo->query("INSERT INTO students (name) VALUES(:name)");
の後で$pdo->errorInfo()で確認すると
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ':name)' at line 1
のエラーを確認できると思います。
:nameは名前付けされたプレースホルダで後で評価されるものです。一方queryはすぐ実行します。
名前付けされたプレースホルダを使うのであればqueryではなくprepareしてその後bindParamしてexecuteすることになります。

>SELECT文にWHERE以降を付け加えたら正常動作しているようです。
おっしゃる通りです。AS句はエイリアスだったんですねぇorz。
$st = $pdo->query('SELECT * FROM students WHERE id = LAST_INSERT_ID()');
カラムをすべて取り出すなら*の方が便利かと

2014/10/07 11:02:06
id:wsapp

解りましたー!
早速、他のPDOコードを見直してみます。
ありがとうございましたm(_ _)m

2014/10/07 11:53:26

その他の回答(0件)

id:wsapp

質問者から

wsapp2014/10/05 23:10:54

質問文を編集しました。詳細はこちら

id:tobeoscontinue No.1

tobeoscontinue回答回数213ベストアンサー獲得回数522014/10/06 20:51:53ここでベストアンサー

ポイント300pt

思うように動作しない場合、古いやりかたですが私は変数のデータがどうなっているかをvar_dumpやprint_rを使って調べるようにしています。ただ今回はechoなど標準出力が使えないのでファイルに出力するようにしました。
そのためローカルで開発していない場合、問題になるかもしれません。

<?php

$dfn = "log/debug.txt";

switch ($_SERVER['REQUEST_METHOD']) {
case 'GET':
  // query
  $st = $pdo->query("SELECT * FROM students");
  $json = json_encode($st->fetchAll(PDO::FETCH_ASSOC));
  file_put_contents($dfn, "query:".print_r($json, TRUE)."\n", FILE_APPEND);
  echo $json;
  break;
case 'POST':
  // save
  $name = 'massan';
  $pdo->query("INSERT INTO students (name) VALUES(\"".$name."\")");
//  $pdo->query("INSERT INTO students (name) VALUES(:name)");
  file_put_contents($dfn, "save:".implode('|', $pdo->errorInfo())."\n", FILE_APPEND);
  $st = $pdo->query('SELECT LAST_INSERT_ID() AS id, name, age, comment FROM students');
  $json = json_encode($st->fetch(PDO::FETCH_ASSOC));
  file_put_contents($dfn, "save:".print_r($json, TRUE)."\n", FILE_APPEND);
  echo $json;
  break;
case 'PUT':
  // update
  $in = json_decode(file_get_contents('php://input'), true);
  file_put_contents($dfn, "update:".print_r($in, TRUE)."\n", FILE_APPEND);
  $age = null;
  $st = $pdo->prepare("UPDATE students SET name=:name,age=:age,comment=:comment WHERE id=:id");
  $st->execute($in);
  file_put_contents($dfn, "update:".implode('|', $st->errorInfo())."\n", FILE_APPEND);
  break;
case 'DELETE':
  // delete
  $st = $pdo->prepare("DELETE FROM students WHERE id=?");
  $st->execute(array($_GET['id']));
  break;
}

$dfnは出力用のファイル名で適当なものを設定してください。logディレクトリーは書き込み権限が必要です。
file_put_contents($dfn, "内容", FILE_APPEND);で内容を書き込みます。
print_r($変数, TRUE)でTRUEを付加すると$変数の内容を文字列で受け取ることができます。

追加ボタンを押すとsave()が実行されstudents.phpのcase 'POST':の部分が実行されることになります。
デフォルト値を設定する場合はINSERT文のVALUES()で設定します。
index.html上で空白の一行が追加されますがidの部分に数字が出ない場合はstudents.phpのmysqlが動いていません。
$st = $pdo->query('SELECT LAST_INSERT_ID() AS id, name, age, comment FROM students');
でmysqlに追加されたものが返されるのですがオリジナルではidだけなのでnameにデフォルト値を設定しても反映されません。
name, age, commentを必要に応じて追加する必要があります。

更新ボタンを押すとupdate()が実行されstudents.phpのcase 'PUT':の部分が実行されることになります。
index.html上で変更された値はphp://inputを経由してmysqlへと反映されるのですがそのmysqlの値を返していないのでindex.html上とmysqlで値が異なる(ageに関して)ことになっています。(index.html上でageを空にしてもmysqlでは0になっている)
mysqlでageはINTとなっているので一度設定されてしまうとnullにはならないのではないでしょうか。
json上で"age":nullであればindex.htmlで0とはならないようです。


>2. レコード追加のときにnameフィールドにはphpで取得したデフォルト値をセット表示させることは可能ですか?
デフォルト値をセットする方法としてmysqlのCREATE TABLEのDEFAULT、students.php、controller.jsが考えられますが
wsappさんのようにstudents.phpでするのが融通がきくように思います。
ただ$pdo->query("INSERT INTO students (name) VALUES(:name)");
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ':name)' at line 1
のように:nameは使えないので
"INSERT INTO students (name) VALUES(\"".$name."\")"

"INSERT INTO students (name) VALUES(\"massan\")"
とする必要があります。

他1件のコメントを見る
id:tobeoscontinue

>前者の書き方は他のところで何か所も使っていますが問題なく動いています。
問題なく動いているように見えているだけで実際はmysql側は動いていないはずです。
$pdo->query("INSERT INTO students (name) VALUES(:name)");
の後で$pdo->errorInfo()で確認すると
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ':name)' at line 1
のエラーを確認できると思います。
:nameは名前付けされたプレースホルダで後で評価されるものです。一方queryはすぐ実行します。
名前付けされたプレースホルダを使うのであればqueryではなくprepareしてその後bindParamしてexecuteすることになります。

>SELECT文にWHERE以降を付け加えたら正常動作しているようです。
おっしゃる通りです。AS句はエイリアスだったんですねぇorz。
$st = $pdo->query('SELECT * FROM students WHERE id = LAST_INSERT_ID()');
カラムをすべて取り出すなら*の方が便利かと

2014/10/07 11:02:06
id:wsapp

解りましたー!
早速、他のPDOコードを見直してみます。
ありがとうございましたm(_ _)m

2014/10/07 11:53:26
  • id:Lhankor_Mhy
    確認させてほしいのですが、データを空白にした時に以下の動作になるということでいいですか?
     
    サンプルコード
    ・追加→更新 登録できない
    ・更新 nullで登録される

    補足にあるコード
    ・追加→更新 0で登録される
    ・更新 nullで登録される
  • id:wsapp
    コメントありがとうございますm(_ _)m
    おっしゃる通りです。
    すこし厳密に書きますと・・・


    サンプルコード
    ・追加→更新
      追加で新idが振られ他のフィールドはnullのレコード追加
      空白項目があると更新失敗、id以外nullのまま変わらず
      項目が全部埋まっていると更新成功
    ・リロード後更新のみ
      空白項目があっても更新成功
      触らない項目はnullのまま、一度値を入力しようとし取り消し後に更新を押すと、型がINTは0、VARCHARやTEXTは""へと更新


    補足にあるコード
    ・追加→更新
      追加で新idが振られ他のフィールドはnullのレコード追加は、サンプルコードと同じ
      入力した値があるとその値が反映され、入力しない項目は型に関係なく0でアップデート
    ・リロード後更新のみ
      サンプルコードと挙動は同じ


    よろしくお願いします。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません