PHPで表示したMySQLでの検索機能について
解決したいこと
MySQLで作成したDBをPHPで表示させるプログラムを作っています。
端末テーブル(devices.php)に検索フォームを追加し、入力 or 検索した項目を含む行を表示するようにしたいのですが、
①入力フォーム(device_name,serial_number,os,school_year,class)に値を入力して検索すると正常に検索結果が表示されますが、
_②選択フォーム(model,os_version,school_id)を選択して検索しても、「検索対象は見つかりませんでした。」と表示されて、検索結果が表示されません。
_
検索条件からSQl文を生成する部分についてご教示お願いします。
エラーコード
※modelのoption valueやissetの引数を数字ではなく「Surface Laptop Go」に書き換えて、選択フォームから検索を実行した場合に発生するエラー
Fatal error: Uncaught mysqli_sql_exception: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'Laptop Go' at line 1 in C:\xampp\htdocs\DevicesWithInventory\devices\model.php:51 Stack trace: #0 C:\xampp\htdocs\DevicesWithInventory\devices\model.php(51): mysqli->query('select * from d...') #1 C:\xampp\htdocs\DevicesWithInventory\devices\devices.php(6): getDeviceData(Array) #2 {main} thrown in C:\xampp\htdocs\DevicesWithInventory\devices\model.php on line 51
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',
`os_version` varchar(15) NOT NULL,
`school_id` char(4) NOT NULL,
`school_year` int(1) DEFAULT NULL,
`class` int(1) DEFAULT NULL,
PRIMARY KEY (`device_name`),
UNIQUE KEY `serial_number` (`serial_number`),
KEY `fk_school_id` (`school_id`),
CONSTRAINT `fk_school_id` FOREIGN KEY (`school_id`) REFERENCES `school` (`school_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
該当するソースコード
devices.php
<?php
//①データ取得ロジックを呼び出す
include_once('model.php');
$deviceData = getDeviceData($_GET);
?>
<!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>
<h1 class="col-xs-6 col-xs-offset-3">端末テーブル</h1>
<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="Surface Laptop Go" <?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</option>
</select>
</div>
<div class="form-group">
<label for="InputOs">OS</label>
<input type="os" class="form-control" id="InputOs" value="Windows">
</div>
<div class="form-group">
<label for="InputOs_version">OS Version</label>
<select name="os_version" class="form-control" id="InputOs_version">
<option value="0" <?php echo empty($_GET['os_version']) ? 'selected' : '' ?>>選択しない</option>
<option value="1" <?php echo isset($_GET['os_version']) && $_GET['os_version'] == '1' ? 'selected' : '' ?>>10.0.19041.1165</option>
<option value="2" <?php echo isset($_GET['os_version']) && $_GET['os_version'] == '2' ? 'selected' : '' ?>>10.0.19041.329</option>
~~~以下略~~~
<option value="15" <?php echo isset($_GET['os_version']) && $_GET['os_version'] == '15' ? 'selected' : '' ?>>10.0.19044.1889</option>
</select>
</div>
<div class="form-group">
<label for="InputSchool_id">学校ID</label>
<select name="school_id" class="form-control" id="InputSchool_id">
<option value="0" <?php echo empty($_GET['school_id']) ? 'selected' : '' ?>>選択しない</option>
<option value="1" <?php echo isset($_GET['school_id']) && $_GET['school_id'] == '1' ? 'selected' : '' ?>>X01X</option>
~~~以下略~~~
<option value="20" <?php echo isset($_GET['school_id']) && $_GET['school_id'] == '20' ? 'selected' : '' ?>>X07X</option>
</select>
</div>
<div class="form-group">
<label for="InputSchool_year">学年</label>
<input name="school_year" class="form-control" id="InputSchool_year" value="<?php echo isset($_GET['school_year']) ? htmlspecialchars($_GET['school_year']) : '' ?>">
</div>
<div class="form-group">
<label for="InputClass">クラス</label>
<input name="class" class="form-control" id="InputClass" value="<?php echo isset($_GET['class']) ? htmlspecialchars($_GET['class']) : '' ?>">
</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>
<th>OS Version</th>
<th>学校ID</th>
<th>学年</th>
<th>クラス</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>
<td><?php echo htmlspecialchars($row['os_version']) ?></td>
<td><?php echo htmlspecialchars($row['school_id']) ?></td>
<td><?php echo htmlspecialchars($row['school_year']) ?></td>
<td><?php echo htmlspecialchars($row['class']) ?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php else: ?>
<p class="alert alert-danger">検索対象は見つかりませんでした。</p>
<?php endif; ?>
<form action="input_devices.php" method="post">
<input type="submit" value="新規端末登録">
</form>
</div>
</body>
</html>
config/database.php
<?php
//DBの接続情報
$host = "127.0.0.1";
$username = "XXX00";
$password = "";
$dbname = "XXXX";
model.php
<?php
function getDeviceData($params){
//DBの接続情報
include_once('config/database.php');
//DBコネクタを生成
$Mysqli = new mysqli('127.0.0.1', 'XXX00', '', 'XXXX');
if ($Mysqli->connect_error) {
error_log($Mysqli->connect_error);
exit;
}
//入力された検索条件からSQl文を生成
$where = [];
if(!empty($params['device_name'])){
$where[] = "device_name like '%{$params['device_name']}%'";
}
if(!empty($params['serial_number'])){
$where[] = "serial_number like '%{$params['serial_number']}%'";
}
if(!empty($params['manufacturer'])){
$where[] = 'manufacturer = ' . $params['manufacturer'];
}
if(!empty($params['model'])){
$where[] = 'model = ' . $params['model'];
}
if(!empty($params['os'])){
$where[] = 'os = ' . $params['os'];
}
if(!empty($params['os_version'])){
$where[] = 'os_version = ' . $params['os_version'];
}
if(!empty($params['school_id'])){
$where[] = 'school_id = ' . $params['school_id'];
}
if(!empty($params['school_year'])){
$where[] = "school_year like '%{$params['school_year']}%'";
}
if(!empty($params['class'])){
$where[] = "class like '%{$params['class']}%'";
}
if($where){
$whereSql = implode(' AND ', $where);
$sql = 'select * from devices where ' . $whereSql ;
}else{
$sql = 'select * from devices';
}
//SQL文を実行する
$DeviceDataSet = $Mysqli->query($sql);
//扱いやすい形に変える
$result = [];
while($row = $DeviceDataSet->fetch_assoc()){
$result[] = $row;
}
return $result;
}
自分で試したこと
manufacturerについては上記のように修正して正常に表示されるようになりましたが、
(例えば)modelについてoption valueやissetの値を文字列に変更するとエラーが発生してしまいますが、
値の記述の仕方が分かりません。