2012-01-29 9 views
18

Estoy tratando de obtener una comprensión de cómo Backbone.js, Slim PHP y Paris/Idiorm podrían trabajar juntos y estoy teniendo problemas para completar el flujo, comenzando con el modelo de datos de atributos, todo el camino a la base de datos. PROBLEMA: ¿Qué se envía exactamente a mi servidor cuando hago model.save()?la forma de publicar los datos del modelo espina dorsal a través de DB php delgado y París

del lado del cliente: 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 

Creo que lo anterior es mi principal problema. Tengo entendido que, por defecto, la red troncal sabrá enviar datos POST ya que son nuevos. Lo envía a/donut que se enruta, pero la pregunta que tengo es ¿QUÉ envía? ¿Y en qué formato? El resultado que quiero es guardar esos atributos donut en mi DB. Me puede pasar el código del lado del servidor de un JSON como esto usando jQuery $ .post() ...

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

... y felizmente se lo lleva, lo guarda en mi base de datos. Pero con la configuración actual tratando de enviar los datos de mi donación de red troncal, recibo el POST 500 Internal Server Error. A continuación tengo un código del lado del servidor.

del lado del servidor: Delgado PHP w/París

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

Tengo la sensación de que la respuesta es por ahí, pero todos los ejemplos que he mirado parece que falta una pieza del rompecabezas u otro y No puedo entender "A-hA!" momento. Te agradezco de antemano y me disculpo si esta es una pregunta realmente ignorante. :-P

SEGUIMIENTO/EDIT: 1

¿Puede pegar los mensajes de error?

Aparece el mensaje POST http://localhost:8888/donut 500 (Error interno del servidor) en el estado actual. Puedo obtener más información con el siguiente código.

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

Ahora en que funciono a save(), sigo teniendo el 500 Error de columna vertebral, sino también XMLHttpRequest como mi respuesta fallar. La única pista notable de XMLHttpRequest es responseText = SQLSTATE [23000]: Integrity constraint violation: 1048 El 'nombre' de columna no puede ser nulo.

Así que mi suposición es que o bien 1) Estoy arruinando algo con el guardado() en el sentido de que no está capturando mis atributos correctamente, 2) Actualmente estoy enviando mis atributos en un formato que mi servidor no está t reconociendo con el estándar $ app-> request() -> post() Métodos delgados (No parece hacer mucho cuando intento acceder directamente con $ _POST tampoco), 3) Mi servidor no está configurado correctamente para tomar el tipo de datos que se envían.

Otra cosa que he notado, aunque no sé qué hacer con él es que cuando agrego

echo $_POST; 

Vuelve a mí una matriz vacía. Todavía me da el FAIL. Si lo hago sin embargo ...

echo json_encode($_POST); 

Me da un ÉXITO y la respuesta es un []. Nada allí. Claramente, mis datos de POST aún son escasos.

Respuesta

30

Se me ocurrió una solución para completar el problema: cómo obtener datos del cliente al servidor utilizando la estructura principal predeterminada save() y .sync - transferido al framework Slim php y pasando por Paris/Idiorm a mi base de datos .

Estoy incluyendo mi código de trabajo actualizado a continuación:

del lado del cliente: 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-lateral: Delgado PHP w/París/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 
} 

Ahora mi código está feliz con la configuración predeterminada de Backbone.js (sin cambios para sincronizar) y el envío de m adecuada Odel atribuye información a mi servidor que parece aceptar con éxito los datos y guardarlos en mi base de datos.

La clave aquí parece ser esta línea ...

/* $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

¡Eres un genio! para eso una ventaja para la pregunta + respuesta. ¡Gracias! –

+0

Hola orangewarp, he estado luchando con el mismo problema aquí usando Backbone y Slim. Me resulta muy extraño, sin embargo, que tengas que usar getBody() mientras que es más apropiado usar post() o put() dependiendo de tu solicitud. – Maarten

+0

Puede hacer que Slim analice el JSON por usted. Aún deberá llamar a getBody(). El método post() de la solicitud no respeta el análisis que realizó el middleware ContentType, y parece que solo trata los datos del formulario. Después de instanciar $ app, haga esto: $ app-> add (new \ Slim \ Middleware \ ContentTypes()); // Obtenga el JSON entrante analizado. Después de eso, getBody() devuelve una buena matriz de datos analizados. –

1

Si usted quiere saber "exactamente lo que se envía al servidor", debería echar un vistazo a la Backbone.sync function in Backbone's code. Está muy bien documentado, paso a paso. Entonces, la forma más limpia de lograr lo que necesita es escribir su propia función de sincronización, inspirada en la sincronización del Backbone.

Además, una forma rápida de ver lo que se envía al servidor es utilizar la consola de depuración del navegador (ficha Red). Aquí puedes comparar lo que se envía por Backbone con lo que se envía cuando usas $ .post directamente. ¡Publique esta información si necesita más ayuda!

+0

voy a releer la documentación Backbone.sync. Mi comprensión hasta ahora es que ya tiene un comportamiento predeterminado, ¡que quiero entender! :-) Por lo que entiendo, toma los atributos de mi modelo y los serializa en JSON, lo envía y espera un JSON a cambio del servidor si realizo cambios en el objeto. Usando mi ejemplo publicado, cuando lo hago ... bostonCream.save(); que esperaba algo como ... { "name": "Bawston Crema", "chispas": true, "creamFilled": true} que se enviará. Si esto fuera cierto, debería funcionar con mi código anterior pero no es así. ¡Sospechar! – jmk2142

+0

Además, con respecto al uso de la consola. Con jQuery's $ .post hay una devolución de llamada de éxito o error que puedo usar para console.log (datos). Puedo repetir $ _POST y ver qué se está capturando o no. Pero con Backbone, no estoy seguro de cómo ver mi eco $ _POST. bostonCream.save() enviará la solicitud y devolverá ... ¿algo? ¿Sería algo así como la forma correcta de verificar lo que se devuelve? bostonCream.save ({}, {success: function (modelo, respuesta) {console.log ('SUCCESS'); console.log (respuesta);}, error {console.log ('FAIL'); console.log (respuesta);}}); – jmk2142

+0

Lo siento, quise decir "leer el código fuente de Backbone" (publiqué un enlace a la documentación, mi error). En backbone.sync verás lo que sucede. – Blacksad

0

espina dorsal envía datos JSON para su servidor backend PHP, que debe exponer su API REST para responder a http verbo como GET, POST, palabras, etc. eliminar y

su api backend es responsable de comunicarse con la base de datos .

No estoy seguro acerca de SLIM PHP. parece manejar la solicitud. ¿Puedes pegar los mensajes de error?

+0

He actualizado el código anterior con algunos más mensajes de error después de la prueba. Voy a leer un poco más, como sugiere @Blacksad. – jmk2142

Cuestiones relacionadas