【问题标题】:PHP and Prototype's AJAXPHP 和 Prototype 的 AJAX
【发布时间】:2012-06-15 11:50:16
【问题描述】:

我有一个 php 函数,它返回 JSON 以响应 ajax 请求以支付运费。这是php函数:

public function getDeliveryOptions($weight, $postcode)
{

    if($weight == 0)
    {

        return array(array("name" => "Non-Deliverable", "value" => "0.00"));

    }

    $this->db->where('dmc_lower_boundary <=', $weight);
    $this->db->where('dmc_upper_boundary >=', $weight);

    if(preg_match("([aA][bB](3[1-8]|4[1-5]|5[1-6])\s?[1-9][a-zA-Z]{2}|[fF][kK](19|20|21)\s?[1-9][a-zA-Z]{2}|[hH][sS][1-9]\s?[1-9][a-zA-Z]{2}|[iI][vV][1-9]{1,2}\s?[1-9][a-zA-Z]{2}|[kK][aA](27|28)\s?[1-9][a-zA-Z]{2}|[kK][wW][1-9]{1,2}?\s?[1-9][a-zA-Z]{2}|[pP][aA][2-8][0-9]\s?[1-9][a-zA-Z]{2}|[pP][hH]([156789]|1[056789]|[2-5][0-9]){1,2}\s?[1-9][a-zA-Z]{2}|[zZ][eE][1-9]\s?[1-9][a-zA-Z]{2})", $postcode))
    {

        $this->db->where("dm_id = ", 1);
        $this->db->or_where("dm_id =", 3);

    }
    elseif(preg_match("/([bB][tT][1-9]{1,2}\s?[1-9][a-zA-Z]{2}|[iI][mM][1-9]{1,2}\s?[1-9][a-zA-Z]{2}|[tT][rR](21|22|23|24|25)\s?[1-9][a-zA-Z]{2})/", $postcode))
    {

        $this->db->where("dm_id =", 1);
        $this->db->or_where("dm_id =", 4);

    }
    elseif(preg_match("/([gG][yY][1-9]\s?[1-9][a-zA-Z]{2}|[jJ][eE][1-4]\s?[1-9][a-zA-Z]{2})/", $postcode))
    {

        $this->db->where("dm_id =", 1);
        $this->db->or_where("dm_id =", 5);

    }
    else
    {

        $this->db->where("dm_id =", 1);
        $this->db->or_where("dm_id =", 2);

    }

    $this->db->group_by("dm_id");
    $query = $this->db->get("delivery_method_option_views");
    //print_r($query->result());
    //print_r(json_encode($query->result()));
    return(json_encode($query->result()));
}

这是我的 javascript(使用原型)将结果发送到服务器并使用响应来创建单选按钮:

function updateDelivery()
{
if($('deliveryUpdate') == null)
{

    return false;

}

// This 'observes' our form submit - sort of like onsubmit
$('deliveryUpdate').observe('submit', function(evt) {

    // Stop the actual event from happening
    evt.stop();

    // This is the url we submit to - change it as needed
    var url = '/checkout/updateDelivery';

    //This will be the form and div we update
    var containerForm = $('deliveryUpdate');
    var optionsDisplay = $('deliveryOptions');

    // Grab all the info in the form
    var form_data = containerForm.serialize();
    var form = containerForm.innerHTML;

    // Here we make the request
    new Ajax.Request(url, {
        method: 'post',
        parameters: form_data,
        onCreate: function() {
            form = containerForm.innerHTML;
            containerForm.update(form+'<img src="/images/loader.gif" alt="loading..." class="loader" />');
        },
        onSuccess: function(transport) {
            containerForm.update(form);
            NVPResponse = transport.responseText;

            if(NVPResponse !== '[object Array]')
            {

                NVPResponse = new Array(NVPResponse);

            }
            alert(NVPResponse);
            options = "";
            for(i=0; i<NVPResponse.length; ++i)

            {

                options += '<label for="delivery">'+NVPResponse[i].dm_name+'</label><input type="radio" name="delivery" value="'+NVPResponse[i].dmc_price+'" />';

            }

            //optionsDisplay.update(NVPResponse);
            optionsDisplay.update(options);
        }

    });

});

}

如果我只是更新 JSON 结果(对于邮政编码 ab31 2as),我会得到以下信息:

Calculate Delivery Costs[{"dm_id":"1","dm_name":"Royal Mail","dm_admin_name":"Royal Mail","dmc_lower_boundary":"101","dmc_upper_boundary":"250","dmc_price":"3.65"},{"dm_id":"3","dm_name":"Courier","dm_admin_name":"Fed Ex Zone 4","dmc_lower_boundary":"101","dmc_upper_boundary":"250","dmc_price":"4.50"}]

但是,如果我使用选项 var 进行更新,我会在标签文本和单选按钮值所在的位置得到“未定义”。这是在 onSuccess 函数的 for 循环中构建的。有什么想法吗?

编辑

我在 for 循环之前添加了以下代码,因为我试图将 JSON 字符串用作对象而不是对象:

NVPResponse = JSON.parse(NVPResponse);

【问题讨论】:

    标签: php javascript ajax codeigniter for-loop


    【解决方案1】:

    我不是原型方面的专家,但在我看来,您的 NVPResponse 是一个字符串,而不是转换为 javascript 对象。 (参见AJAX(特别是评估 JavaScript 响应)和JSON 的原型文档。

    您的代码似乎还有其他一些问题。

    在 PHP 代码中:

    if($weight == 0)
        {
    
            return array(array("name" => "Non-Deliverable", "value" => "0.00"));
    
        }
    

    你返回一个没有 JSON 化的数组,这是故意的吗?

    另外,好像还有逻辑错误:

    $this->db->or_where("dm_id =", 3);
    

    查询 dm_id = 3,而不管您之前设置的任何“位置”,以便

    $this->db->where('dmc_lower_boundary <=', $weight);
    $this->db->where('dmc_upper_boundary >=', $weight);
    

    如果 dm_id = 3 (或任何其他 or_where 当然)将被忽略。 解决方案可能是这样的:

    $this->db->where_in("dm_id", array(1,3));
    

    编辑:

    在这种情况下,您编写的查询运行良好,但您应该注意到 Codeigniter 不会在其查询中的 OR 参数周围放置括号,因此在同一查询中组合 OR 和 AND 可能会出现问题。 您编写代码的方式查询看起来像这样(工作正常):

    SELECT * FROM (`t_name`) 
    WHERE `dmc_lower_boundary` <= $weight AND `dm_id` = 1 OR `dm_id` = 3
    

    以不同的顺序编写相同的查询(或者有时在编写复杂的查询时)会给您带来非常不同的结果:

    SELECT * FROM (`t_name`) 
    WHERE `dm_id` = 1 OR `dm_id` = 3 AND `dmc_lower_boundary` <= $weight
    

    在经历了一些严重的错误之后,我学会了小心“or_where”:)

    【讨论】:

    • 但是我的数据库查询得到了正确的结果? :S 感谢第一个数组 :)
    • 我的错。 CI 不会在 OR 语句周围加上括号,因此它们往往是错误的。我编辑了答案以反映这一点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-31
    • 1970-01-01
    • 1970-01-01
    • 2019-11-29
    • 1970-01-01
    相关资源
    最近更新 更多