从PHP函数中获得一个可理解的结果返回给AJAX调用


Getting an understandable result back to my AJAX call from my PHP function?

我有一个PHP服务器端函数,看起来像这样:

function isHandleAvailable($displayname) {
    $res = user::getRow(
        "SELECT `id` FROM `users` WHERE `displayname` = :displayname",
        array(':displayname' => $displayname)
    );
    if ($res) {
        $res = 'Got a row!';
    } else {
        $res = 'No row :(';
    }
    echo $res;
}

,它用于确定站点上是否已经使用了显示名称。这个函数由以下JavaScript代码调用:

function checkHandleAvailability(displayName, callback) {
    $.ajax({
        type: 'POST',
        url: '/users/isHandleAvailable',
        data: { displayname: displayName }
    })
        .done(function(data, textStatus, jqXHR) {
            isHandleAvailable = data;
        })
        .fail(function() {
            isHandleAvailable = false;
        })
        .always(function() { callback(); });
}

datajqXHR.responseText都是空字符串。我知道PHP代码是工作的,因为我把它放在一个基本的test.php页面,并得到预期的字符串echo ed到屏幕上。

为什么结果没有回到.done函数?

您需要输出值,就像非ajax网页内容一样。

如果您想要与客户端通信结构化/类型化数据(而不是一些文本或HTML), 您可能应该使用JSON。PHP提供了一个方便的json_encode函数来将PHP值序列化为JSON。

输出的方式可能会有所不同,这取决于你的框架,以及你是否认为这应该算作一个"视图",但一个简单的方法是只echo你想要从控制器方法传递给客户端。

您还应该将Content-type头设置为application/json,以让客户端知道您正在通过网络发送JSON。同样,应该在哪里/如何做的具体细节取决于您的框架和体系结构偏好。一种简单但可能不太容易维护的方法是在controller方法中设置header。

那么,把这些放在一起,试试这个:

function isHandleAvailable($displayname) {
    $handleIsAvailable = user::getRow(
        "SELECT `id` FROM `users` WHERE `displayname` = :displayname",
        array(':displayname' => $displayname)
    ) == null;
    // This has to happen before any output.
    header('Content-type: application/json');
    echo json_encode($handleIsAvailable);
}

尝试添加选项"dataType: 'string'",默认为$。Ajax尝试猜测响应的内容,可能这次是错误的。

但是,正如Matt Kantor建议的那样,最佳实践是使用JSON或XML等结构化协议对您的响应进行编码。