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

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

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

POSTはHTTPプロトコルのリクエストメソッドです。ファイルをアップロードしたときや入力フォームが送信されたときなど、クライアントがデータをサーバに送る際に利用されます。

PHP

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

バリデーション

Validationとは特定の入力データが、求められた条件に当てまっているかをチェックするために使われます。

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

Q&A

解決済

2回答

515閲覧

PHP ユーザー関数定義を使用した入力フォームのバリデーションチェック

1h_m

総合スコア19

POST

POSTはHTTPプロトコルのリクエストメソッドです。ファイルをアップロードしたときや入力フォームが送信されたときなど、クライアントがデータをサーバに送る際に利用されます。

PHP

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

バリデーション

Validationとは特定の入力データが、求められた条件に当てまっているかをチェックするために使われます。

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

0グッド

1クリップ

投稿2020/03/18 03:31

現在PHPで図鑑投稿アプリを作成しています。
生き物の写真とその生き物の名前、分類、説明を投稿できるアプリです。

create.phpにて、

-new.phpでPOSTされてきたユーザーの入力値を$pbookに渡す。
-入力値のバリデーションチェックを行う

この2点をfunction.phpで定義したユーザー関数を使用して実装を試みています。
うまくいかず手詰まりになってしまいました。
変数のスコープや引数の設定に問題があるのかと考えましたが、解決に至りそうにないので質問しました。
解決策やヒントをご教授していただきたいです。よろしくお願いいたします。

実現したい事
-POSTされてきた入力値が空欄もしくは文字数オーバーなど不備がある場合のみ、$errorの各項目に'blank','length','type'の値を渡し、エラー文を出力する。

発生している問題点
-POSTされてきた入力値にかかわらず$error配列全てに'blank'の値が渡ってしまう

以下が該当のコードです。

function.php

php

1<?php 2function h($str){ 3 echo htmlspecialchars($str, ENT_QUOTES, 'UTF-8'); 4} 5 6function hbr($str){ 7 echo nl2br(htmlspecialchars($str, ENT_QUOTES, 'UTF-8')); 8} 9 10function optionLoop($start, $end, $selection=''){ 11 echo '<option value="">選択してね</option>'; 12 for($i=$start; $i<=$end; $i++){ 13 $i = sprintf('%02d', $i); 14 $selected = $i==$selection?'selected':''; 15 echo "<option value=\"{$i}\" $selected>{$i}</option>"; 16 } 17} 18 19function emptyError(){ 20 $error = ['sp_name'=>'', 'team'=>'', 'picture'=>'', 'description'=>'']; 21 return $error; 22} 23 24function hasError($error) { 25 return $error['sp_name'] != '' 26 || $error['team'] != '' 27 || $error['picture'] != '' 28 || $error['description'] != ''; 29} 30 31function assignmentPost(){ 32 $pbook['user_id'] = $_POST['user_id'] ?? ''; 33 $pbook['sp_name'] = $_POST['sp_name'] ?? ''; 34 $pbook['team'] = $_POST['team'] ?? ''; 35 $pbook['picture'] = $_FILES['picture']['name'] ?? ''; 36 $pbook['description'] = $_POST['description'] ?? ''; 37 return $pbook; 38} 39// 40function validatePbook($p){ 41 $error = emptyError(); 42 // $pbook = $_POST; 43 // $pbook = assignmentPost(); 44 if(isset($pbook['sp_name']) == ''){ 45 $error['sp_name'] = 'blank'; 46 }elseif(mb_strlen($pbook['sp_name']) > 50){ 47 $error['sp_name'] = 'length'; 48 } 49 if(isset($pbook['team']) == ''){ 50 $error['team'] = 'blank'; 51 } 52 if(isset($pbook['picture']) == ''){ 53 $error['picture'] = 'blank'; 54 }else{ 55 $filename = $pbook['picture']; 56 if(!empty($filename)){ 57 $ext = substr($filename, -3); 58 if($ext != 'jpg' && $ext != 'JPG' && $ext != 'png'){ 59 $error['picture'] = 'type'; 60 } 61 } 62 } 63 if(isset($pbook['description']) == ''){ 64 $error['description'] = 'blank'; 65 } 66 return $error; 67} 68

create.php

php

1<?php 2session_start(); 3require_once __DIR__ . '/vendor/autoload.php'; 4 5error_reporting(E_ALL); 6require_once ('db_connect.php'); 7require_once('function.php'); 8require_once('init.php'); 9$message = "入力エラーがあります"; 10 11 12 if($_SERVER['REQUEST_METHOD'] != 'POST'){ 13 header('Location:room.php'); 14 exit; 15 } 16 $pbook = assignmentPost(); 17 18 $error = validatePbook($pbook); 19 20 if($_SESSION['id'] != '' || hasError($error)){ 21 logD($pbook, 'pbook'); 22 logD($error, 'error'); 23 require_once('new.tpl.php'); 24 exit; 25 } 26 27 //$errorに値が一つも入っていなければDBに接続する 28 if(!isset($error)){ 29 $picture = date('YmdHis') . $_FILES['picture']['name']; 30 move_uploaded_file($_FILES['picture']['tmp_name'], '/Applications/XAMPP/xamppfiles/htdocs/pbook/files/'.$picture); 31 32 //入力内容をDBに保存する 33 34 $sql = 'INSERT INTO picture (sp_name, team, picture, description, user_id) 35 VALUES (:sp_name, :team, :picture, :description, :user_id)'; 36 $stmt = $pdo->prepare($sql); 37 $stmt->bindValue(':sp_name', $pbook['sp_name'], PDO::PARAM_STR); 38 $stmt->bindValue(':team', $pbook['team'], PDO::PARAM_STR); 39 $stmt->bindValue(':picture', $pbook['picture'], PDO::PARAM_STR); 40 $stmt->bindValue(':description', $pbook['description'], PDO::PARAM_STR); 41 $stmt->bindValue(':user_id', $pbook['user_id'], PDO::PARAM_INT); 42 $stmt->execute(); 43 44 45 $pdo = null; 46 $stmt = null; 47 48 $team = $pbook['team']; 49 $url = "{$team}/index.php"; 50 header('Location:'.$url); 51 exit(); 52 }

new.php

php

1<?php 2session_start(); 3require_once('function.php'); 4$pbook = ['id'=>'', 'sp_name'=>'', 'picture'=>'', 'description'=>'', 5 'team'=>'', 'user_id'=>'']; 6 7if(!isset($_SESSION['id'])){ 8 $_SESSION['return_uri'] = "http://localhost/pbook/new.php"; 9 header('Location:login/login.php'); 10 exit; 11} 12 13if(isset($_SESSION['id']) && ($_SESSION['time']) + 3600 > time()){ 14 15$message = "図鑑登録"; 16require_once ('new.tpl.php'); 17var_dump($member); 18} 19

new.tpl.php

php

1<!DOCTYPE html> 2<html> 3<?php include('header_inc.php') ?> 4<body> 5 6<h2><?php h($message) ; ?></h2> 7 <p></p> 8<form action="create.php" method="post" enctype="multipart/form-data"> 9 <input type="hidden" name="user_id" value="<?php echo $_SESSION['id']; ?>"> 10 <label>種名</label> 11 <input type="text" name="sp_name" value="<?php if(isset($pbook['sp_name'])){ echo $pbook['sp_name'];}?>"> 12 <?php if(isset($error['sp_name']) && $error['sp_name'] == 'blank'): ?> 13 <p>*種名を登録してください*</p> 14 <?php endif; ?> 15 <?php if(isset($error['sp_name']) && $error['sp_name'] == 'length'): ?> 16 <p>*種名は50文字以内で登録してください*</p> 17 <?php endif; ?> 18 <label></label> 19 <select name="team"> 20 <option value="">選んでね</option> 21 <option value="sea"<?php if(isset($pbook['team']) && $pbook['team'] == 'sea'){echo 'selected';} ?>></option> 22 <option value="kinoko"<?php if(isset($pbook['team']) && $pbook['team'] == 'kinoko'){echo 'selected';} ?>>きのこ</option> 23 <option value="plant"<?php if(isset($pbook['team']) && $pbook['team'] == 'plant'){echo 'selected';} ?>>植物</option> 24 </select> 25 26 <?php if(isset($error['team']) && $error['team'] == 'blank'): ?> 27 <p>*班を選んでください*</p> 28 <?php endif; ?> 29 <p></p> 30 <label>写真</label> 31 <input type="file" name="picture" /> 32 <p></p> 33 <?php if(isset($error['picture']) && $error['picture'] == 'blank'): ?> 34 <p>*写真を登録してください*</p> 35 <?php endif; ?> 36 <?php if(isset($error['picture']) && $error['picture'] == 'type'): ?> 37 <p>*写真は「.gif」もしくは「.png」の形式で登録してください*</p> 38 <?php endif; ?> 39 <?php if(!isset($error['picture']) && !empty($error)): ?> 40 <p>*もう一度写真を登録してください*</p> 41 <?php endif; ?> 42 <label>説明</label> 43 <!-- name属性は$_POSTのキーとなる。$_POST['description'] --> 44 <textarea name="description" cols="40" row="80"><?php if(isset($pbook['description'])){ echo $pbook['description'];}?></textarea> 45 <p></p> 46 <?php if(isset($error['description']) && $error['description'] == 'blank'): ?> 47 <p>*説明を登録してください*</p> 48 <?php endif; ?> 49 <input type="submit" name="submit" value="登録する"> 50</form> 51 <p><a href="room.php">班一覧に戻る</a></p> 52 <?php if(isset($_SESSION)): ?> 53 <p><a href="login/logout.php">ログアウトする</a></p> 54 <?php endif; ?> 55 56<?php include('footer_inc.php') ?> 57</body> 58</html>

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

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

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

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

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

guest

回答2

0

この構成ならきちんとクラスを組んで、出力はテンプレートを作ってやるとよいでしょう。
ユーザーの入力をバリデーションするならfilter_inputするのが楽です

投稿2020/03/18 04:05

yambejp

総合スコア114843

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

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

1h_m

2020/03/19 02:21

回答ありがとうございます。 今回はvalidatePbookの引数を$pから$pbookに修正し、関数内のissetを除くことで解決できました。 まだ関数化のところで知識がおぼつかない状態でしたので、クラスを組んでの実装はまだ挑戦していないのですが次回はチャレンジしてみます。 確かにfilter_inputは便利そうなので次回は使ってみます。 新しい視点をくださりありがとうございました。
guest

0

ベストアンサー

変数のスコープや引数の設定に問題があるのかと考えましたが、解決に至りそうにないので質問しました。
解決策やヒントをご教授していただきたいです。よろしくお願いいたします。

まずは現状で各箇所の変数がどうなっているかを確認してデバッグしてください。
多分今回の場合だと

PHP

1function validatePbook($p){ 2 $error = emptyError(); 3 // $pbook = $_POST; 4 // $pbook = assignmentPost(); 5 var_dump($pbook); 6 die(); 7 if(isset($pbook['sp_name']) == ''){ 8 $error['sp_name'] = 'blank'; 9

とすれば、blankを代入している直前の$pbookを確認できます。
想定していたものと違う値が入っていたら、それより前に遡って同じように確認していく。
というのを積み上げていけば想定した通りに動くようになります。


環境が不明なのでどこでも使えるvar_dump()によるデバッグを回答しましたが
var_dump()によるデバッグはソースコードを汚すなどの弊害や限界があるので、
リモートデバッグ環境を作ってブレークポイントを仕掛ける方が良いです。
余裕が出来たら
PHP リモートデバッグ xdebugといったキーワードに使用しているエディタやIDEをキーワードに追加して検索してみてください。

投稿2020/03/18 04:01

編集2020/03/19 02:20
tanat

総合スコア18713

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

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

1h_m

2020/03/19 02:14

回答してくださりありがとうございます。 順に値を確認していき、validatePbookの引数が$pとしていましたがこれが間違いだと気づき$pbookに修正しました。また関数内でissetの使用は不適切でしたので取り除いたところ想定通りの値が渡ってくれました。 リモートデバッグにも挑戦してみようと思います。 順を追ってどの場所でデバッグするか、とても大事なことを教えていただきました。ありがとうございました。
tanat

2020/03/19 02:26

修正箇所のフィードバックありがとうございます。 解決して良かったです。 開発のうち、多くの時間はデバッグやテストで使われるというのは普通のことなので、 デバッグやのやり方を色々試してみるのも良いかもしれませんね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問