我被告知我以前的帖子不是很清楚,所以我会尝试以不同的方式提问。
我在OOP食谱书中工作。目前,我正在努力添加食谱。为此,我显示一个测量下拉列表,当用户选择测量时,我想显示另一个下拉列表,其中包含为该measurement_id找到的单位。
mysql上的表是具有id和name列的度量,以及具有id,name和measurement_id列的单位(measurement_id是单位表的外键)。多个单元属于一个测量。
为此,我创建了一个测量php对象/类。
在new_recipe.php上,我添加了一个表单,其余列添加了一个配方,我将只包括我现在正在处理的问题:
注意:在measurement.php上,Measurement php对象/类具有以下方法: - display_measurements() - >只需从测量表中选择所有测量值即可。 - get_units_for_measurement($ measurement_id) - >选择具有相同measurement_id的所有单位。
public function display_measurements() {
include 'includes/db_connection.php';
try {
$sql = "SELECT id, name FROM measurements";
$results = $conn->prepare($sql);
$results->execute();
} catch(PDOException $e) {
echo 'Error: ' . $e->getMessage() . '<br />';
return array();
}
return $results->fetchAll(PDO::FETCH_ASSOC);
}
public function get_units_for_measurement($measurement_id = ':measurement_id') {
include 'includes/db_connection.php';
try {
$sql = "SELECT measurements.id, units.id, units.name "
. "FROM measurements "
. "JOIN units "
. "ON measurements.id=units.measurement_id WHERE measurements.id=:measurement_id";
$result = $conn->prepare($sql);
$result->bindParam(':measurement_id', $measurement_id, PDO::PARAM_INT);
$result->execute();
} catch(PDOException $e) {
echo 'Error: ' . $e->getMessage() . '<br />';
return array();
}
return $result->fetchAll(PDO::FETCH_ASSOC);
}
<form id="newRecipe" method="POST" action="new_recipe.php">
(...)
<div class="input_group">
<label for="name" class="required">Name</label>
<input name="name" type="text" value="" />
</div>
<div class="input_group">
<label for="measurements" class="required">Measurements</label>
<select name="measurements" class="selectMeasurement">
<option disabled selected value=""> -- select a measurement -- </option>
<?php
$measurements = $measurementObj->display_measurements();
foreach ($measurements as $measurement) {
echo '<option value="' . $measurement['id'] . '" ';
echo '>' . $measurement['name'] . '</option>';
}
?>
</select>
</div>
<div class="input_group">
<label for="units" class="required">Units</label>
<select id="selectUnit" name="units">
<option disabled selected value=""> -- select a unit -- </option>
<?php
if (isset($_POST['measurements'])) {
die('ddddd');
// $units = $measurementObj->get_units_for_measurement($_POST['measurements']);
// foreach ($units as $unit) {
// echo '<option value="' . $unit['id'] . '" ';
// echo '>' . $unit['name'] . '</option>';
// }
}
?>
</select>
</div>
(...)
<button class="submit" type="submit" name="submit">Submit</button>
</form>
您可以在表单中看到两个选择下拉列表;第一个是我正在显示测量值的那个,下一个是我用一些注释线,我在那里“过滤”在第一个下拉列表中选择的measurement_id来显示所属单位。要做它没有重新加载页面,我被建议用ajax(我不是很熟悉)。这个ajax调用js文件,链接到项目的页脚:
$(document).ready(function() {
$('#newRecipe').on('change','.selectMeasurement', function(){
var selectedMeasurementId = this.value;
$.ajax({
method: 'POST',
url: 'classes/measurement.php',
data: selectedMeasurementId
});
return true;
});
});
或
$(document).ready(function(){
$('#newRecipe')。on('change','。selectMeasurement',function(){
var selectedMeasurementId = this.value;
$就({
方法:'POST',
url:'classes / measurement.php',
data:selectedMeasurementId,
成功:function(){
警报(selectedMeasurementId);
}
});
});
});
在js文件中,我想到的是成功,调用方法对象:
成功:$ measurementObj-&gt; get_units_for_measurement($ _ POST ['测量']),我明白,如果我有一个ajax响应,我想得到给定测量的单位,但是,我不能打电话这里有一个PHP对象。
此外,我在设置测量时尝试做某事。选择测量后,我试着这样做:
if (isset($_POST['measurements'])) {
//then $measurementObbj->get_units_for_measurement|($_POST['measurements']), but it seems it does not "detect" the measurements has been set.
}
所以我的问题是......为了ajax请求的成功,我怎么能执行这个$ measurementObj-&gt; get_units_for_measurement(在第一个下拉列表中选择了measurement_id)?
我希望现在有点清楚。 谢谢
答案 0 :(得分:1)
免责声明: 这是一个粗略且未经测试的草图,说明如何做到这一点。
正如您提到的OOP,我首先会重构您如何访问数据库以使其更加面向对象。我将使用DAO模式的缩短版本。如果您按照certain conventions进行操作,则可以非常轻松地使用它。这种模式有一些缺点,但在大多数情况下它会使您的代码更有条理。
首先,我将创建两个类MeasurementDAO
和UnitDAO
,分别用于访问每个表的数据。 (如果对你来说更方便,你可以使用一个班级。)
<强>类/ MeasurementDAO.php 强>
class MeasurementDAO
{
protected $conn;
public function __construct(PDO $conn) {
$this->conn = $conn;
}
public function getMeasurements() {
try {
// no need to use prepare() if you are not using any placeholders e.g. :name or ?
// query() and prepare() do not return results, but a (st)atement (h)andler
$sth = $this->conn->query("SELECT id, name FROM measurements");
return $sth->fetchAll(PDO::FETCH_OBJ);
} catch (PDOException $e) {
echo 'Error: ' . $e->getMessage() . '<br />';
}
}
}
<强>类/ UnitDAO.php 强>
class UnitDAO
{
protected $conn;
public function __construct(PDO $conn) {
$this->conn = $conn;
}
public function getUnitsByMeasurement($measurementId) {
try {
// if I am not mistaken, this query should be shorter and equivalent to your initial one
$sth = $this->conn->prepare("SELECT * FROM units WHERE measurement_id = ?");
// I have never seen any reason to use bindParam() as you can just pass your values in execute()
$sth->execute(array($measurementId));
return $sth->fetchAll(PDO::FETCH_OBJ);
} catch (PDOException $e) {
echo 'Error: ' . $e->getMessage() . '<br />';
}
}
}
(您可能还需要使用getRecipes()
,addRecipe($recipe)
,updateRecipe($recipe)
,deleteRecipe($id)
等方法 RecipeDAO.php 。)
接下来,当您向脚本发出AJAX请求时,您不想直接调用该类。相反,您想要调用使用该类的脚本。
<强> ajaxHandler.php 强>
// this will hold the data to be sent back as our response
$res = array();
// initialize connection
$conn = new PDO(/*...*/);
// determine what action to take
if ($_GET['action'] === 'get_units') {
// get units
$res['units'] = (new UnitDAO($conn))->getUnitsByMeasurement($_GET['measurement']);
}
header('Content-Type: application/json');
// last line: send response (it should be the only thing that gets outputted)
echo json_encode($res);
您可以通过转到例如JavaScript来调用脚本ajaxHandler.php?action=get_units&measurement=123
。
接下来,我们将使用我们的新方式进行测量。 (我个人认为在开始时做所有数据库工作更好更干净 - 反对在输出HTML时这样做。)
<强> new_recipe.php 强>
<?php
// initialize connection
$conn = new PDO(/*...*/);
// get measurements
$measurements = (new MeasurementDAO($conn))->getMeasurements();
?>
<form id="newRecipe" method="POST" action="new_recipe.php">
<!-- etc -->
<div class="input_group">
<!-- sidenote: label's FOR attribute attaches itself to the inputs's ID attribute, not NAME attribute -->
<label for="measurements" class="required">Measurements</label>
<select name="measurements" class="selectMeasurement">
<option disabled selected value=""> -- select a measurement -- </option>
<?php if ($measurements) : ?>
<?php foreach ($measurements as $measurement) : ?>
<option value="<?php echo $measurement->id ?>"><?php echo $measurement->name ?></option>
<?php endforeach ?>
<?php endif ?>
</select>
</div>
<div class="input_group">
<label for="units" class="required">Units</label>
<select name="units" id="selectUnit">
<option disabled selected value=""> -- select a unit -- </option>
</select>
</div>
<!-- etc -->
</form>
最后,让我们调用ajax处理脚本并构建选项列表。
// shorter syntax for $(document).ready
$(function() {
$('#newRecipe').on('change', '[name=measurements]', function () {
console.log('send request with ', this.value);
// we'll use a $.getJSON() which is a shortened version of $.ajax()
// make a GET request to ajaxHandler.php?action=get_units&measurement={this.value}
$.getJSON('ajaxHandler.php', { action: 'get_units', measurement: this.value }, function (res) {
console.log('got response', res);
var html = '';
// build list of options if any
if (!$.isEmptyObject(res.units)) {
$.each(res.units, function (unit) {
html += '<option>' + unit.name + '</option>';
});
}
// set list of options
$('[name=units]').html(html);
});
});
});
那应该是它。您需要添加缺少的部分,例如包含PHP文件。
(如果您想保留当前的设置,只需按照 ajaxHandler.php 中的所有内容进行必要的调整。