Frage

Ich schreibe eine ziemlich einfache App, die Backbone benötigt.js-Modelle und Laravel 4-Modelle müssen synchron sein.Probleme entstehen, wenn ich die Laravel-Modelle einbeziehe Carbon Reisedaten.Mein Laravel-Controller sieht so aus:

class OrderController extends \BaseController {
    ...
    public function update($id = null) {
        ...
        if (Request::ajax()) 
            return $order;
        ...
    }
}

Dies antwortet erfolgreich mit einer JSON-Darstellung von $order, die die Clientseite verwendet, um synchron zu bleiben.Kohlenstoffdaten werden jedoch wie folgt als Kohlenstoffobjektdarstellung zurückgegeben:

{
    "delivered_at":{"date":"2014-02-25 12:55:29","timezone_type":3,"timezone":"America\/Argentina\/Buenos_Aires"}
}

Ich könnte es ziemlich einfach schaffen, dies als Javascript-Datumsobjekt zu interpretieren, aber wenn dieses Objekt zu Laravel zurückkehrt, entfernt JSON das Carbon klasse und Eloquent lesen das nicht als Datum:

[2014-02-25 12:58:32] log.ERROR: exception 'ErrorException' with message 'preg_match() expects parameter 2 to be string, array given' in vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:2210
Stack trace:
#0 [internal function]: Illuminate\Exception\Handler->handleError(2, 'preg_match() ex...', '/Users/maurospi...', 2210, Array)
#1 vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(2210): preg_match('/^(\d{4})-(\d{2...', Array)
#2 vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(2151): Illuminate\Database\Eloquent\Model->fromDateTime(Array)
#3 vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php(306): Illuminate\Database\Eloquent\Model->setAttribute('delivered_at', Array)
#4 app/controllers/OrderController.php(120): Illuminate\Database\Eloquent\Model->fill(Array)
#5 [internal function]: OrderController->update('91')
#6 vendor/laravel/framework/src/Illuminate/Routing/Controllers/Controller.php(138): call_user_func_array(Array, Array)
#7 vendor/laravel/framework/src/Illuminate/Routing/Controllers/Controller.php(115): Illuminate\Routing\Controllers\Controller->callMethod('update', Array)
#8 vendor/laravel/framework/src/Illuminate/Routing/Router.php(985): Illuminate\Routing\Controllers\Controller->callAction(Object(Illuminate\Foundation\Application), Object(Illuminate\Routing\Router), 'update', Array)
#9 [internal function]: Illuminate\Routing\{closure}('91')
#10 vendor/laravel/framework/src/Illuminate/Routing/Route.php(80): call_user_func_array(Object(Closure), Array)
#11 vendor/laravel/framework/src/Illuminate/Routing/Route.php(47): Illuminate\Routing\Route->callCallable()
#12 vendor/laravel/framework/src/Illuminate/Routing/Router.php(1016): Illuminate\Routing\Route->run(Object(Illuminate\Http\Request))
#13 vendor/laravel/framework/src/Illuminate/Foundation/Application.php(574): Illuminate\Routing\Router->dispatch(Object(Illuminate\Http\Request))
#14 vendor/laravel/framework/src/Illuminate/Foundation/Application.php(550): Illuminate\Foundation\Application->dispatch(Object(Illuminate\Http\Request))
#15 public/index.php(49): Illuminate\Foundation\Application->run()
#16 {main} [] []

Also muss ich entweder:

  1. Erweitern Sie die JsonResponse-Klasse, um Kohlenstoffdaten in Zeichenfolgendarstellungen zu konvertieren.
  2. Erweitern Sie die Eloquent-Klasse, um stdClass-Objekte der zu interpretieren Carbon klassenstruktur bis dato.
  3. Tu etwas, das mir eindeutig fehlt, Laravel 4 behauptet, in RUHE großartig zu sein, also denke ich, dass mir etwas fehlt.
War es hilfreich?

Lösung

Zunächst schlage ich vor, dass Sie die API von den Controllern trennen.Verwenden Sie Ressourcen für API-Aufrufe.

Für das an Laravel zurückgegebene Objekt weiß ich nicht, wie Sie es verarbeiten, um den Fehler zu erhalten, aber Sie sollten eine neue Carbon-Instanz initiieren, wenn Sie ein Carbon-Datum wünschen.Andernfalls könnten Sie das Datum einfach als Zeichenfolge zurückgeben, Laravels Modell erledigt den Rest.

Angenommen, das zurückgegebene Objekt ist:

{
    "delivered_at":{"date":"2014-02-25 12:55:29","timezone_type":3,"timezone":"America\/Argentina\/Buenos_Aires"}
}

Und die Variable $data wird die aktuelle Antwort haben, Sie könnten einfach delivered_at überschreiben:

$data->delivered_at = $data->delivered_at->date;

Oder wenn Sie ein Carbonobjekt wollen:

$data->delivered_at = new \Carbon\Carbon($data->delivered_at->date, $data->delivered_at->timezone);

Andere Tipps

Dies könnte etwas spät kommen, aber normalerweise benutze ich Accessoren und Mutatoren, um dies zu erreichen.Zum Beispiel, wenn ich alles will created_at und updated_at felder, die immer im ATOM-Format zurückgegeben werden sollen, erstelle ich eine Basismodellklasse, die erweitert wird Eloquent was jedes andere Modell erbt:

use Carbon\Carbon as Carbon;
use Illuminate\Database\Eloquent\Model as Model;

class BaseModel extends Model {

    public function getCreatedAtAttribute($value)
    {
        return Carbon::parse($value)->toATOMString();
    }

    public function setCreatedAtAttribute($value)
    {
        $this->attributes['created_at'] = Carbon::parse($value)->toDateTimeString();
    }

    public function getUpdatedAtAttribute($value)
    {
        return Carbon::parse($value)->toATOMString();
    }

    public function setUpdatedAtAttribute($value)
    {
        $this->attributes['created_at'] = Carbon::parse($value)->toDateTimeString();
    }
}

Dies ist möglicherweise nicht dasselbe, aber ich würde diesen Fehler erhalten, wenn ich mit Zeitstempeln und Kohlenstoff arbeite, aber die Verwendung von strtotime () für die Daten, die ich übergeben habe, hat mein Problem gelöst.

Wie Sie mit Daten sowohl in Backbone als auch in Laravel umgehen, wird Auswirkungen haben.
Sie müssen ein Datumsformat auswählen und sich daran halten.Stellen Sie dann sicher, dass beide Seiten in dieses Format konvertieren, wenn Sie Daten an das JS und die Controller zurück- und weiterleiten.

Wenn Sie ein reines JavasScript-Datumsobjekt senden, wird eine Datumszeichenfolge zurückgegeben, die folgendermaßen aussieht
"Sat Apr 19 2014 00:00:00 GMT+0200 (South Africa Standard Time)"
Was nicht so schön ist, da PHP's strtotime endet damit, es funky zu analysieren.

hier ist ein Beispiel:

$jsdate = "Sat Apr 19 2014 00:00:00 GMT+0200 (South Africa Standard Time)";
$carbon = Carbon::createFromTimestamp(strtotime($jsdate));
$iso8601 = $carbon ->format(Carbon::ISO8601)
//output '1970-01-01T02:00:00+0200' which is a UNIX timestamp 0.

Warum dieses Datum? vielleicht kann es jemand anderes besser ausarbeiten als ich.Sie können ein benutzerdefiniertes Datumsformat verwenden, um es richtig zu lesen, aber verwenden Sie stattdessen ein Format, das beide verstehen können.

Wie ISO 8601

//javascript
var jsdate = (new Date()).toISOString();

Und in PHP sollte Carbon in der Lage sein, damit ohne Probleme umzugehen

Wenn Sie die Datumsspalte Ihres Modells erhalten möchten (created_at) im String-Format wie folgt verwenden:

$response['created_at'] = Carbon::parse($model->created_at)->toDateString();

das wird sich ändern

created_at = {"date":"2014-02-25 12:55:29","timezone_type":3,"timezone":"America\/Argentina\/Buenos_Aires"}

in diese:

created_at = "2014-02-25 12:55:29"

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top