douxiuyi6529 2019-02-13 03:26
浏览 103
已采纳

如何将下拉更改事件链接到PHP函数

Scenario

I have the following HTML code for the drop down menu

<div class="form-group col-sm-2">
  <label>Machine</label><br>
  <select class="combobox form-control col-sm-2" name="machineNumber">
    <option>1</option>
    <option>2</option>
  </select><br>
  <label id="machineSer">Machine Serial Number: <?php echo $serialNumberRemarks; ?></label>
</div>

What I need

When there is a change in the combobox, I need to run the following php function that runs a query and fetch data to display an item accordingly to the label with id machineSer. My php function as follows

<?php
    function labelVal(){
        if(isset($_POST['machineNumber'])){
            $machineName = $_POST['machineNumber'];

            $query = "SELECT machineSerialRemarks FROM machinenames WHERE machineName = '$machineName'";
            $result = mysqli_query($conn, $query);
            $row = mysqli_fetch_array($result);
            $serialNumberRemarks = $row['machineSerialRemarks'];
            return $serialNumberRemarks;
        }
    }
?>

Does anyone knows how to do it? I know this has something to do with Javascript and probably Ajax. I look through some of the Ajax but I don't understand how it works. Is there any way to do this without using Javascript? If that is not possible, how can I link this two with Javascript and Ajax?

</div>
  • 写回答

3条回答 默认 最新

  • dongshijiao2363 2019-02-13 04:40
    关注

    You should use AJAX for this task. You can use either jQuery ajax or vanilla JavaScript ajax.

    I have created a full working example using vanilla JavaScript which I have tested and it works fine.

    Here's the changes I made:

    1. I added an onchange listener to the select element in the HTML e.g onchange="selectMachineNumber()"
    2. I created a javascript function called selectMachineNumber which will be executed everytime the select menu is changed. Within this function we make the ajax request to a php file called machine_number_processing.php (containing your php script).
    3. I echo back a json encoded response containing the serialNumberRemarks variable.
    4. Then I inserted the serialNumberRemarks to your html in a span tag (within your label). The span tag has an id of: machine-serial-number.

    index.html (or whatever the name of your HTML page is)

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <title></title>
    <script>
    //declare a global xmlhttp variable 
    var xmlhttp;
    
    function createXHR(){
      //This function sets up the XMLHttpRequest
      try{
        return new XMLHttpRequest();
      }catch(e){
        //to support older browsers
        try{
          return new ActiveXObject("Microsoft.XMLHTTP");
        }catch(e){
          return new ActiveXObject("Msxml2.XMLHTTP");
        }
      }
    }
    
    function selectMachineNumber(selectElement){
       //this function will be called when there is a change in the machineNumber select menu
       //check the value selected in the console as follows:
       console.log(selectElement.value);
       var machineNumber = selectElement.value;
       //do ajax request
       xmlhttp = createXHR();
       xmlhttp.onreadystatechange = ajaxCallback; //name of our callback function here
       //Ive called the php file machine_number_processing.php but you can call it whatever you like.
       xmlhttp.open("POST", "machine_number_processing.php" ,true);
       xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
       //send our variables with the request
       xmlhttp.send("machineNumber=" + machineNumber);
    }
    
    function ajaxCallback(){
       //this function will be executed once the ajax request is completed
       if(xmlhttp.readyState == 4 && xmlhttp.status == 200){
          //The ajax request was successful.
          //we can now get the response text using xmlhttp.responseText. 
          //This will be whatever was echoed in the php file
          //we also need to parse this as JSON because we used json_encode on the PHP array we sent back 
          var data = JSON.parse(xmlhttp.responseText);
          console.log(data.machineNumber); 
          console.log(data.serialNumberRemarks);
          //insert the serialNumberRemarks to the span tag with id="machine-serial-number"
          document.getElementById("machine-serial-number").innerText = data.serialNumberRemarks;
    
       }
    }
    
    
    </script>
    </head>
    <body>
     <div class="form-group col-sm-2">
      <label>Machine</label><br>
      <select class="combobox form-control col-sm-2" name="machineNumber" id="machineNumber" onchange="selectMachineNumber(this)">
        <option>1</option>
        <option>2</option>
      </select><br>
      <label id="machineSer">Machine Serial Number: <span id="machine-serial-number"></span></label>
    </div>
    </body>
    </html>
    

    machine_number_processing.php

    <?php
      if(isset($_POST['machineNumber'])){
        $machineName = $_POST['machineNumber'];
    
        $query = "SELECT machineSerialRemarks FROM machinenames WHERE machineName = '$machineName'";
        $result = mysqli_query($conn, $query);
        $row = mysqli_fetch_array($result);
        $serialNumberRemarks = $row['machineSerialRemarks'];
    
        //create a PHP array to store the data we will send back to the client side
        $responseData = array(); 
        //store the machineNumber that was submitted into a variable in order to test the ajax request
        //without performing the SQL query.
        $responseData['machineNumber'] = $_POST['machineNumber']; 
    
        //store the $serialNumberRemarks variable into our response array
        $responseData['serialNumberRemarks'] = $serialNumberRemarks;
        echo json_encode($responseData); //echo the response data back to the client
      }
    ?>
    

    Note: As you know (as people have said in the comments) you'll need to look into making your SQL code more secure but for demonstration purposes I have left your PHP code as it is.

    Hope this helps :)

    Edit

    If you just want to test that the ajax request is working (without doing the SQL query) then change your php file to the following

    machine_number_processing.php

    <?php
      if(isset($_POST['machineNumber'])){
        $machineName = $_POST['machineNumber'];
        //create a PHP array to store the data we will send back to the client side
        $responseData = array(); 
        //store the machineNumber that was submitted into a variable in order to test the ajax request
        //without performing the SQL query.
        $responseData['machineNumber'] = $_POST['machineNumber']; 
    
        echo json_encode($responseData); //echo the response data back to the client
      }
    ?>
    

    And in the ajaxCallback function comment out these two lines:

     console.log(data.serialNumberRemarks);
     document.getElementById("machine-serial-number").innerText = data.serialNumberRemarks;
    

    You can check the response you get under the Network tab in developer tools as follows:

    response

    Edit 2-Making the PHP code more secure

    I wanted to show an example of how to use the PHP Data Objects (PDO) extension in your project. This is an interface for accessing databases in PHP.

    It has prepared statements, which helps make the processing more secure (i.e helps to prevent against SQL injection).

    Here's a working example of how you can incorporate it to your code (instead of using mysqli)

    Your file where you set up the connection would be something like as follows:

    connect.php

    <?php
      //Define our connection variables. (really these credentials should be in a file stored in a private folder on the server but i'll them here for simplicity.)
      //set the character set for more security. (I will use utf8mb4. This is a good idea if you want to store emojis. YOu can just use utf8 though.
      define("HOSTDBNAME", "mysql:host=localhost;dbname=machine_app;charset=utf8mb4");     
      define("USER", "root");    
      define("PASSWORD", ""); 
    
      //initiate a PDO connection
      $pdoConnection = new PDO(HOSTDBNAME, USER, PASSWORD);
      $pdoConnection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
      $pdoConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    
      //set the character set for more security. set it to utf8mb4 so we can store emojis. you can just use utf8 if you like.
      $pdoConnection->exec("SET CHARACTER SET utf8mb4");
    
    ?>
    

    Create a file called phpfunctions.php to hold a getSerialNumberRemarks() function which makes the query to the database to get $serialNumberRemarks

    phpfunctions.php

    <?php
      function getSerialNumberRemarks($machineName, $pdoConnection){
        /*
         * This is a function to access the machinenames table using PDO with prepared statements and named parameters.
         * I have included extra comments (for learning purposes) with appropriate information taken
         * from the documentation here: http://php.net/manual/en/pdo.prepare.php
         */
        $serialNumberRemarks = ""; 
        try{
          //We create our $query with our named (:name) parameter markers 
          //These parameters will be substituted with real values when the statement is executed.
          //Use these parameters to bind any user-input, (N.B do not include the user-input directly in the query).    
          $query ="SELECT machineSerialRemarks FROM machinenames WHERE machineName = :machineName";
    
          //We now use the PDO::prepare() method on the query.
          //Note: calling PDO::prepare() and PDOStatement::execute() helps to prevent SQL injection attacks by eliminating the need 
          //to manually quote and escape the parameters.    
          $statement = $pdoConnection->prepare($query);
    
          //We now bind our user-input values.
          //If the user-input is an INT value then use PDO::PARAM_INT, if it is a string then use PDO::PARAM_STR.
          //$machineName will be an INT so bind the value as follows.
          $statement->bindValue(':machineName', $machineName, PDO::PARAM_INT); 
          $statement->execute();
          $statement->setFetchMode(PDO::FETCH_ASSOC);
    
          while($row = $statement->fetch()){
            $serialNumberRemarks = $row['machineSerialRemarks'];
          }
          return $serialNumberRemarks;
        }catch(PDOException $e){
          throw new Exception($e);
        }   
      }
    ?>
    

    The following is the file the AJAX request is going to. We need to include the connect.php file and the phpfunctions.php file.

    machine_number_processing.php

    <?php
      require("connect.php"); //this file contains our PDO connection configuration
      require("phpfunctions.php"); //this file contains the getSerialNumberRemarks(); function
    
      if(isset($_POST['machineNumber'])){
        //store $_POST['machineNumber'] into a local variable
        $machineName = $_POST['machineNumber'];
    
        //checks should be done here to check the input is valid i.e it's a valid length, its valid encoding.
        //You should also filter the input. 
        //This can be done with PHP methods such as trim(), htmlspecialchars(), strip_tags(), stripslashes() 
        //and other methods depending on the type of input.
        //In this demonstration I will perform minimal sanitization of the input. 
        //Note: if its a string use FILTER_SANITIZE_STRING instead
        $machineName = filter_var($machineName, FILTER_SANITIZE_NUMBER_INT);
    
        //create a PHP array to store the data we will send back to the client side
        $responseData = array(); 
    
        //call the getSerialNumberRemarks() function and store the serialNumberRemarks returned into our response array
        $responseData['serialNumberRemarks'] = getSerialNumberRemarks($machineName, $pdoConnection);
        echo json_encode($responseData); //echo the response data back to the client
      }
    ?>
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 华为ensp模拟器中S5700交换机在配置过程中老是反复重启
  • ¥15 java写代码遇到问题,求帮助
  • ¥15 uniapp uview http 如何实现统一的请求异常信息提示?
  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看
  • ¥15 关于#Java#的问题,如何解决?
  • ¥15 加热介质是液体,换热器壳侧导热系数和总的导热系数怎么算
  • ¥100 嵌入式系统基于PIC16F882和热敏电阻的数字温度计