可能的PHP / Javascript竞争条件

时间:2012-02-07 23:43:45

标签: php javascript html ajax race-condition

我对网络编程比较陌生。 Javascript,PHP,Ajax等新手。我一直在谷歌搜索这个问题看似简单的解决方案一段时间了,但已经放弃了。我相信存在竞争条件,但与竞争条件以及PHP和Javascript相关的所有内容似乎都有逐案解决方案。

这是设置: 我有一个输出表的PHP页面。在其中一个表中的一行中,我用一个附加表填充一个单元格。它有5个单元格,我想改变单元格的颜色,以反映机器上wifi卡的信号强度(目前只有两张卡)。所以在填充了一个表并且已经设置了单元格的id之后,我调用了一个javascript函数,它将另一段PHP代码发布到cat / proc / net / wireless,解析并返回我调用的卡的信号强度

问题: 解析无线卡的javascript和PHP代码,获取单元ID并设置颜色适用于一张卡。但是,当我在PHP中的标记内调用Javascript函数时,只有最后一次调用才能执行任何操作。第一个似乎什么都不做。

我完全被难倒了,并且已经用尽所有谷歌搜索条件......

PHP代码:

<?php include('assets/header.inc.php'); ?>
<script type="text/javascript" src="<?php echo _JS_?>/ajax_home_display.js"></script>
<div id="cm_body" onload="return false">
    <?php
        $ap_intf = rtrim(shell_exec("cat /tmp/config | grep AP_DEV | cut -d'=' -f2"));
        $mesh_intf = rtrim(shell_exec("cat /tmp/config | grep MESH_DEV | cut -d'=' -f2"));
        $uptime = rtrim(shell_exec("uptime | awk '{print $3}' | cut -d',' -f1"));

    function display_status_intf($intf, $name) 
    {   
        global $uptime;
        $packet_success = "100%";

        echo "
        <tr>
        <td style=\"font-size:14px; font-weight:bold;\"><pre>$intf [$name]</pre></td>
        <td id=\"sig_status_$intf\">
        <table id=\"intf_status\" class = \"list\" cellpadding=10>
        <td id=\"sig_st_1_$intf\"></td>
        <td id=\"sig_st_2_$intf\"></td>
        <td id=\"sig_st_3_$intf\"></td>
        <td id=\"sig_st_4_$intf\"></td>
        <td id=\"sig_st_5_$intf\"></td>
        </table>
        <td><pre>$uptime</pre></td></td>
        <td style=\"text-align:center;\"><pre id=\"packet_success_$intf\">$packet_success</pre></td>
        </tr>
        <script>update_interface('$intf')</script>
        ";

    }   

        // Make a table
        echo "<table class=\"list\" cellpadding=1>";
        echo "<tr><th>Interface</th><th>Signal Status</th><th>Uptime</th><th>Packet success</th></tr>";
            // Make a row on the table for the first wifi card (wifi0)
            if ($ap_intf)
                display_status_intf($ap_intf, "AP");

        // Add a blank row
        echo "<tr><td colspan=\"7\" height=\"30px\"></td></tr>";
            // Make a row on the table for the second wifi card (wifi1)
            if ($mesh_intf)
                display_status_intf($mesh_intf, "Mesh");

        echo "</table>";
    ?>  
</div>
<?php include('assets/footer.inc.php'); ?>

Javascript代码:

    THRESH1 = -60;
    THRESH2 = -55;
    THRESH3 = -50;
    THRESH4 = -45;

    function update_interface(intf)
    {
        xmlhttpPost("run_interface_status.php","intf="+intf,interface_stat_response);
    }

    function interface_stat_response(strQuery,strResponse)
    {
        var sig_st = [];

        // Trim response
        var test_return = strResponse;
        var intface = strQuery.split("=");
        var intf = intface[1];

        // Get cell ID's, put in an array sig_st
        for (i=1;i<=5;i++)
             sig_st[i] = document.getElementById("sig_st_"+i+"_"+intf);
        // Reset all colors to default
        for (i=1;i<=2;i++)
            sig_st[i].setAttribute("style", "background-color:transparent");

        if (test_return != "err") {
            // Set all colors based on the wifi strength
            sig_st[1].setAttribute("style", "background-color:red");

            if (test_return > THRESH1)
                sig_st[2].setAttribute("style", "background-color:orange");
            if (test_return > THRESH2)
                sig_st[3].setAttribute("style", "background-color:yellow");
            if (test_return > THRESH3)
                sig_st[4].setAttribute("style", "background-color:green");
            if (test_return > THRESH4)
                sig_st[5].setAttribute("style", "background-color:green");
        }
    }

Ajax繁重(如果重要的话)

    function xmlhttpPost(strURL,strQuery,responseFunc)
    {
        var xmlHttpReq = false;
        var self = this;
        // Mozilla/Safari
        if (window.XMLHttpRequest) {
            self.xmlHttpReq = new XMLHttpRequest();
        }
        // IE
        else if (window.ActiveXObject) {
            self.xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
        }
        self.xmlHttpReq.open('POST', strURL, true);
        self.xmlHttpReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        self.xmlHttpReq.onreadystatechange = function() {
            if (self.xmlHttpReq.readyState == 4) {
                responseFunc(strQuery,self.xmlHttpReq.responseText);
            }
        }
        self.xmlHttpReq.send(strQuery);
    }

    function trim(s)
    {
        s = s.replace(/(^\s*)|(\s*$)/gi,"");
        s = s.replace(/[ ]{2,}/gi," ");
        s = s.replace(/\n /,"\n");
        return s;
    }

一些额外的信息:我认为这是一个竞争条件,因为Firebug显示已经触发了两个帖子,每个帖子都返回正确的值,但是当我在响应函数的开头放置一个断点(interface_stat_response())时, Firebug只使用后者$ intf和$ strength变量(wifi1的东西)落入其中一次。

任何一般指针都会很棒。我知道代码不漂亮,但我想变得更好:3

2 个答案:

答案 0 :(得分:0)

在审核完所有内容后,我能提供的最好的就是......

尝试使用jQuery post方法http://api.jquery.com/jQuery.post/

替换AJAX繁重的工作

它需要jQuery,但它应该很容易尝试,它可能会修复它。

jQuery是一个非常有用的工具,通常用于处理AJAX / JS。

如果问题出在您的AJAX繁重工作中,这应该解决它。

答案 1 :(得分:0)

我发现你没有使用jquery。 Jquery有一个漂亮的.live()方法,可以让你更轻松地更新事物。我提到它的原因是因为我看到了:

document.getElementById("sig_st_"+i+"_"+intf)

这就是糟糕的做法。使用css classes标识您的不同设置,并根据其他值进行连接。

我假设你对比赛状况是正确的。我目前无法测试您的代码。如果你想在没有jquery的情况下做事,你必须确保你的js等待php完成加载。如果你真的想以这种方式做事,就我而言,最糟糕的做法是,你需要一个while循环。检查while循环中是否存在元素,直到它们存在,然后四处寻找并设置。

如果你把它换成了一个类,而不是按ID着色,你的结果会更简单,更顺畅。

**不会发布这个,但人们要求澄清