2012-01-29 8 views
18

Próbuję zrozumieć, w jaki sposób mogą współpracować ze sobą Backbone.js, Slim PHP i Paris/Idiorm. Mam problem z ukończeniem przepływu, zaczynając od danych atrybutów modelu, aż do bazy danych. PROBLEM: Co dokładnie jest wysyłane do mojego serwera, gdy wykonuję model.save()?Jak umieścić dane modelu szkieletowego w DB przez Slim php i Paryż

Client-side: 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 

myślę, że powyżej jest mój główny problem. Rozumiem, że szkielet domyślnie będzie wiedział, że wysyła dane POST, ponieważ jest nowy. Wysyła go do/donut, który jest routowany, ale pytanie, które mam, to CO wysyła? I w jakim formacie? Rezultatem, którego chcę, jest zapisanie tych atrybutów pączków do mojego DB. Mogę przekazać ten kod po stronie serwera do json jak to przy użyciu jQuery $ .post() ...

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

... i to szczęśliwie bierze, zapisuje go do mojej bazy danych. Ale przy obecnej konfiguracji próbującej wysyłać dane mojego głównego szkieletu, otrzymuję błąd wewnętrznego serwera POST 500. Poniżej mam kod po stronie serwera.

po stronie serwera: Slim PHP w/Paryż

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 
}); 

Mam wrażenie odpowiedź jest gdzieś tam, ale każdy przykład Sprawdziliśmy wydaje się, że brakuje jednego kawałka układanki lub inny i Nie mogę dostać tego "A-hA!" za chwilę. Z góry dziękuję i przepraszam, jeśli to naprawdę niedorzeczne pytanie. :-P

obserwacji/EDIT: 1

można wkleić komunikaty o błędach?

Otrzymuję POST http://localhost:8888/donut 500 (Wewnętrzny błąd serwera) w bieżącym stanie. Mogę uzyskać więcej informacji za pomocą następującego kodu.

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); 
    } 
}); 

Teraz gdy uruchamiam szkieletowej za save(), wciąż otrzymuję błąd 500, ale także XMLHttpRequest jako moją odpowiedź zawiedzie. Jedyną niezwykłą wskazówką z XMLHttpRequest jest responseText = SQLSTATE [23000]: Naruszenie ograniczenia integralności: 1048 Kolumna "name" nie może mieć wartości NULL.

Zgaduję, że albo 1) coś zepsuję z save(), ponieważ nie przechwytuje poprawnie moich atrybutów, 2) Obecnie wysyła moje atrybuty w formacie, który nie jest moim serwerem. • rozpoznawanie za pomocą standardowych metod $ app-> request() -> post() Slim (nie wydaje się zbytnio robić, gdy próbuję uzyskać dostęp bezpośrednio za pomocą $ _POST), 3) Mój serwer nie jest poprawnie skonfigurowany do pobierania rodzaj danych, które są wysyłane.

Inną rzeczą, jaką zauważyłem, chociaż nie wiem, co zrobić z tym jest to, że kiedy dodać

echo $_POST; 

To powraca do mnie pustą tablicę. Nadal daje mi FAIL. Jeśli jednak to zrobię ...

echo json_encode($_POST); 

Daje mi SUKCES, a odpowiedź jest []. Nic tam nie ma. Najwyraźniej moje dane POST są wciąż niewyraźne.

Odpowiedz

30

Wpadłem na rozwiązanie tego problemu: jak uzyskać dane od klienta do serwera za pomocą domyślnego szkieletu save() i .sync - przekazanego do Slim php framework i przechodząc przez Paris/Idiorm do mojego DB .

Jestem tym moim roboczym zaktualizowanego kodu poniżej:

Client-side: 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); 
    } 
}); 
************************************************************/ 

Sever-side: Slim PHP w/Paryż/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 
} 

Teraz mój kod korzysta z domyślnych ustawień Backbone.js (bez zmian w synchronizacji) i wysyłania właściwego m odel przypisuje informacje do mojego serwera, który wydaje się skutecznie akceptować dane i zapisywać je do mojego DB.

Kluczem wydaje się być ta linia ...

/* $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(); 
+0

Jesteś genialny! za to plus za pytanie + odpowiedź. Dzięki! –

+0

Cześć orangewarp, ja walczyłem z tym samym problemem tutaj, używając Backbone i Slim. Uważam za bardzo dziwne, że musisz użyć getBody(), podczas gdy bardziej odpowiednie jest użycie post() lub put() w zależności od twojego żądania. – Maarten

+0

Możesz mieć Slim analizować JSON dla ciebie. Nadal będziesz musiał wywołać getBody(). Metoda post() żądania nie uwzględnia analizy składniowej oprogramowania pośredniego ContentType i wydaje się zajmować tylko danymi formularza. Po utworzeniu aplikacji $ wykonaj następujące czynności: $ app-> add (new \ Slim \ Middleware \ ContentTypes()); // Pobierz przeanalizowany przychodzący JSON. Następnie getBody() zwraca ładną tablicę analizowanych danych. –

1

Jeśli chcesz wiedzieć "co dokładnie jest wysyłane na serwer", powinieneś rzucić okiem na Backbone.sync function in Backbone's code. Jest to bardzo dobrze udokumentowane, krok po kroku. Najczystszym sposobem na osiągnięcie tego, czego potrzebujesz, jest napisanie własnej funkcji synchronizacji, zainspirowanej synchronizacją Backbone.

Szybkim sposobem sprawdzenia, co jest wysyłane na serwer, jest użycie konsoli debugowania przeglądarki (karta Sieć). Możesz porównać tutaj to, co wysyła Backbone kontra to, co jest wysyłane, gdy bezpośrednio używasz $ .post. Opublikuj te informacje, jeśli potrzebujesz więcej pomocy!

+0

będę ponownie przeczytać dokumentację Backbone.sync. Jak dotąd rozumiem, że ma już domyślne zachowanie, które chcę zrozumieć! :-) Z tego co rozumiem, pobiera moje atrybuty modelu i serializuje je do JSON, wysyła je i oczekuje JSON w zamian od serwera, jeśli dokonam zmian w obiekcie. Używając mojego wysłanego przykładu, kiedy robię ... bostonCream.save(); spodziewałem się czegoś jak ... { "name": "Bawston Creme", "błyskotki": true "creamFilled": true} powinna być wysłana. Jeśli to prawda, powinna działać z powyższym kodem, ale nie działa. Posądzać! – jmk2142

+0

Również w odniesieniu do korzystania z konsoli. Z $ .post jQuery jest wywołanie zwrotne sukcesu lub awarii, które mogę użyć do console.log (dane). Mogę echo $ _POST i zobaczyć, co jest przechwytywane, czy nie. Ale z Backbone, nie jestem pewien, jak wyświetlić moje echo $ _POST. bostonCream.save() wyśle ​​żądanie i zwróci ... coś? Czy coś takiego może być właściwym sposobem sprawdzenia, co jest zwracane? bostonCream.save ({}, {success: funkcja (model, odpowiedź) {console.log ("SUCCESS"); console.log (odpowiedź);}, błąd {console.log ("FAIL"); console.log (odpowiedź);}}); – jmk2142

+0

Przepraszam, miałem na myśli "przeczytaj kod źródłowy szkieletu" (zamieściłem link do dokumentacji, moja wina). W backbone.sync zobaczysz, co się stanie. – Blacksad

0

kręgosłup wysyła dane json do serwera php backend, który należy narażać REST API w odpowiedzi http czasownika jak GET, POST, włóż, usuwać itd

Twój backend API jest odpowiedzialny za komunikację z bazą danych .

Nie jestem pewien co do SLIM PHP. wydaje się, że obsługuje to żądanie. Czy możesz wkleić komunikaty o błędach?

+0

Po wykonaniu testu zaktualizowałem powyższy kod o kilka dodatkowych komunikatów o błędach. Zrobię więcej czytania jak sugeruje @Blacksad. – jmk2142