几年后我会回到这里…生活让我走上了一条不同的道路,但我又回到了这一步,仍然试图找到一些有用的东西。
我不是一个专业的前端开发人员,我正在学习,但为了“代码优先,学习第二”的兴趣,我正在尝试使用mysql存储过程提供的多个下拉菜单加载一个页面。虽然我总是对“最好的方法”感兴趣(例如,“你为什么不做面向对象编程?”或者“你为什么要这么做?”,我只想说我在学习,但现在,我只是想弄明白“为什么这不管用?”我在YouTube上看了很多视频——在这里搜了很多文章——但仍然搞不清这是怎么回事。这看起来应该比现在简单得多,而且不明白为什么我不能让它工作,即使这不是最佳实践。我观看的视频不可避免地展示了如何使用(单个)过程填充下拉列表。我可以得到一个(单个)下拉列表来填充;我不能在同一页上得到两个或更多。
我数据库中的表过于简单,再说一遍,并不是真正的重点。我有一个“year”表,基本上(为了简单起见)有一个“id”,它是年份,还有一个列(也是年份)。
所以:
year_id year
2017 2017
2018 2018
别问我“为什么”—简单的说就是要证明这个概念(让它起作用)。
我的“团队”表有一个seq和一个名字
team_seq team_name
1 joe_smith
2 tom_jefferson
我有两个程序,一个叫做ref_sp_year_ref,这是一个简单的按年选择,另一个叫做ref_sp_team_ref,这也是一个简单的选择。
在mysql中,这些过程运行良好;没问题。
如果我将select语句从mysql过程中取出,并将它们作为“select”键入php代码中的变量中,那么它就可以正常工作,下拉列表就会填充。即,如果我有:
$qry1 = "Select ... <the rest of the Team query"
$qry2 = "Select ... <the rest of the Year query"
然后下拉菜单开始工作。
如果我使用$qry1=“call ref_sp_team_ref”和$qry2=“call ref_sp_year_ref”,则可以使用第一个下拉列表进行填充,但第二个下拉列表不会。
下面是我当前的代码。再说一次,我相信还有更好的办法——两年前我最初的问题的答案已经表明了这一点。但我想知道为什么这行不通。为什么它与php中的“selects”一起工作,而不与存储过程一起工作?
运行此操作将导致“团队”下拉列表正确填充,但随后会在“年份”下拉列表所在的位置显示错误消息,并显示:
警告:mysqli_num_rows()期望参数1是mysqli_result,book-given-in:,它引用此行:if(mysqli_num_rows($years)>0)
第二个错误本质上是相同的,引用这一行:mysqli_free_result($years);
在这两种情况下,在我看来很明显,第二个进程要么没有被调用,要么没有运行,然后返回空的。我不明白为什么…
作为对最初答案的回应,我会说,以前我使用的是“multi_query”,显然它不是一个multi-query。当时,我刚从书上打出来,不明白那是怎么回事。不过,目前,由于顶级过程(ref_sp_team_ref)确实返回结果,我的猜测是,我的问题不是调用本身或调用的语法。我只是不知道为什么ref_sp_year_ref也不会运行和加载
另外,我可以添加:在我的php代码中,如果我在第一次调用(teams)中有一个select查询,在第二次调用(years)中有一个过程调用,那么它可以工作。两个下拉列表都会填充。这就是我“得不到”的东西。为什么两个“select”工作,或者一个“select”和一个过程调用,但是两个过程调用不工作?
提前感谢您的帮助。
<form method="post" action="">
<?php
require_once('../../../mysqlconnect_mysqli.php');
/* TEAM DROPDOWN */
$qry1 = "CALL ref_sp_Team_Ref()";
$teams = mysqli_query($conn,$qry1);
if (mysqli_num_rows($teams) > 0)
{
echo "<label for='teams'>Teams: </label>";
echo "<select name='teams' size='1' required>";
echo "<option>Team Names</option>";
while($row = mysqli_fetch_array($teams))
{
echo "<option value=\"{$row['team_seq']}\">{$row['team']}</option>";
}
echo "</select>";
echo "<br /><br />";
}
else
{
echo "Why is this empty?";
}
mysqli_free_result($teams);
/* YEAR DROPDOWN */
$qry2 = "CALL ref_sp_Year_Ref()";
$years = mysqli_query($conn,$qry2);
if (mysqli_num_rows($years) > 0)
{
echo "<label for='years'>Years: </label>";
echo "<select name='years' size='1' required>";
echo "<option>Seasons</option>";
while($row = mysqli_fetch_array($years))
{
echo "<option value=\"{$row['year_id']}\">{$row['year']}</option>";
}
echo "</select>";
echo "<br /><br />";
}
else
{
echo "Why is this empty?";
}
mysqli_free_result($years);
echo " <input type='submit' name='submit1' value='Get Results'/>";
echo "</form>";
?>
我以前的职位(两年前)如下。
我已经读了很多关于这个话题的文章,但似乎还是找不到我的问题所在。当谈到html表单和php时,我会认为自己是一个初学者。我有丰富的使用存储过程的经验(t-sql、oracle和mysql新过程)。我的信念是,这里的问题是在php或html中—mysql存储过程在执行时看起来没问题。
我正在尝试在由procs填充的html页面中创建多个下拉列表。我还没有做任何花哨的事情,例如动态选择第一个值发送到第二个进程…我只是想做一些基本的“加载”所有下拉列表。
下面的代码将导致第一个下拉列表(“years”)填充fine,但第二个下拉列表(“teams”)为空。如果我切换块的顺序,“团队”将很好地填充,但“年”将是空的。
我肯定我只是错过了一些很简单的事情…但我们非常感谢您的帮助。
我的代码是:
<form method="post" action="">
<p>
Years:
<select name="years">
<?php
#the following returns the connection variable $dbh
require_once('../../../mysqlconnect_mysqli.php');
$sql = "call ref_sp_Year_Ref";
if ($mysqli->multi_query($sql))
{
#Get first data set from Procedure - do nothing with it
$result = $mysqli->store_result();
while($row = mysqli_fetch_array($result,MYSQLI_ASSOC))
{
echo
"<option value='" . $row['year_id'] . "'>" . $row['year'] . "</option>";
}
mysqli_free_result($result);
}
?>
</select>
</p>
<p>
Teams:
<select name="teams">
<?php
#the following returns the connection variable $dbh
require_once('../../../mysqlconnect_mysqli.php');
$sql = "call ref_sp_Team_Ref";
if ($mysqli->multi_query($sql))
{
#Get first data set from Procedure - do nothing with it
$result = $mysqli->store_result();
while($row = mysqli_fetch_array($result,MYSQLI_ASSOC))
{
echo
"<option value='" . $row['team_id'] . "'>" . $row['team'] . "</option>";
}
mysqli_free_result($result);
}
?>
</select>
</p>
<br>
<input type="submit" name="submit1" value="Get Results"/>
</form>
最佳答案
注意:因为我使用面向对象编程,所以我永远不会像在项目中那样解决这个问题。但是,如果你要走程序路线,好吧,让我看看我能做些什么来帮助你。
这是很长的一段路,但是如果您按照下面问题中我的答案的链接,您将看到我是如何模块化(使用函数)使用sql(my sql i等)创建动态php的。
Modularizing Procedural PHP with SQL for dynamic HTML
在这种情况下,程序员希望创建一个动态的<table>
,但我相信如果您需要,您可以为您的特定情况挑选一些想法。一定要把我的答案搞清楚。
对于您的问题,我更改了查询的执行方式。MySQLi::query
而不是MySQLi::multi_query
。此外,我还改变了处理结果(mysqli_result
)的方式。
我看到你在使用MySQLi::multi_query
。您的存储过程是多重查询吗?如果是这样,您可能还需要使用while
(检查更多结果,返回MySQi::more_results
)、bool
和MySQi::next_result
)添加一个小算法(MySQi::store_result
循环)。
从php手册:mysqli::multi_query
示例1(处理多个查询)
if ($mysqli->multi_query($sql)) { // Run the multi-query
do {
if ($result = $mysqli->store_result()) { // Access the result.
while ($row = $result->fetch_assoc()) { // Use the result.
//Your code here
}
$result->free();
}
} while ($mysqli->next_result()); //Get the next result.
}
你的具体解决方案(希望如此)。
<form method="post" action="">
<label>Years:
<select name="years">
<?php
require_once('../../../mysqlconnect_mysqli.php');
$sql = 'CALL ref_sp_Year_Ref()';
$result = $dbh->query($sql);
if($result === false) {
throw new UnexpectedValueException("The stored proceedure ref_sp_Year_Ref() did not return a mysqli_result object.");
}
while ($row = $result->fetch_assoc($result,MYSQLI_ASSOC)) {
echo "<option value=\"{$row['year_id']}\">{$row['year']}</option>";
}
$result->free();
?>
</select>
</label>
<label>Teams:
<select name="teams">
<?php
$sql = 'CALL ref_sp_Team_Ref()';
$result = $dbh->query($sql);
if($result === false) {
throw new UnexpectedValueException("The stored proceedure ref_sp_Team_Ref() did not return a mysqli_result object.");
}
while ($row = $result->fetch_assoc()) {
echo "<option value=\"{$row['team_id']}\">{$row['team']}</option>";
}
$result->free();
?>
</select>
</label>
<br>
<input type="submit" name="submit1" value="Get Results"/>
</form>
米斯利
标准查询。
这两个函数用于实例化
MySQLi
对象并返回一个简单的mysqli_result
对象。/**
* Returns a mysqli_result object, or throws an `UnexpectedValueException`.
* You can reuse this for other SELECT, SHOW, DESCRIBE or EXPLAIN queries.
*/
function getMySQLiResult(MySQLi $db, $sql)
{
if (!is_string($sql)) {
throw new InvalidArgumentException("The second argument to the function getMySQLiResult must be a string (SQL query)!");
}
$result = $db->query($sql);
if (!($result instanceof mysqli_result)) {
throw new UnexpectedValueException("<p>MySQLi error no {$db->errno} : {$db->error}</p>");
}
return $result;
}
/**
* Returns a MySQLI object, or throws an `UnexpectedValueException`.
*/
function getMySQLi()
{
require_once 'dbCreds.php'; //Choose your own file name. Do not put in public directory.
$db = new mysqli($host, $username, $passwd, $dbname); //$port would be next.
if (!($db instanceof MySQLi)) {
throw new UnexpectedValueException("A MySQLi object was not returned during your connection attempt.");
}
if (isset($db->connect_error)) {
throw new UnexpectedValueException("The database connection was not established. {$db->connect_errno} : {$db->connect_error}");
}
return $db
}
多个查询。
这两个函数是处理多个查询的一种方法。
/**
* Returns null, or an array of mysqli_result objects.
*/
function gatherMQResults(MySQLi $db, $sql)
{
$results = []; //PHP 5.4+
if ($db->multi_query($sql)) { // Run the multi-query
do {
$result = $db->store_result(); //Store result.
if ($result !== false) { //Test result
$results[] = $result //Be careful when result set is large!!
}
} while ($db->next_result()); //Get the next result.
}
return (empty($results)) ? null : $results;
}
/**
* Uses an anonymous function to use the query result.
*/
function useMySQLiResult(Callable $fn, mysqli_result $result)
{
$value = $fn($result->fetch_all()); //PHP 5.3+, Where $fn is an anonymous function
$result->free();
return $value;
}
实例
您可以像这样使用这两个函数。看看他们,你可能会有一些想法。
/* Define an anonymous function */
$makeOptions = function(array $data) {
$options = [];
foreach ($data as $key => $value) {
$options[] = "<option value=\"{$key}\">{$value}</option>"
}
return implode("\n", $options) . "\n"
};
function drawYearOptions(MySQLi $db, Callable $fn)
{
$sql = "someAmazingMultiQuery"; // The multi-query.
$results = gatherMQResults($db, $sql); // All the results.
if (!isset($results)) {
throw new Exception("Where the heck are the year results? None found.");
}
return useMySQLiResult($fn, results[0]) // Index depends on query.
}
function drawTeamOptions(MySQLi $db, Callable $fn)
{
$sql = "anotherAmazingMultiQuery"; // The multi-query.
$results = gatherMQResults($db, $sql); // All the results.
if (!isset($results)) {
throw new Exception("Where the heck are the team results? None found.");
}
return useMySQLiResult($fn, results[0]) // Index depends on query.
}
在选择的内部使用上面的最终函数:
<select>
。<select name="foo">
<?= drawYearOptions($mysqli, $makeOptions); ?>
</select>
<select name="bar">
<?= drawTeamOptions($mysqli, $makeOptions); ?>
</select>
现在,当您准备好了,可以使用一些方便的、漂亮的对象实例和方法来清除这个问题。
<select name="foo">
<?= $view->drawYearOptions(); ?>
</select>
<select name="bar">
<?= $view->drawTeamOptions(); ?>
</select>
当你的系统足够完善时,它就变成了这个(不是双关语)。
<select name="foo">
<?= $this->drawYearOptions(); ?>
</select>
<select name="bar">
<?= $this->drawTeamOptions(); ?>
</select>
关于php - HTML下拉列表使用PHP和MySQL填充,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42728182/