几年后我回到了这里......生活让我走上了不同的道路,但我回到了这一点,并且仍然试图找到有用的东西。
我不是专业的前端开发人员,我正在学习,但为了“代码优先,学习第二”的利益,我正在尝试使用多个下拉菜单来加载页面MySQL存储过程。虽然我总是对“做这件事的最好方法”感兴趣(例如“你为什么不做OOP?”或“你为什么要这样做?”),我只想说我正在学习,但就目前而言,我只是想弄清楚“为什么这不起作用?”我在YouTube上观看过很多视频 - 在这里搜索文章 - 但仍然无法弄清楚出了什么问题这看起来应该比它简单得多,并且无法弄清楚为什么我不能让它工作,即使它不是最好的做法。我观看的视频不可避免地显示如何获得A填充下拉列表的(单个)程序。我可以获得A(单个)下拉列表来填充;我不能在同一页面上获得两个或更多。
我的数据库中的表格过于简单,而且并非如此。我有一个“年”表,基本上(为简单起见)有一个“id”,即年份和列(也是年份)。 所以:
year_id year
2017 2017
2018 2018
不要问我的“为什么” - 试图证明这个概念(让它发挥作用)很简单。
我的“团队”表有一个seq和一个名字
team_seq team_name
1 joe_smith
2 tom_jefferson
我有两个程序,一个名为ref_sp_Year_Ref,它是Year上的一个简单选择,另一个名为ref_sp_Team_Ref,也是一个简单的选择。
MySQL中的程序运行良好;没问题。
如果我从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”那么我可以获得FIRST下拉列表,但第二个下拉列表不会填充。
以下是我目前的代码。再说一遍,我确定有更好的方法 - 两年前我原来问题的答案已经提出了这个问题。但是我想知道为什么这不起作用。为什么它适用于PHP中的“选择”而不适用于存储过程?
运行此选项会导致“团队”下拉列表正确填充,但随后会出现“年份”下拉列表中的错误消息,并说: 警告:mysqli_num_rows()期望参数1为mysqli_result,书中给出:并引用此行: if(mysqli_num_rows($ years)&gt; 0) 第二个错误基本相同,引用此行: mysqli_free_result($ years);
在这两种情况下,对我来说很明显,第二个过程要么没有被调用,要么没有被运行,而它又回来了。我没有“得到”为什么......
我会说 - 响应原始答案 - 之前我使用的是“multi_query”,显然它不是一个多查询。当时,我刚从一本书中输入了这个,并且不明白那是什么。目前,由于顶级过程(ref_sp_team_ref)会返回结果,我的猜测是我的问题不是调用本身或调用的语法。我只是不知道为什么ref_sp_year_ref也不会运行并加载
此外,我可能会补充:在我的PHP代码中,如果我在第一次调用(团队)中有SELECT查询,并且在第二次调用(Years)中有一个过程调用,则它可以正常工作。两个下拉列表都填充。这就是我没有“得到”的东西。为什么两个“选择”工作,或一个“选择”和一个过程调用,但两个过程调用将不起作用?
提前感谢您的任何帮助。
<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 Forms和PHP方面,我认为自己是初学者。我在使用存储过程(T-SQL,Oracle和MySQL新程序)方面拥有丰富的经验。我的信念是我的问题在于PHP或HTML - MySQL存储过程在执行时似乎没问题。
我正在尝试在Procs中填充的HTML页面中创建多个下拉列表。我还没做任何花哨的事情,例如动态选择发送到第二个proc的第一个值......我只是试图对所有下拉列表进行基本的“加载”。
以下代码导致第一个下拉列表(“年”)填充正常,但第二个下拉列表(“团队”)为空。如果我切换块的顺序,“团队”将填充正常,但“年”将为空。
我确信我只是错过了一些非常简单的东西......但是非常感谢帮助。
我的代码是:
<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>
答案 0 :(得分:2)
注意:因为我使用面向对象的编程,所以我永远不会像我在项目中那样解决这个问题。但是,如果你要走程序路线,那么,让我看看我能做些什么来帮助。
这将是漫长的过程,但如果您在以下问题中按照我的回答链接,您将看到我如何模块化(使用函数)使用SQL创建动态PHP(MySQLi等...)。
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
。
从PHP手册:mysqli::multi_query
示例#1(处理mutli-queries)
MySQi::store_result
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>
答案 1 :(得分:-1)
改变这个: require_once(&#39; ../../../ mysqlconnect_mysqli.php&#39);