jackytom
@jackytom

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

PHPで配列が正しく取得できない(その2)

Q&A

Closed

の続きになります。

やりたいこととしては、submitしても値が消えないように、optionタグに「selected」を追加することです。

しかしながら、上手いきません。

自分なりに調査したところ、配列が上手く取得できていないことがわかりました。
関係する配列をvar_dumpしてみました。

219から220行目

<?php var_dump($item);?>
<?php var_dump($optionData);?>

結果は下記です。
1件ずつなのは、ご回答いただいた通りforeachで初期化しているためです。

; string(42) "瞳セラピー" array(5) { ["option_id"]=> int(3) ["option_name"]=> string(15) "瞳セラピー" ["price"]=> int(2000) ["level"]=> int(1) ["status"]=> int(0) }

$itemは、$_POST[item]の値なので、「3」が期待値です。しかし「瞳セラピー」を取得しています。
$itemと、$optionData['optin_id']が一致したら、「selected」とするようにしたいために下記の記述をしています。

153行目

if(isset($button) && $item == $optionData['option_id'])

しかしながら、$itemが「瞳セラピー」となってしまっているため、一致せずに上手くいかないものと考えています。

$issetが「3」にならない原因究明に協力いただければ幸いです。
全体ソースを添付します。

<?php
	session_start();
	header('Expires:-1');
	header('Cache-Control:');
	header('Pragma:');
		$token = '';
		if ( isset( $_SESSION[ 'token' ] ) || !empty( $_SESSION[ 'token' ] ) ) {
				$token = $_SESSION['token'];
				} else {
					$token = bin2hex(random_bytes(32));
					$_SESSION['token'] = $token;
					}
	
	function escape($val)
	{
		return htmlspecialchars($val, ENT_QUOTES | ENT_HTML5, 'UTF-8');
	}

	require_once('db_connect.php');

	$button = $_POST['button_culculate'] ?? '';
	$reserveDate = $_POST['reserve_date'] ?? '';
	$timeZone = $_POST['time_zone'] ?? '';
	$serviceId = $_POST['service_id'] ?? '';
	$servicePrice = $_POST['service_price'] ?? '';
	//$optionPrice = $_POST['option_price'] ?? '';
	$item = $_POST['item'] ?? '';
?>

<html lang=ja>
	<head>
		<meta charset="utf-8">
		<title>予約登録画面</title>
		<meta name="description" content="ヘッドセラピーを中心としたセラピーのサービスを提供しております。">
		<!--リセットcss-->
		<link rel="stylesheet" href="https://unpkg.com/ress/dist/ress.min.css">
		<!--css-->
		<link href="css/reserve_style.css" rel="stylesheet">
		<!--レスポンシブ対応-->
		<meta name="viwport" content="width=device-width, initial-scale=1">
		<!--Googleフォント-->
		<link href="https://fonts.googleapis.com/css2?family=Sawarabi+Gothic&display=swap" rel="stylesheet">
		<link href="https://fonts.googleapis.com/css2?family=Shippori+Mincho:wght@500&display=swap" rel="stylesheet">
	</head>
	<body>
		<?php require_once('header.php')?>
		<h1 class="title">予約登録画面</h1>
		<h2 class="sub">(確認のクリック前に金額計算をクリックします。)</h2>
		<form method="post" name="reserve" class="reserve" id="reserve" action="?">
			<div class="last_name">
				<label for="sei"></label>
				<input type="text" name="sei" class="sei" id="sei" value=
				"<?php
					if(isset($_SESSION['customer'])){
						echo $_session['customer']['last_name'];
					}
				?>"
				<?php
					if(isset($_SESSION['customer'])){
						echo 'readonly="readonly"';
					}
				?>
				>
			</div>
			<div class="mei">
				<label for="mei"></label>
				<input type="text" name="mei" class="mei" id="mei" value=
				"<?php
					if(isset($_SESSION['customer'])){
						echo $_session['customer']['first_name'];
					}
				?>"
				<?php
					if(isset($_SESSION['customer'])){
						echo 'readonly="readonly"';
					}
				?>
				>
			</div>
			<div class="r_date">
				<label for="reserve_date">予約日</label>
				<input type="date" name="reserve_date" class="reserve_date" id="reserve_date" value="<?="$reserveDate"?>">
			</div>
			<div class="time">
				<label for="time_zone">時間帯</label>
				<select name="time_zone" class="time_zone" id="time_zone">
					<?php
						$sql = ('select * from time_zone where status = :status1 or status = :status2 order by level');
						$stmt = $pdo->prepare($sql);
						$stmt -> bindValue(':status1',0);
						$stmt -> bindValue(':status2',2);
						$stmt -> execute();
						$time = $stmt->fetchAll(PDO::FETCH_ASSOC);

						foreach($time as $timeData){
							if(isset($button) && $timeData['time_zone_id'] == $timeZone){
	    						$zone = "";
								$zone .= "<option value='" . $timeData['time_zone_id'];
	    						$zone .= "' selected>" . $timeData['time_zone'];
	    						$zone .= "</option>"; 
	    						echo $zone;
    							} else {
									$zone = "";
									$zone .= "<option value='" . $timeData['time_zone_id'];
			    					$zone .= "'>" . $timeData['time_zone'];
			    					$zone .= "</option>";
		    						echo $zone;
		    						}

    					}
					?>
				</select>
			</div>
			<div class="service">
				<label for="servise_id">サービス</label>
				<select name="service_id" class="service_id" id="service_id">
					<?php
						$sql = ('select * from service where status = :status');
						$stmt = $pdo->prepare($sql);
						$stmt -> bindValue(':status',0);
						$stmt -> execute();
						$service = $stmt->fetchAll(PDO::FETCH_ASSOC);
						
						foreach($service as $serviceData):
    						if(isset($button) && $serviceId == $serviceData['service_id']){
								$serviceTitle = "";
								$serviceTitle .= "<option value='" . $serviceData['service_id'];
	    						$serviceTitle .= "'selected>". $serviceData['service_name'] . "</option>";
	    						echo $serviceTitle;
	    						} else {
	    								$serviceTitle = "";
										$serviceTitle .= "<option value='" . $serviceData['service_id'];
			    						$serviceTitle .= "'>". $serviceData['service_name'] . "</option>";
			    						echo $serviceTitle;
	    							}
						endforeach;

					?>
				>
				</select>
			</div>
			<div class="option">
				<label for="item">オプション</label>
				<select name="item" class="item" id="item">
					<?php
						$sql = ('select * from `option` where status = :status');
						$stmt = $pdo->prepare($sql);
						$stmt -> bindValue(':status',0);
						$stmt -> execute();
						$option = $stmt->fetchAll(PDO::FETCH_ASSOC);
						
						foreach($option as $optionData):
							if(isset($button) && $item == $optionData['option_id']){
								$item = "";
								$item .= "<option value='" . $optionData['option_id'];
	    						$item .= "'selected>" . $optionData['option_name'] . "</option>";
	    						echo $item;
    						} else {
    							$item = "";
								$item .= "<option value='" . $optionData['option_id'];
	    						$item .= "'>" . $optionData['option_name'] . "</option>";
	    						echo $item;
    							}

						endforeach;
					?>
				</select>
			</div>
			<div class="price_1">
				<label for="servise_price">金額(サービス)(表示のみ)</label>
				<input type=text name="service_price" id="service_price" readonly="readonly" value=
					"<?php
					if(isset($button)){
							$sql = ('select * from service where service_id = ?');
							$stmt = $pdo->prepare($sql);
							$stmt -> execute([escape($serviceId)]);
							$sPrice = $stmt->fetchAll(PDO::FETCH_ASSOC);
							}
							
							foreach($sPrice as $sPriceData){
								echo $sPriceData['price'];
								$price1 = $sPriceData['price'];
								$priceFir = json_encode($price1);
							}
						?>"
						?>

			</div>
			<div class="price_2">
				<label for="option_price">金額(オプション)(表示のみ)</label>
				<input type=text name="option_price" id="option_price" readonly="readonly" value=
					"<?php
						if(isset($button)){
							$sql = ('select * from `option` where option_id = ?');
							$stmt = $pdo->prepare($sql);
							$stmt -> execute([escape($item)]);
							$option = $stmt->fetchAll(PDO::FETCH_ASSOC);
							
							foreach($option as $item):
								echo $item['price'];
								$price2 = $item['price'];
								$priceSec = json_encode($price2);
							endforeach;
						}
					?>"
					>
			</div>
			<div class="total" id="total">
				<label for="total_amount">合計金額(表示のみ)</label>
				<input type=text name="total_amount" class="total_amount" id="total_amount">
			</div>
			<div class="buttons">
				<button type="button" class="button_b" name="button_re" id="button_re" onclick="history.back()">戻る</button>
				<button type="submit" form="reserve" class="button_b" name="button_culculate" id="button_commit" value="calculate">金額計算</button>
 				<button type="submit" class="button_b" name="button_conf" id="button_commit" formaction="reserve_conf.php" value="confirm">確認</button>
			</div>
		</form>
	<?php require_once('js/reserve_total_cal_js.php')?>;
	<?php var_dump($item);?>
	<?php var_dump($optionData);?>
	</body>
	<?php require_once('footer.php')?>
</html>
0

2Answer

変数 $item の使いまわしが原因ではないでしょうか?

	$item = $_POST['item'] ?? ''; //← POST内容から取得

... 中略

						foreach($option as $optionData):
							if(isset($button) && $item == $optionData['option_id']){  // ←ループ1周目はPOST内容が入っている
								$item = "";
								$item .= "<option value='" . $optionData['option_id'];
	    						$item .= "'selected>" . $optionData['option_name'] . "</option>";
	    						echo $item; // ←ループ2周目以降はこちら
    						} else {
    							$item = "";
								$item .= "<option value='" . $optionData['option_id'];
	    						$item .= "'>" . $optionData['option_name'] . "</option>";
	    						echo $item; // ←またはこちら(ループ2周目以降)
    						}

... 中略

	<?php var_dump($item);?> <!-- ← $optionDataが1件でも存在すれば、POST内容とは異なっている -->

var_dump の結果が string(42) "瞳セラピー" ["option_name"]=> string(15) "瞳セラピー" なのも

string(15) "瞳セラピー"
string(42) "<option value='x'>瞳セラピー</option>" //"瞳セラピー" 以外で合計27文字

だったりしませんかね

1Like

下記の抜粋したコードを参照してください。
①でPOSTされたデータを$itemに格納していますが、②でそれを上書きしています。
var_dump($item)の結果であるstring(42) "瞳セラピー"は一見すると「瞳セラピー」だけに見えますが、長さが42あるので<option>などが含まれてそうです。この点からも②の部分で上書きされていると考えられます。
恐らく最初のループで$item == $optionData['option_id']を比較する際は想定された値になっているのではないでしょうか?

さらにいうと、var_dumpするまでに「金額(オプション)(表示のみ)」の部分③でも上書きされる可能性があります。
同じ変数名を使い回すとこうしたトラブルを招くので、用途に合った命名にすることをお勧めしますよ。

$item = $_POST['item'] ?? ''; // ①

foreach($option as $optionData):
    if(isset($button) && $item == $optionData['option_id']){
	    $item = ""; // ②
	    $item .= "<option value='" . $optionData['option_id'];
	    $item .= "'selected>" . $optionData['option_name'] . "</option>";
	    echo $item;
	} else {
	    $item = ""; // ②
	    $item .= "<option value='" . $optionData['option_id'];
	    $item .= "'>" . $optionData['option_name'] . "</option>";
	    echo $item;
    }
endforeach;

if(isset($button)){
    $sql = ('select * from `option` where option_id = ?');
    $stmt = $pdo->prepare($sql);
    $stmt -> execute([escape($item)]);
    $option = $stmt->fetchAll(PDO::FETCH_ASSOC);
							
    foreach($option as $item): // ③
        echo $item['price'];
        $price2 = $item['price'];
        $priceSec = json_encode($price2);
    endforeach;
}

var_dump($item);
0Like

Comments

  1. @jackytom

    Questioner

    @blue32aさん
    @PECMMさん

    ありがとうございました。
    該当箇所まで丁寧にご指摘いただき、大変助かりました。
    今後、配列の使いまわしに注意してソースを記述します。
    今後とも、よろしくお願いいたします。

Your answer might help someone💌