@Tarzan3154

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

MySQLで検索機能(PHP)

解決したいこと

MySQLで作成した検索機能をPHPで表示させるプログラムを作っています。
下記のようにmysqliでプレースホルダを指定しようとして、
devices.phpを出力した際にFatal errorが出てしまい、mysqliが未定義となってしまうのですが、
どのように修正すればよろしいでしょうか?
また、検索結果を表示させる構文についても何かヒントをご教示いただけると助かります。
よろしくお願い致します。

発生している問題・エラー

Warning: Undefined variable $mysqli in C:\xampp\htdocs\test\devices.php on line 9

Fatal error: Uncaught Error: Call to a member function prepare() on null in C:\xampp\htdocs\test\devices.php:9 Stack trace: #0 {main} thrown in C:\xampp\htdocs\test\devices.php on line 9

DBの定義

CREATE TABLE `devices` (
  `device_name` char(9) NOT NULL,
  `serial_number` varchar(9) NOT NULL,
  `manufacturer` varchar(9) NOT NULL COMMENT 'メーカー名 1:FUJITSU 2:Microsoft',
  `model` varchar(32) NOT NULL,
  `os` char(7) NOT NULL DEFAULT 'Windows',
  PRIMARY KEY (`device_name`),
  UNIQUE KEY `serial_number` (`serial_number`),

該当するソースコード

devices.php

<?php
//①データ取得ロジックを呼び出す
include_once('model.php');
$Mysqli = getDeviceData($_GET);

// ここでSQL文を作成する
$sql = "SELECT * from devices where device_name = ? and serial_number = ? and manufacturer = ? and model = ? and os = ?";
// SQL文を$stmt オブジェクトに紐付ける
if ($stmt = $Mysqli->prepare($sql)) {

// プレースホルダと変数を結びつける
$stmt->bind_param('sssss', $device_name, $serial_number, $manufacturer, $model, $os);

// 実行する
$stmt->execute();

// 取得した値を変数に結びつける
$stmt->bind_result($device_name);

// 結びつけた変数に取得した値をセットする。
$stmt->fetch();

// クローズする
$stmt->close();

/* 接続を閉じます */
$Mysqli->close();
}
?>


<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>端末テーブル表示</title>
<link rel="stylesheet" href="style.css">
<!-- Bootstrap読み込み(スタイリングのため) -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.0/css/bootstrap.min.css">
</head>
<body>
<div class="flex_test-box">
    <div class="flex_test-item">
		<h1 class="col-xs-6 col-xs-offset-3">端末テーブル</h1>
    </div>
</div>
<h3 class="col-xs-6 col-xs-offset-3">検索フォーム</h3>
<div class="col-xs-6 col-xs-offset-3 well">
	
	<?php //②検索フォーム ?>
	<form method="get">
		<div class="form-group">
			<label for="InputDevice_name">端末名</label>
			<input name="device_name" class="form-control" id="InputDevice_name" value="<?php echo isset($_GET['device_name']) ? htmlspecialchars($_GET['device_name']) : '' ?>">
		</div>
		<div class="form-group">
			<label for="InputSerial_number">シリアル</label>
			<input name="serial_number" class="form-control" id="InputSerial_number" value="<?php echo isset($_GET['serial_number']) ? htmlspecialchars($_GET['serial_number']) : '' ?>">
		</div>
		<div class="form-group">
			<label for="InputManufacturer">メーカー</label>
			<select name="manufacturer" class="form-control" id="InputManufacturer">
				<option value="0" <?php echo empty($_GET['manufacturer']) ? 'selected' : '' ?>>選択しない</option>
				<option value="1" <?php echo isset($_GET['manufacturer']) && $_GET['manufacturer'] == '1' ? 'selected' : '' ?>>FUJITSU</option>
				<option value="2" <?php echo isset($_GET['manufacturer']) && $_GET['manufacturer'] == '2' ? 'selected' : '' ?>>Microsoft</option>
			</select>
		</div>
		<div class="form-group">
			<label for="InputModel">品名/型番</label>
			<select name="model" class="form-control" id="InputModel">
				<option value="0" <?php echo empty($_GET['model']) ? 'selected' : '' ?>>選択しない</option>
				<option value="1" <?php echo isset($_GET['model']) && $_GET['model'] == '1' ? 'selected' : '' ?>>Surface Laptop Go</option>
				<option value="2" <?php echo isset($_GET['model']) && $_GET['model'] == '2' ? 'selected' : '' ?>>ARROWS Tab Q5010/EEG(FARQ25045Z)</option>
				<option value="3" <?php echo isset($_GET['model']) && $_GET['model'] == '3' ? 'selected' : '' ?>>ARROWS Tab Q509/VE(FARQ22014)</option>
				<option value="4" <?php echo isset($_GET['model']) && $_GET['model'] == '4' ? 'selected' : '' ?>>ARROWS Tab Q508/SE(FARQ18011)</option>
				<option value="5" <?php echo isset($_GET['model']) && $_GET['model'] == '5' ? 'selected' : '' ?>>ARROWS Tab Q507/PE(FARQ14011)</option>
			</select>
		</div>
		<div class="form-group">
			<label for="InputOs">OS</label>
			<input type="os" class="form-control" id="InputOs" value="Windows">
		</div>
		<button type="submit" class="btn btn-default" name="search">検索</button>
	</form>

</div>
<div class="col-xs-6 col-xs-offset-3">
	<?php //③取得データを表示する ?>

	<?php if(isset($deviceData) && count($deviceData)): ?>
		<p class="alert alert-success"><?php echo count($deviceData) ?>件見つかりました。</p>
		<table class="table">
			<thead>
				<tr>
					<th>端末名</th>
					<th>シリアル</th>
					<th>メーカー</th>
					<th>品名/型番</th>
					<th>OS</th>
				</tr>
			</thead>
			<tbody>
				<?php foreach($deviceData as $row): ?>
					<tr>
						<td><?php echo htmlspecialchars($row['device_name']) ?></td>
						<td><?php echo htmlspecialchars($row['serial_number']) ?></td>
						<td><?php echo htmlspecialchars($row['manufacturer'] == 1 ? 'FUJITSU' : 'Microsoft') ?></td>
						<td><?php echo htmlspecialchars($row['model'] ) ?></td>
						<td><?php echo htmlspecialchars($row['os']) ?></td>
					</tr>
				<?php endforeach; ?>
			</tbody>
		</table>
	<?php else: ?>
		<p class="alert alert-danger">検索対象は見つかりませんでした。</p>
	<?php endif; ?>

	

</div>
</body>
</html>
model.php

<?php
function getDeviceData(){

	//DBコネクタを生成
	$Mysqli = new mysqli('localhost', 'root', '', 'deviceswithinventory');
	if ($Mysqli->connect_error) {
		error_log($Mysqli_connect_error);
		exit;
	}
	//戻り値として$Mysqiを呼び出し元に返す
	return $Mysqli;
}
?>
config\databases.php

<?php

//DBの接続情報
$host = "localhost";
$username = "root";
$password = "";
$dbname = "deviceswithinventory";

自分で試したこと

Mysqli(プリペアドステートメント~execute)の箇所の構文をdevices.phpからmodel.phpに転記させても結果変わりませんでした。

0 likes

3Answer

そのスコープに$mysqliなる変数はありません.
適切な場所で宣言してください.

0Like

Comments

  1. @Tarzan3154

    Questioner

    ご回答ありがとうございます。
    model.phpに記述した

    $Mysqli = new mysqli~

    とは別に$mysqliの変数宣言が必要ということでしょうか。
    (すみません、初学者なもので。。。)
  2. そこはfunctionのスコープですので,外からは見えない部分になります.
    グローバルで使えなくてはいけないなら,グローバルで$mysqliを宣言します.
    詳しいことは上記ドキュメントを参照してください.
    変数は大文字小文字を区別することも忘れないでください.

ご丁寧に回答ありがとうございます!

1点追加で質問ですが、上記ご指摘のとおりコードを修正して出力したところ
下記のエラーメッセージが表示されてしまいます。

Fatal error: Uncaught ArgumentCountError: Number of bind variables doesn't match number of fields in prepared statement in C:\xampp\htdocs\test\devices.php:18 Stack trace: #0 C:\xampp\htdocs\test\devices.php(18): mysqli_stmt->bind_result(NULL) #1 {main} thrown in C:\xampp\htdocs\test\devices.php on line 18

devices.php内の
bind_result内の値を「$device_name, $serial_number, $manufacturer, $model, $os」
としても同様のエラーが発生します。
こちらのエラーの原因をご教示いただけないでしょうか。

0Like

Number of bind variables doesn't match number of fields in prepared statement

クエリ中のプレースホルダの数とbind_paramの引数の数が合いません.

0Like

Your answer might help someone💌