php - HTML下拉列表使用PHP和MySQL填充

标签 php html mysql

几年后我会回到这里…生活让我走上了一条不同的道路,但我又回到了这一步,仍然试图找到一些有用的东西。
我不是一个专业的前端开发人员,我正在学习,但为了“代码优先,学习第二”的兴趣,我正在尝试使用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)、boolMySQi::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/

相关文章:

javascript - 对于 &lt;input type ="submit"/> 元素,使用 JavaScript 更改按钮文本在 Opera (11.11) 中不起作用。为什么?

html - CSS根据宽度更改标题高度

Mysql 汇总到每月的每一天

php - .htaccess mod 重写目录索引

php - 创建 zf 自定义命令,例如 zf create form

javascript - 如何使用 localstorage 将列表中的所有复选框 bool 值存储到数组中?

php - 更改数据库中的用户名

php - 更新创建简单的 Php、MySql 投票系统的问题

php - 升级到 php 7 后出现 fsockopen 错误

php - 从 php 调用 Windows 串行调制解调器