带有Silex(PHP)的Backbone.js和REST api
假设我有一个叫约翰的模型,上面有几个参数:带有Silex(PHP)的Backbone.js和REST api,php,rest,backbone.js,silex,Php,Rest,Backbone.js,Silex,假设我有一个叫约翰的模型,上面有几个参数: { Language : { code : 'gr', title : 'Greek' }, Name : 'john' } 所以现在,当我触发John.save()时,它会将这些内容发布到服务器: 使用这些标题: Silex中的代码非常简单: <?php require_once __DIR__.'/silex.phar'; $app = new Silex\App
{
Language : {
code : 'gr',
title : 'Greek'
},
Name : 'john'
}
所以现在,当我触发John.save()
时,它会将这些内容发布到服务器:
使用这些标题:
Silex中的代码非常简单:
<?php
require_once __DIR__.'/silex.phar';
$app = new Silex\Application();
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
// definitions
$app['debug'] = true;
$app->post('/api/user', function (Request $request) {
var_dump($request->get('Name'));
$params = json_decode(file_get_contents('php://input'));
var_dump($params->Name);
});
$app->run();
实际上这很容易
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\ParameterBag;
$app->before(function (Request $request) {
if (0 === strpos($request->headers->get('Content-Type'), 'application/json')) {
$data = json_decode($request->getContent(), true);
$request->request = new ParameterBag(is_array($data) ? $data : array());
}
});
然后是一个示例路线:
$app->match('/', function (Request $request) {
return $request->get('foo');
});
和卷曲测试:
$ curl http://localhost/foobarbazapp/app.php -d '{"foo": "bar"}' -H 'Content-Type: application/json'
bar
$
另一种方法是查看(稍微过时的)
编辑:我已经把这个答案变成了一个答案。我以前的做法如下:
$app->post('/api/todos', function (Request $request) use ($app) {
$data = json_decode($request->getContent());
$todo = $app['paris']->getModel('Todo')->create();
$todo->title = $data->title;
$todo->save();
return new Response(json_encode($todo->as_array()), 200, array('Content-Type' => 'application/json'));
});
window.TodoList = Backbone.Collection.extend({
model: Todo,
url: "api/todos",
...
});
在主干集合中,添加以下内容:
$app->post('/api/todos', function (Request $request) use ($app) {
$data = json_decode($request->getContent());
$todo = $app['paris']->getModel('Todo')->create();
$todo->title = $data->title;
$todo->save();
return new Response(json_encode($todo->as_array()), 200, array('Content-Type' => 'application/json'));
});
window.TodoList = Backbone.Collection.extend({
model: Todo,
url: "api/todos",
...
});
我在这里编写了一个完整的分步教程我自己通过在请求对象上设置一个额外的
$payload
属性解决了这个问题
$app->before(function(Request $request) {
if (stristr($request->getContentType(), 'json')) {
$data = json_decode($request->getContent());
$request->payload = $data;
} else {
$request->payload = null;
}
});
你好,非常感谢!这是一个解决办法!虽然我相信Silex在默认情况下应该注意它,而不需要在过滤器之前添加
。关于内容类型,$request->headers->get('content-type')
返回application/json;charset=UTF-8
所以我更喜欢这样检查:if('application/json'==strstr($request->headers->get('Content-Type'),';',true))
或者更像防弹的:if(false!==strops($request->headers->get('Content-Type'),'application/json'))
0==strops(
even,将调整我的答案。在php手册中:此函数可能返回布尔值FALSE,但也可能返回计算结果为FALSE的非布尔值,例如0或“”。
因此我倾向于使用FALSE而不是0:)如果你想用0===strpos
检查abc中是否存在b,你会得到false,但事实并非如此,例如:0===strpos('abc','b')
返回false0==strpos('abc','a')
将返回true,因此最好的方法是false!==strpos('abc','b'))
要做到防弹,我想检查它是否以application/json
开头。