【问题标题】:How to POST backbone model data to DB through Slim php and Paris如何通过 Slim php 和 Paris 将主干模型数据发布到数据库
【发布时间】:2012-02-21 15:06:13
【问题描述】:

我试图了解Backbone.jsSlim PHPParis/Idiorm 可能如何协同工作,但我无法完成流程,从模型属性数据开始,一直到数据库。问题:当我执行 model.save() 时,究竟什么会发送到我的服务器?

客户端:Backbone.js

var Donut = Backbone.Model.extend({
    defaults: {
        name: null,
        sparkles: false,
        creamFilled: false
    },
    url: function() {
        return '/donut';
    }
});

var bostonCream = new Donut({
    name: 'Bawston Cream',
    sparkles: true,
    creamFilled: true
});

bostonCreme.save();  // <-- Problem: Not sure what & format this is sending

我认为以上是我的主要问题。我的理解是,骨干默认情况下会知道发送 POST 数据,因为它是新的。它将它发送到路由的 /donut,但我的问题是它发送了什么?以及以什么格式?我想要的结果是将这些甜甜圈属性保存到我的数据库中。我可以使用 jQuery $.post() 将这个服务器端代码传递给这样的 json ...

var myDonut = {"name":"Jelly Filled", "sparkles":false, "creamFilled":true};
$.post('http://localhost/donut', myDonut);

...它很高兴地接受它,将它保存到我的数据库中。但是在当前设置尝试发送我的主干甜甜圈数据时,我收到 POST 500 Internal Server Error。下面我有一些服务器端代码。

服务器端:Slim PHP w/ Paris

class Donut extends Model {}

$app->post('/donut', function() use ($app) {  // Slim framework routes my POST...

    $donuts = Model::factory('Donut')->create();  // Paris stuff...

    $donuts->name = $app->request()->post('name');  // Slim request parameters...
    $donuts->sparkles = $app->request()->post('sparkles');
    $donuts->creamFilled = $app->request()->post('creamFilled');

    $donuts->save();   // Paris... Save name, sparkles, and creamFilled to my DB
});

我感觉答案就在那里,但我看过的每个示例似乎都缺少一个或另一个难题,我无法得到“啊哈!”片刻。如果这是一个非常无知的问题,我提前感谢您并道歉。 :-P

跟进/编辑:1

你能粘贴错误信息吗?

我在当前状态下收到一个 POST http://localhost:8888/donut 500(内部服务器错误)。我可以通过以下代码获取更多信息。

bostonCream.save({}, {  // REPLACE bostonCream.save();
    success: function(model, response) {
        console.log('SUCCESS:');
        console.log(response);
    },
    error: function(model, response) {
        console.log('FAIL:');
        console.log(response);
    }
});

现在,当我运行骨干网的 save() 时,我仍然收到 500 错误,还有 XMLHttpRequest 作为我的 FAIL 响应。 XMLHttpRequest 中唯一值得注意的线索是 responseText = SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'name' cannot be null。

所以我的猜测是,要么 1) 我在 save() 上搞砸了,因为它没有正确捕获我的属性,2) 它目前正在以我的服务器不正确的格式发送我的属性使用标准的 $app->request()->post() Slim 方法识别(当我尝试直接使用 $_POST 访问时似乎也没有多大作用),3)我的服务器没有正确设置以采用这种方法正在发送的数据。

我注意到的另一件事虽然我不知道该怎么做,但是当我添加时

echo $_POST;

它返回给我一个空数组。仍然给我失败。但是,如果我这样做...

echo json_encode($_POST);

它给了我一个成功,响应是一个 []。里面什么都没有。显然我的 POST 数据仍然不稳定。

【问题讨论】:

    标签: php json backbone.js slim idiorm


    【解决方案1】:

    我想出了一个解决问题的解决方案:如何使用默认主干 save() 和 .sync 从客户端获取数据到服务器 - 传递给 Slim php 框架并通过 Paris/Idiorm 传递到我的数据库。

    我在下面包含了我的工作更新代码:

    客户端:Backbone.js

    var Donut = Backbone.Model.extend({
        defaults: {
            name: null,
            sparkles: false,
            creamFilled: false
        },
        url: function() {
            return '/donut';
        }
    });
    
    var bostonCream = new Donut({
        name: 'Bawston Cream',
        sparkles: true,
        creamFilled: true
    });
    
    bostonCream.save();
    
    /***** If you want to check out the response to save() ? ***
    bostonCream.save({}, {
        success: function(model, response) {
            console.log('SUCCESS:');
            console.log(response);
        },
        error: function(model, response) {
            console.log('FAIL:');
            console.log(response);
        }
    });
    ************************************************************/
    

    服务器端:Slim PHP w/Paris/Idorm

    class Donut extends Model {}
    
    $app->post('/donut', function() use ($app) {
    
        $donuts = Model::factory('Donut')->create();
    
        /* EDIT: Works... but not the Slim way
        $parameters = json_decode(file_get_contents('php://input'), true);
        $donuts->name = $parameters['name'];
        $donuts->sparkles = $parameters['sparkles'];
        $donuts->creamFilled = $parameters['creamFilled']; */
    
        /* SLIM: Using Slim Request Object */
        $requestBody = $app->request()->getBody();  // <- getBody() of http request
        $json_a = json_decode($requestBody, true);
        $donuts->name = $json_a['name'];
        $donuts->sparkles = $json_a['sparkles'];
        $donuts->creamFilled = $json_a['creamFilled'];
    
        $donuts->save();
    
        // echo json_encode($parameters); // Prove you've captured POST data, send it back
    }
    

    现在我的代码很高兴使用 Backbone.js 的默认设置(同步没有更改)并向我的服务器发送正确的模型属性信息,这似乎成功地接受了数据并将其保存到我的数据库中。

    这里的关键似乎是这一行……​​

    /* $parameters = json_decode(file_get_contents('php://input'), true); */
    // EDITED: getBody() method not documented in Develop Doc, only Stable @ time of post
    
    $requestBody = $app->request()->getBody();
    

    【讨论】:

    • 你真是个天才!这对于问题+答案来说是一个加号。谢谢!
    • 嗨 orangewarp,我在这里使用 Backbone 和 Slim 一直在努力解决同样的问题。我觉得很奇怪,虽然你必须使用 getBody() 而根据你的要求使用 post() 或 put() 更合适。
    • 你可以让 Slim 为你解析 JSON。您仍然需要调用 getBody()。请求的 post() 方法不支持 ContentType 中间件所做的解析,并且似乎只处理表单数据。实例化 $app 后,执行以下操作: $app->add(new \Slim\Middleware\ContentTypes()); // 获取解析的传入 JSON。之后,getBody() 返回一个很好的解析数据数组。
    【解决方案2】:

    backbone 将 json 数据发送到您的 php 后端服务器,您应该公开您的 RESTful api 以响应 http 动词,例如 get、post、put、delete 等。

    您的后端 api 负责与数据库通信。

    我不确定 SLIM PHP。它似乎可以处理请求。你能粘贴错误信息吗?

    【讨论】:

    • 我在测试后更新了上面的代码,增加了一些错误信息。我会像@Blacksad 建议的那样做更多阅读。
    【解决方案3】:

    如果您想知道“发送到服务器的确切内容”,您应该查看Backbone.sync function in Backbone's code。这是非常有据可查的,一步一步的。然后,实现您需要的最简洁的方法是编写自己的同步函数,灵感来自 Backbone 的同步。

    此外,查看发送到服务器的内容的一种快速方法是使用浏览器调试控制台(网络选项卡)。您可以在此处比较 Backbone 发送的内容与直接使用 $.post 时发送的内容。如果您需要更多帮助,请发布此信息!

    【讨论】:

    • 我将重新阅读 Backbone.sync 文档。到目前为止,我的理解是它已经有一个我想理解的默认行为! :-) 据我了解,它获取我的模型属性并将它们序列化为 JSON,发送它,如果我对对象进行更改,它期望从服务器返回一个 JSON。使用我发布的示例,当我这样做时... bostonCream.save();我希望发送类似... {"name":"Bawston Creme", "sparkles":true, "creamFilled":true} 的内容。如果这是真的,它应该适用于我上面的代码,但它没有。怀疑!
    • 另外,关于使用控制台。使用 jQuery 的 $.post,我可以将成功或失败回调用于 console.log(data)。我可以回显 $_POST 并查看正在捕获的内容。但是对于 Backbone,我不确定如何查看我的回声 $_POST。 bostonCream.save() 将发送请求并返回......什么?这样的事情会是检查返回什么的正确方法吗? bostonCream.save({ }, {success: function(model, response) {console.log('SUCCESS'); console.log(response); }, error{ console.log('FAIL'); console.log(响应);}});
    • 对不起,我的意思是“阅读主干源代码”(我发布了文档链接,我的错)。在backbone.sync 你会看到发生了什么。
    • 关于控制台,你用的是什么浏览器?试试 Chrome,有一个“网络”标签。您会看到调用和响应。
    • Cmd+Alt+J!我爱铬。 :-) 顺便说一句,您检查其他工具的提示确实很有帮助。谢谢你。到目前为止我只使用控制台,但网络工具非常方便。结果,我意识到我需要更多地了解 HTTP。现在我正在为如何在我的 Slim 后端捕获 PUT 数据而苦苦挣扎。适用于 POST 的技术似乎并没有做到这一点。 Backbone 正确地将模型放到后端。请求有效载荷 = {"id":"5","name":"Aardvark"}。但是我的后端只是在抢空气: json_decode(file_get_contents('php://input'), true) 没有工作。提示?
    猜你喜欢
    • 2014-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-02
    • 1970-01-01
    • 2022-01-15
    • 2014-01-25
    相关资源
    最近更新 更多