【问题标题】:creating a dynamic selection with PHP使用 PHP 创建动态选择
【发布时间】:2021-08-05 06:53:45
【问题描述】:

正如我的标题所述,我正在尝试使用 PHP 动态填充 html 中的选择。 我在互联网上找到了一些有用的代码 sn-ps,但无法弄清楚如何将它们连接在一起并按照我的意愿实现它们。 我有这些应该被填充的选择,第一个决定应该放入第二个:

<select id="linetime" name="line" onChange="dynSelect(this.id);">
<option value="L411">L411</option>
<option value="L412">L412</option>
<option value="L414">L414</option>
<option value="L421">L421</option>
<option value="L422A">L422A</option>
<option value="L422B">L422B</option>
<option value="L423">L423</option>
<option value="L424">L424</option>
</select>

<select id="scannertime" name="scanner">
</select>

并尝试以这种方式填充它:

function dynSelect(i){
$.ajax({
type: 'post',
url: "ajax.php.",
data: { id:'i' }
}).done(function(data) {
while(data.length){
$temp = data['scanner'];
$("#scannertime").append($("<options>").text($temp).val($temp));
}
});
}

PHP:

$id = $_REQUEST['id']; 
$json = array();

$dsn = "mysql:dbname=faultcounter; host=127.0.0.1";
$user = "root";
$password = "";
$dbh = new PDO($dsn,$user,$password);

$sql = $dbh->prepare("select * from possiblefaults where line=$id");
$sql->execute();
while ($row = $sql->fetch(PDO::FETCH_ASSOC)) {
$json[] = $row;
}
echo json_encode($json);

我的问题是,我对脚本语言和 PHP 还很陌生,到目前为止我还不太清楚事情是如何工作的,我无法弄清楚如何正确调试,因为我只用 C# 编写过和Java。我也不太明白我的 PHP 是否没有返回我想要的数据,或者我在上面的代码中使用它是错误的。 如果有人可以向我解释这些事情,我会很高兴。

注意:第一次使用stackoverflow。

【问题讨论】:

  • 欢迎来到 Stackoverflow。你提出了一个很好的问题。首先,我认为您应该在 HTML 代码中使用 value 而不是 id,如下所示:dynSelect(this.value);。另一个提示是在您的 javascript 中添加 console.log(&lt;your debug message&gt;) 以跟踪您需要的任何内容。通过在 Web 浏览器中按 F12,您将找到您的开发人员工具,您还可以在其中找到“控制台”(您的跟踪输出所在的位置)。祝你好运:)
  • 感谢您的快速帮助,如果我正确假设我的数据应该是一个数组,我如何记录数据中的特定值?
  • 你根本不需要返回 json-data。我个人更喜欢直接在 PHP 中生成 HTML 字符串,以便返回的数据很容易附加到您现有的 HTML 文档中。所以我会写 $html .= "&lt;option value='something'&gt;First Option... etc" 这样的东西,而不是 $json[] = $row。恕我直言,它更具可读性。
  • 什么究竟不能使用代码?你有什么努力让它发挥作用?此外,请注意,您的查询非常适合 SQL 注入 - 如果您已经使用准备好的语句,请通过 not 注入原始 $id 来正确使用它
  • @NicoHaase,我希望它根据第一个选择来填充我发布的第二个选择,看来我要么没有得到第一个选择到我的 php 的选择,要么我弄错了人口。注意:我知道我的查询对 SQL 注入是开放的,我计划在代码像网站当前在本地网络服务器上运行一样工作后这样做。(感谢您指出这一点。)编辑:因为我是新人对于一般的脚本语言,我真的不知道如何找到控制台中不存在的错误,或者像 c# 中常见的那样立即抛出我的脸。

标签: php html jquery ajax


【解决方案1】:

PHP 的缺陷在于,准备好的语句嵌入用户直接在 SQL 命令中提供数据,因此否定了Prepared Statements 的好处

由于您特别需要 ID 可用于运行 sql,因此您应该使用逻辑测试以确保在继续之前设置它。

如果您要使用另一种选择特定选择菜单的方法,可以删除 HTML 元素的 ID 属性 - querySelector 对此非常有用,因为我不使用 jQuery,所以我提供了一个使用 vanilla js 的可能解决方案。

<?php
    /*
        We can only process the request if the ID/line is present
    */
    if( isset( $_POST['id'] ) ){
    
        $id=filter_input( INPUT_POST, 'id', FILTER_SANITIZE_STRING );
        $data=array();
        
        $dsn = "mysql:dbname=faultcounter; host=127.0.0.1";
        $user = "root";
        $password = "";
        $dbh = new PDO($dsn,$user,$password);
        /*
            The `prepared statement` should use a `placeholder` rather
            than directly embedding variables in the SQL. Embedding variables
            opens the code to SQL injection vulnerabilities.
        */
        $sql='select `scanner` from `possiblefaults` where `line`=:id';
        $stmt=$dbh->prepare($sql);
        /*
            execute the statement with the bound variable
        */
        $res=$stmt->execute(array(
            ':id'   =>  $id
        ));
        
        while( $row = $stmt->fetch( PDO::FETCH_ASSOC ) ) $data[]=$row;
        exit( json_encode( $data ) );
    }
?>

一些稍微修改的 HTML:

<select name='line'>
    <option value='L411'>L411
    <option value='L412'>L412
    <option value='L414'>L414
    <option value='L421'>L421
    <option value='L422A'>L422A
    <option value='L422B'>L422B
    <option value='L423'>L423
    <option value='L424'>L424
</select>
<select name='scanner'></select>

使用Fetch的香草js

<script>
    /*
        vanilla javascript using querySelector to target the `select` menus
        and bind the event listener externally as opposed to inline using `onChange`
    */
    document.querySelector('select[name="line"]').addEventListener('change',function(e){
        //find target Select menu
        let scanner=document.querySelector('select[name="scanner"]');
        
        //create payload to send to server
        let fd=new FormData();
            fd.set('id',this.value);
        
        // send the ajax request using fetch
        fetch('ajax.php',{method:'post',body:fd})
            .then( r=>r.json() )
            .then( json=>{
                scanner.innerHTML='';
                // process the response data and add new option for each record
                Object.keys( json ).forEach( key=>{
                    let obj=json[ key ];
                    scanner.append( new Option( obj.scanner, obj.scanner ) );
                })
            })
    });
</script>

更新 以下内容完全经过测试 - 从初始选择菜单返回所有项目的结果。

<?php

    error_reporting( E_ALL );
    
    # script is running from different directory to where db connection files are stored
    # set the include path to the directory 2 levels up
    chdir('../../');
    set_include_path( realpath( sprintf( '%s/dbo', getcwd() ) ) );
    
    require 'db-conn-details.php';
    require 'pdo-conn.php';
    

    if( $_SERVER['REQUEST_METHOD']=='POST' && isset( $_POST['id'] ) ){
        ob_clean();
        
        $id=filter_input( INPUT_POST, 'id', FILTER_SANITIZE_STRING );
        $data=array();
        
        # different table and columns but essentially the same query.
        # This returns a single record per line/id.
        $sql='select `seqid` as `scanner` from `account` where `line`=:id';
        $stmt=$dbh->prepare( $sql );

        $res=$stmt->execute(array(
            ':id'   =>  $id
        ));
        
        while( $row = $stmt->fetch( PDO::FETCH_ASSOC ) ) $data[]=$row;
        exit( json_encode( $data ) );
    }
?>
<!DOCTYPE html>
<html lang='en'>
    <head>
        <meta charset='utf-8' />
        <title></title>
    </head>
    <body>
        <select name='line'>
            <option value='L411'>L411
            <option value='L412'>L412
            <option value='L414'>L414
            <option value='L421'>L421
            <option value='L422A'>L422A
            <option value='L422B'>L422B
            <option value='L423'>L423
            <option value='L424'>L424
        </select>
        <select name='scanner'></select>
        <script>
            document.querySelector('select[name="line"]').addEventListener('change',function(e){
                let scanner=document.querySelector('select[name="scanner"]');
                let fd=new FormData();
                    fd.set('id',this.value);
                    
                fetch( location.href,{ method:'post', body:fd })
                    .then( r=>r.json() )
                    .then( json=>{
                        scanner.innerHTML='';
                        Object.keys( json ).forEach( key=>{
                            let obj=json[ key ];
                            scanner.append( new Option( obj.scanner, obj.scanner ) );
                        })
                    })
            });
        </script>
    </body>
</html>

db表数据:

mysql> select `line`, `seqid` as `scanner` from `account`;
+-------+----------------+
| line  | scanner        |
+-------+----------------+
| L411  | sri-0000001    |
| L412  | sri-0000002    |
| L413  | sri-0000003    |
| L414  | sri-0000004    |
| L421  | sri-00000014   |
| L422A | sri-00000015   |
| L422B | sri-00000016   |
| L423  | sri-00000017   |
| L425  | sri-00000018   |
|       | sri-00000019   |
|       | sri-00000020   |
|       | sri-00000021   |
|       | sri-00000022   |
|       | sri-00000023   |
|       | sri-0000003580 |
|       | sri-0000003581 |
|       | sri-0000003582 |
|       | sri-0000003583 |
|       | sri-0000003584 |
+-------+----------------+
19 rows in set (0.00 sec)

【讨论】:

  • 这似乎在解析 JSON 之前有效,它表明解析器已到达数据的未扩展端。任何想法为什么会受到赞赏。
  • 您能否捕获并发布(从控制台)由 ajax 查询返回的数据的样本?
  • 我不太明白这个问题,但我可以复制控制台的输出: Uncaught (in promise) SyntaxError: JSON.parse: unexpected end of data at line 1 column 1 of the JSON数据编辑:我想这意味着我的承诺失败了?
  • 如果您观察到网络请求,您应该(希望)看到来自 ajax 请求的响应。那是有效的JSON吗?请添加您可以帮助确定问题的内容。我在这里使用不同的数据库和表结构进行了测试,这对我来说没问题...
  • 初始下拉列表 (line) 是否直接从 db 填充?如果是这样,那么您可以轻松地在 PHP 代码中添加 selected 属性。如果列表是静态的(即:不使用来自 db 的数据呈现),则需要添加一些在页面加载时运行的额外 Javascript 以选择选择菜单中的选项之一,然后添加 selected 属性。顺便说一句:不用担心!
【解决方案2】:

你可以试试这个例如:

HTML:

 <div class="col-sm-6" id="occupation"></div>

这是您选择的 div

接下来,您尝试混合使用 jquery 和 PHP,但我将为您提供两者的示例

我在 json 文件中的数据:

[{"beruf_id":"58","beruf_name":"A SCH 19-23 B"},{"beruf_id":"1","beruf_name":"Anlagen- und Apparatebauer EFZ"},{"beruf_id":"59","beruf_name":"Automobil-Assistent\/in EBA"},{"beruf_id":"60","beruf_name":"Automobil-Fachleute EFZ"},{"beruf_id":"61","beruf_name":"Automobil-Mechatroniker\/in EFZ"},{"beruf_id":"62","beruf_name":"Automobil-Mechatroniker\/in EFZ Am-Me 19-23"},{"beruf_id":"2","beruf_name":"B\u00e4cker-Konditor-Confiseur EBA BKA 20-22A"},{"beruf_id":"3","beruf_name":"B\u00e4cker-Konditor-Confiseur EFZ"},{"beruf_id":"4","beruf_name":"Baupraktiker\/in EBA BPA 20-22A"},{"beruf_id":"5","beruf_name":"Berufsmatura Informatik"},{"beruf_id":"6","beruf_name":"Berufsmaturit\u00e4t 3-j\u00e4hrig"},{"beruf_id":"7","beruf_name":"Berufsmaturit\u00e4t I 3-j\u00e4hrig"},{"beruf_id":"8","beruf_name":"Berufsmaturit\u00e4t I 3-j\u00e4hrig  DL"},{"beruf_id":"9","beruf_name":"Berufsmaturit\u00e4t I 3-j\u00e4hrig TAL"},{"beruf_id":"10","beruf_name":"Berufsmaturit\u00e4t I 4-j\u00e4hrig TAL"},{"beruf_id":"63","beruf_name":"Berufsmaturit\u00e4t II 1-j\u00e4hrig TAL"},{"beruf_id":"11","beruf_name":"Berufsmaturit\u00e4t II 2-j\u00e4hrig TAL 21-23 A"},{"beruf_id":"12","beruf_name":"Berufsmaturit\u00e4t II BBM 20-22 A"},{"beruf_id":"13","beruf_name":"Betriebsinformatiker\/in EFZ"},{"beruf_id":"64","beruf_name":"BP HW Hauswart\/in"},{"beruf_id":"65","beruf_name":"Coiffeuse\/Coiffeur EBA"},{"beruf_id":"66","beruf_name":"Coiffeuse\/Coiffeur EFZ"},{"beruf_id":"14","beruf_name":"E Lehr mit Kick"},{"beruf_id":"15","beruf_name":"E Lehr mit Kick 20-24"},{"beruf_id":"16","beruf_name":"Elektroinstallateur EFZ"},{"beruf_id":"67","beruf_name":"Fachkunde Distribution"},{"beruf_id":"68","beruf_name":"Fachkunde Distribution FKD 20-23"},{"beruf_id":"69","beruf_name":"Fachleute Betriebsunterhalt EFZ HD"},{"beruf_id":"70","beruf_name":"Fachleute Betriebsunterhalt EFZ HD FBH 21-24 B"},{"beruf_id":"71","beruf_name":"Fachleute Betriebsunterhalt EFZ WD"},{"beruf_id":"72","beruf_name":"Fachmann\/Fachfrau BP LOFA 19-22"},{"beruf_id":"17","beruf_name":"Fleischfachassistent\/in EBA"},{"beruf_id":"18","beruf_name":"Fleischfachleute EFZ"},{"beruf_id":"73","beruf_name":"F\u00f6rderkurs Kombi Dienstag"},{"beruf_id":"74","beruf_name":"F\u00f6rderkurs Kombi Donnerstag"},{"beruf_id":"75","beruf_name":"F\u00f6rderkurs Kombi Mittwoch"},{"beruf_id":"76","beruf_name":"F\u00f6rderkurs Kombi Montag"},{"beruf_id":"77","beruf_name":"Forstwart\/in EFZ"},{"beruf_id":"19","beruf_name":"G\u00e4rtner\/in EBA Landschaft"},{"beruf_id":"20","beruf_name":"G\u00e4rtner\/in EBA Produktion"},{"beruf_id":"21","beruf_name":"G\u00e4rtner\/in EFZ Landschaft"},{"beruf_id":"22","beruf_name":"G\u00e4rtner\/in EFZ Produktion"},{"beruf_id":"78","beruf_name":"Grundsch\u00fcler"},{"beruf_id":"79","beruf_name":"Haustechnikpraktiker\/in EBA"},{"beruf_id":"23","beruf_name":"hf-ict 19-22 B2"},{"beruf_id":"24","beruf_name":"hf-ict 20-23 B1"},{"beruf_id":"25","beruf_name":"HF-ICT 21-24 A"},{"beruf_id":"26","beruf_name":"HF-ICT 21-24 B"},{"beruf_id":"27","beruf_name":"Holzbearbeiter\/in EBA"},{"beruf_id":"80","beruf_name":"IG Fahrzeugrestaurator"},{"beruf_id":"28","beruf_name":"Informatiker Applikationsentwickler"},{"beruf_id":"29","beruf_name":"Informatiker Betriebsinformatik"},{"beruf_id":"30","beruf_name":"Informatiker System"},{"beruf_id":"31","beruf_name":"Informatiker\/in EFZ Applikation"},{"beruf_id":"32","beruf_name":"Informatiker\/in EFZ Plattformentwicklung 21-25 A"},{"beruf_id":"33","beruf_name":"Informatiker\/in EFZ Plattformentwicklung 21-25 B"},{"beruf_id":"34","beruf_name":"Koch\/K\u00f6chin EFZ"},{"beruf_id":"35","beruf_name":"Koch\/K\u00f6chin EFZ KOC 20-23 A"},{"beruf_id":"36","beruf_name":"Koch\/K\u00f6chin EFZ KOC 20-23 B"},{"beruf_id":"37","beruf_name":"Koch\/K\u00f6chin EFZ KOC 20-23 C"},{"beruf_id":"38","beruf_name":"K\u00fcchenangestellte EBA"},{"beruf_id":"81","beruf_name":"Landmaschinenmechaniker\/in EFZ"},{"beruf_id":"82","beruf_name":"Logistiker\/in EBA"},{"beruf_id":"83","beruf_name":"Logistiker\/in EFZ Art. 32"},{"beruf_id":"84","beruf_name":"Logistiker\/in EFZ LOG  19-22 C"},{"beruf_id":"85","beruf_name":"Logistiker\/in EFZ LOG 21-24 A"},{"beruf_id":"86","beruf_name":"Maler\/in EFZ"},{"beruf_id":"87","beruf_name":"Malerpraktiker\/in EBA"},{"beruf_id":"88","beruf_name":"Malerpraktiker\/in EBA MAA 21-23 A"},{"beruf_id":"39","beruf_name":"Maurer\/in EFZ"},{"beruf_id":"89","beruf_name":"Mechanikpraktiker\/in EBA"},{"beruf_id":"40","beruf_name":"Metallbauer\/in EFZ"},{"beruf_id":"41","beruf_name":"Metallbaupraktiker\/in EBA"},{"beruf_id":"42","beruf_name":"Montage-Elektriker\/in EFZ"},{"beruf_id":"90","beruf_name":"NHB Art. 32 alle Berufe ABU 20-22"},{"beruf_id":"91","beruf_name":"NHB Art. 32 alle Berufe ABU 21-23"},{"beruf_id":"92","beruf_name":"NHB Art. 32 LOG ILB 21-23"},{"beruf_id":"93","beruf_name":"Polym.\/Konstr. E EFZ"},{"beruf_id":"94","beruf_name":"Polym.\/Konstr. E EFZ PMK 21-25 A"},{"beruf_id":"95","beruf_name":"Polym.\/Konstr. EFZ"},{"beruf_id":"96","beruf_name":"Polym.\/Konstr. EFZ PMK 21-25 M"},{"beruf_id":"97","beruf_name":"Polym.\/Konstr. G EFZ"},{"beruf_id":"98","beruf_name":"Polym.\/Konstr. G EFZ PMK 21-25 B"},{"beruf_id":"99","beruf_name":"Produktionsmechaniker\/in EFZ"},{"beruf_id":"100","beruf_name":"Sanit\u00e4rinstallateur\/in EFZ"},{"beruf_id":"101","beruf_name":"Schreiner\/in EFZ"},{"beruf_id":"102","beruf_name":"Spengler\/in EFZ"},{"beruf_id":"43","beruf_name":"St\u00fctzkurs B\u00e4cker-Konditor-Confiseur"},{"beruf_id":"44","beruf_name":"St\u00fctzkurs Elektro DI"},{"beruf_id":"45","beruf_name":"St\u00fctzkurs Elektro MI"},{"beruf_id":"46","beruf_name":"St\u00fctzkurs G\u00e4rtner DO"},{"beruf_id":"47","beruf_name":"St\u00fctzkurs Koch DI"},{"beruf_id":"48","beruf_name":"St\u00fctzkurs Mathe\/Deutsch DI"},{"beruf_id":"49","beruf_name":"St\u00fctzkurs Mathe\/Deutsch DO"},{"beruf_id":"50","beruf_name":"St\u00fctzkurs Mathe\/Deutsch MI"},{"beruf_id":"51","beruf_name":"St\u00fctzkurs Mathe\/Deutsch MO"},{"beruf_id":"52","beruf_name":"St\u00fctzkurs Maurer DI"},{"beruf_id":"53","beruf_name":"St\u00fctzkurs Maurer\/Zimmerleute DO"},{"beruf_id":"54","beruf_name":"St\u00fctzkurs Metall DI"},{"beruf_id":"55","beruf_name":"St\u00fctzkurs Metall MI"},{"beruf_id":"56","beruf_name":"St\u00fctzkurs Zimmerleute DI"},{"beruf_id":"103","beruf_name":"Unterhaltspraktiker\/in EBA"},{"beruf_id":"104","beruf_name":"Vorlehre Metall"},{"beruf_id":"105","beruf_name":"Vorlehre VLB 21-22 C"},{"beruf_id":"106","beruf_name":"Zeichner\/in EFZ, Architektur"},{"beruf_id":"57","beruf_name":"Zimmermann\/Zimmerin EFZ"}]

jQuery 解决方案:。

    function fetchOccupations() {
  var occupationSelectionCode = '<h2>Berufsauswahl</h2>' +
    '<select class="form-control" name="occupationSelection" id="occupationSelection">' +
    '<option value="">Please select an occupation...</option>' +
    '</select>' +
    '<br>';

  $('#occupation').append(occupationSelectionCode);
  $('#occupationSelection').on('change', function () {
    $
    console.log($('#occupationSelection').val());
    fetchClasses();
    $('#class').fadeTo("slow", 1);
  })

  $.getJSON(occupationApi)
    .done(function (occupationsData) {
      $.each(occupationsData, function (_occupationIndex, occupationsData) {
        $('#occupationSelection').append($('<option value="' + occupationsData.beruf_id + '">' + occupationsData.beruf_name + '</option>'));
      })
    })
    .fail(function (error) {
      console.log("Request Failed: " + error);
    })
}

PHP解决方案:

<?php
$connect = new mysqli("127.0.0.1","root","");

            if ($connect -> connect_errno)
                {
                    echo "Failed to connect to MySQL: " . $connect -> connect_error;
                    exit();
                }

                    $connect -> select_db("Your Database");
                if ($result = $connect -> query("Your query")) 
                {
                    
                }
                echo "<select>";
                while($row = mysqli_fetch_array($result)) 
                {
                    echo "<option>" . $row['Your columns'] . "</option>"
                }
                echo "</select>"
?>

请注意,对于 PHP 解决方案,您将需要在 PhpMyAdmin 中的本地设置数据库,例如

希望对你有帮助:)

【讨论】:

  • PHP解决方案,对于第一个select的selected选项,如何改变select的选项?我猜它没有写,因为它只是一个例子。不管怎样,谢谢你的回答。
  • @Simon 我不是 PHP 专业人士,但我认为它应该在您选择一个选项时自动执行。这是一种乐趣。
猜你喜欢
  • 1970-01-01
  • 2018-01-11
  • 1970-01-01
  • 2021-04-23
  • 1970-01-01
  • 2016-10-11
  • 1970-01-01
  • 1970-01-01
  • 2020-06-11
相关资源
最近更新 更多