【问题标题】:communication between PHP and JS when a row is added in JSJS中添加一行时PHP和JS之间的通信
【发布时间】:2020-04-07 22:56:43
【问题描述】:

我有一个php代码如下图:

PHP代码:

<?php     
$output['house_sitting_date_yes_no']=$_POST['house_sitting_date_yes_no'];

if(file_exists('../feeds/ptp-ess_landing_house.json')){
    $data = json_decode(file_get_contents('../feeds/ptp-ess_landing_house.json'));
}
?>

<?php if($data) { ?>
<form>
    <!-- Sitting Days START -->
    <div class="sitting-days" style="display:flex; justify-content:center; margin-bottom:20px;">
        <!-- Yes/No START -->
        <div class="yes-no">
            <h4 style="text-align:center;">Yes/No</h4>
            <select name="house_sitting_date_yes_no" id="house-yes-no" style="height:24px;">
                <option value="nada" <?php if($data->{"house_sitting_date_yes_no"}=="nada"){echo 'selected';}?>>Please choose an option</option>
                <option value="yes" <?php if($data->{"house_sitting_date_yes_no"}=="yes"){echo 'selected';} ?>>Yes</option>
            </select>
        </div>
        <!-- Yes/No END -->
    </div>
    <!-- Sitting Days END -->
</form>
<? } else {
echo 'Cannot read JSON settings file';
}
?>

上面的php代码对应下面的fiddle。在小提琴中,它在单击 Javascript 中的按钮时添加了一个新行。 我没有在上面的 php 代码中包含 JS 代码。

添加新行 按钮让我们可以根据需要添加任意数量的行。添加后我们可以在输入框中输入Yes,然后保存。

问题陈述:

我目前面临一个问题。当我添加新行时,表单会被保存,但新添加的行会被删除,只留下一行(日期和是/否)

我想知道我应该在上面的 php 代码中进行哪些更改,以便当我们添加新行时,它应该有一些与之关联的值,这样当我们保存表单时,新添加的行应该保留 有他们可敬的价值观。

当有一行时(当我不添加新行时),所有内容都从 JSON 中提取,并且工作正常。

【问题讨论】:

  • 在两个选择中更改名称,该名称已显示在函数 house_sitting_date_yes_no[] 中,它将作为数组发送到 $_POST。
  • @miguelcalderons 我想知道你能否给我一个答案。对此的任何帮助将不胜感激。
  • 警告,您将面临此代码的潜在安全问题。将任意数据插入 HTML 上下文时始终使用htmlspecialchars()

标签: javascript php arrays json select


【解决方案1】:

您需要对 HTML、JS 和 PHP 进行一些更改才能使其正常工作。从 JS 到 PHP 不需要通信。表单提交已经可以了,对吧?

修改name属性值。

因为您的代码中有多个selectinput 元素,您希望能够将这些元素的所有值发送到服务器。但是因为它们都具有相同的name 属性值,您需要对这些值进行修改。

在名称末尾添加[]。这使 PHP 可以将每个 house_sitting_date_yes_no 读取为一个数组。这意味着,在这种情况下,页面上的每个 select 字段值都将在全局 $_POST 变量中发送到服务器。

查看下面的示例。

<select name="house_sitting_date_yes_no[]">
  ...
</select>

名称末尾有[],表示house_sitting_date_yes_no同名下会有多个值。

<?php
$_POST[ 'house_sitting_date_yes_no' ] // array( 'yes', 'no', 'nada' )
?>

在服务器端,您可以像往常一样访问这些值。但在这种情况下,它不是一个字符串,而是一个包含多个字符串的数组。每个字符串一个,在本例中,选择字段。

一个 ID 只能使用一次。改用类。

您的newRow 函数会创建一个新行。这是一种完美的方法,但该函数还输出带有id 的元素。 ID 必须是唯一的,并且不能在页面上多次出现。

只要可以删除 id,就删除它们并改用一个类。或者让它们像应有的那样独一无二。

以 JSON 格式存储值

您已经开始着手打开和解码 JSON 文件了。我假设您希望使用更多数据更新 JSON,而不是覆盖当前数据。

由于数据将存储在编码为 JSON 的关联数组中,因此可以使用array_merge_recursive 来组合这些数组及其值。

在组合值后,将数组编码回 JSON 并使用 file_put_contents 再次保存您的文件。

$output = array();
$output['house_sitting_date'] = $_POST['house_sitting_date'];
$output['house_sitting_date_yes_no'] = $_POST['house_sitting_date_yes_no'];

$file_url = '../feeds/ptp-ess_landing_house.json';

if (file_exists($file_url)) {

  // Get current file.
  $current_data = json_decode(file_get_contents($file_url));

  // Combine data if possible, or create a new data.
  if (is_array($current_data)) {
    $new_data = array_merge_recursive($current_data, $output);
  } else {
    $new_data = $output;
  }

  // Update the file with new data.
  $updated_data = json_encode($new_data);
  file_put_contents($file_url, $updated_data);
}

希望对你有所帮助。

【讨论】:

  • @NVRM 我已经编辑了我的问题。希望这是有道理的。通过脚本添加的行应该有一些与之关联的值。
【解决方案2】:

好吧,我在您的代码中看到的是我在使用 PHP 时使用的旧方式

我曾经将 PHP 与 HTML 和 Javascript 混合使用,这在大型项目中使事情变得更难维护和调试,尤其是多年以后。你最终会得到许多 if else 语句,这可能会使你的代码复杂化

如果 PHP 服务器由于共享主机流量或延迟而挂起,至少客户端浏览器不会挂起。 XHR 和 Rest API 对我来说是最棒的时刻......

所以我改变了使用 Web 技术的方式,开始使用其他 API 客户端并将前端和后端技术分开

这是我的建议

  1. HTML 表单、XHR 和 Jasvascript 发布到其余的 PHP 服务器 每个 onclick 事件(这使浏览器保持快速,并且在使用后台服务时不会像 php 页面有时那样挂起)

  2. 服务器处理每个请求,从文件中读取 JSON 并 插入新条目然后保存文件(PHP 仅在后台)

  3. Javascript 然后刷新 JSON 缓存。在 XHR 请求结束时显示日期页面(通过添加诸如 async 和 await 之类的关键字来实现)

这里是开始..

将此文件称为 post.PHP

        <?php
    // Headers
    header('Access-Control-Allow-Origin: *');
    header('Content-Type: application/json');
    header('Access-Control-Allow-Methods: POST');
    header('Access-Control-Allow-Headers: Access-Control-Allow-Headers,Content-Type,Access-Control-Allow-Methods, Authorization, X-Requested-With');

    if($_POST)
    {
    echo json_encode($_POST);
    //Open your Existing JSON file here and do the edits to append the new data 
    //Note weather your data passed or failed you have to respond back to the XHR request in the front end with json_encode...



    }else{

    echo json_encode(
            array('message' => 'Post  Created')
    );
    }



    ?>

它与休息客户端接入点相同。此文件是您使用更新编辑 json 的位置...

sn-p 是 XHR 的前端,是一种从 HTML 表单中提取表单数据的特殊技术

function rowAdd(event) {
        document.getElementById("rows")
          .insertAdjacentHTML('beforeend', newRow());
    }
// Iterator to get allow unique for ID;s
let i =0 ;

      function newRow() {

            i++;
      return `
        <div id="default-node" class="sitting-days" style="display:flex; justify-content:center; margin-bottom:20px;">
            <div class="select-date" style="margin-right:30px;">
                <input type="date" id="house-sitting-date`+i+`" name="house_sitting_date`+i+`" value="">
            </div>
            <div class="yes-no">
                <select name="house_sitting_date_yes_no`+i+`" id="house-yes-no`+i+`" style="height:24px;">
                    <option value="nada" selected>Please choose an option</option>
                    <option value="yes">Yes</option>
                    <option value="no">No</option>
                </select>
            </div>
        </div>
      `
    }





let xtart = document.getElementById('xhrStart');


xtart.addEventListener('click',function(){console.log('Xstarted')

                // First iterate over the form and get all the form Values
                var element = {};
                var data = new FormData(theForm);

                // Display the key/value pairs
                for(var pair of data.entries()) {
                       // console.log(pair[0]+ ', '+ pair[1]);
                       element[ pair[0].toString() ] = pair[1];
                }
                console.log(element);


                // Time to send the control over to PHP to do its magic

                let xhr = new XMLHttpRequest();

                xhr.open('POST', 'post.php');
                xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");


                xhr.responseType = 'json';
                xhr.send(JSON.stringify(element));
                //xhr.send();

                // the response is {"message": "Hello, world!"}
                xhr.onload = function() {
                  let responseObj = xhr.response;
                  alert(responseObj.message); // Hello, world!
};



});
<h3 style="text-align:center;margin-top:45px;">Sitting Days</h3>
<div class="add-new-row-button">
    <input type="button" id="addRow" value="Add New Row" onclick="rowAdd()" />
</div>
<form id='theForm'>
<div id="rows">
    <div class="sitting-days" style="display:flex; justify-content:center; margin-bottom:20px;">
        <div class="select-date" style="margin-right:30px;">
            <h4 style="text-align:center;">Select Date</h4>
            <input type="date" id="house-sitting-date" name="house_sitting_date" value="">
        </div>
        <div class="yes-no">
            <h4 style="text-align:center;">Yes/No</h4>
            <select name="house_sitting_date_yes_no" id="house-yes-no" style="height:24px;">
                <option value="nada" selected>Please choose an option</option>
                <option value="yes">Yes</option>
            </select>
        </div>
    </div>
</div>
<input type='button' value='Submit' id='xhrStart'>

注意我给了表单一个 ID 并创建了迭代器,所以表单中的每个新元素都是唯一的

这里是sn-p ...

PHP 也让您对是否收到天气数据一无所知,使用 XHR 可以让您使用 Google 调试工具轻松查看服务器响应... Node JS、react 和所有其他伟大的技术都使用了与 rest api 相同的原理,因为它更简单,并且使在 chrome 上的调试变得轻而易举

这是调试的图像

相信这会有所帮助,让您的工作效率更高

【讨论】:

    【解决方案3】:
    <?php 
    
    echo "<div id='demo'></div>"; 
    
    ?> 
    
    <script type="text/JavaScript"> 
    
    
    // Function is called, return  
    
    // value will end up in x 
    
    var x = myFunction(11, 10);    
    
    document.getElementById("demo").innerHTML = x; 
    
    
    // Function returns the product of a and b 
    
    function myFunction(a, b) { 
    
    return a * b;              
    
    } 
    
    </script> 
    

    【讨论】:

    • 答案应该有解释。
    猜你喜欢
    • 2013-03-25
    • 2020-09-24
    • 2012-08-17
    • 1970-01-01
    • 2021-02-02
    • 2023-04-06
    • 2012-12-14
    • 2021-02-07
    • 1970-01-01
    相关资源
    最近更新 更多