2012-01-04 42 views
14

可以說我有一個叫約翰與PARAMS型號:Backbone.js的並用的Silex(PHP)的REST API

{ 
    Language : { 
     code : 'gr', 
     title : 'Greek' 
    }, 
    Name : 'john' 
} 

所以現在,當我觸發John.save()它公佈這些服務器:

post params http://o7.no/ypvWNp

與頭:

headers http://o7.no/x5DVw0

在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(); 

但首先var_dump返回NULL當然第二的var_dump工作,因爲我直接從php://input資源獲取請求。我不知道我怎麼會從Silex的

獲得使用Request對象的PARAMS

感謝

回答

15

這是很容易實際。

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 
$ 

備選地看(稍微過時)RestServiceProvider

編輯:我把這個答案變成了cookbook recipe in the silex documentation

+0

你好,非常感謝!這是一個解決方案!儘管我相信Silex應該在默認情況下保留它,而不需要添加'before'過濾器。關於內容類型,'$ request-> headers-> get('Content-Type')'返回application/json; charset = UTF-8',所以我寧願這樣檢查:if('application/json'=== strstr($ request-> headers-> get('Content-Type'),';',true) )'或者更像這樣:'if(false!== strpos($ request-> headers-> get('Content-Type'),'application/json'))' – panosru 2012-01-04 22:09:25

+0

'0 === strpos ('even,will adjust my answers。 – igorw 2012-01-04 22:13:46

+0

從php手冊:'此函數可能返回布爾FALSE,但也可能返回一個非布爾值,其值爲FALSE,如0或「」。「,所以我傾向於使用false而不是0 :) – panosru 2012-01-04 22:15:04

4

之前,我已經做了它的方式如下:

$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", 

    ... 
}); 

我已經寫了一個完整的一步一步的教程這裏http://cambridgesoftware.co.uk/blog/item/59-backbonejs-%20-php-with-silex-microframework-%20-mysql

0

我已經通過在請求對象上設置一個額外的$payload屬性來解決它自己

$app->before(function(Request $request) { 
    if (stristr($request->getContentType(), 'json')) { 
     $data    = json_decode($request->getContent()); 
     $request->payload = $data; 
    } else { 
     $request->payload = null; 
    } 
});