Javascript 如何处理在Laravel上包含碳日期的模型的JSON响应?

Javascript 如何处理在Laravel上包含碳日期的模型的JSON响应?,javascript,json,backbone.js,laravel-4,php-carbon,Javascript,Json,Backbone.js,Laravel 4,Php Carbon,我正在编写一个非常简单的应用程序,它要求Backbone.js模型和Laravel 4模型保持同步。当我发现Laravel模型涉及日期时,问题就出现了。我的Laravel控制器如下所示: class OrderController extends \BaseController { ... public function update($id = null) { ... if (Request::ajax()) retur

我正在编写一个非常简单的应用程序,它要求Backbone.js模型和Laravel 4模型保持同步。当我发现Laravel模型涉及日期时,问题就出现了。我的Laravel控制器如下所示:

class OrderController extends \BaseController {
    ...
    public function update($id = null) {
        ...
        if (Request::ajax()) 
            return $order;
        ...
    }
}
这成功地响应了$order的JSON表示,客户端使用它保持同步。但是,碳日期作为碳对象表示返回,如下所示:

{
    "delivered_at":{"date":"2014-02-25 12:55:29","timezone_type":3,"timezone":"America\/Argentina\/Buenos_Aires"}
}
$response['created_at'] = Carbon::parse($model->created_at)->toDateString();
我可以很容易地将其解释为一个javascript日期对象,但是,当这个对象返回到laravel时,JSON删除了
Carbon
类,而Eloquent无法将其理解为日期:

[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} [] []
因此,我需要:

  • 扩展JsonResponse类以将碳日期转换为字符串表示形式
  • 扩展雄辩类,将
    Carbon
    类结构的StdClass对象解释为dates
  • 做一些我明显错过的事情,Laravel 4声称在休息时很棒,所以我想我错过了一些东西

  • 这可能不一样,但我在使用时间戳和carbon时会出现此错误,但在传递的数据上使用strotime()解决了我的问题,可能会对您有所帮助。

    首先,我建议您将API与控制器分开。使用资源进行API调用

    对于返回到Laravel的对象,我不知道您如何处理它以获得错误,但是如果您想要碳日期,您应该启动一个新的碳实例。否则,您可以将日期作为字符串返回,其余部分由Laravel的模型处理

    假设返回的对象是:

    {
        "delivered_at":{"date":"2014-02-25 12:55:29","timezone_type":3,"timezone":"America\/Argentina\/Buenos_Aires"}
    }
    
    变量$data将具有当前响应,您只需在以下位置覆盖已交付的\u:

    $data->delivered_at = $data->delivered_at->date;
    
    或者如果你想要一个碳物体:

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

    您如何处理主干网和Laravel中的日期将产生影响。
    你需要选择一种日期格式并坚持下去。然后确保在向JS和控制器来回传递数据时,双方都转换为该格式

    如果发送一个纯JavasScript日期对象,它将返回一个日期字符串,如下所示
    “2014年4月19日星期六00:00:00 GMT+0200(南非标准时间)”

    这不太好,因为PHP的strotime最后解析它是一个时髦的东西

    以下是一个例子:

    $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.
    
    也许其他人能比我更详细地阐述。 您可以使用自定义日期格式来正确读取它,但可以使用双方都能理解的格式

    比如ISO8601

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

    在php中,Carbon应该能够处理它而不会出现问题

    这可能来得有点晚,但我通常使用访问器和变异器来实现这一点。例如,如果我希望所有在处创建的和在处更新的字段始终以ATOM格式返回,我将创建一个扩展了雄辩的的基本模型类,每个其他模型继承该类:

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

    如果您想以字符串格式获取模型(
    created\u at
    )的日期列,请使用以下命令:

    {
        "delivered_at":{"date":"2014-02-25 12:55:29","timezone_type":3,"timezone":"America\/Argentina\/Buenos_Aires"}
    }
    
    $response['created_at'] = Carbon::parse($model->created_at)->toDateString();
    
    这将改变

    创建时间={“日期”:“2014-02-25 12:55:29”,“时区类型”:3,“时区”:“美洲\/阿根廷\/布宜诺斯艾利斯”}

    为此:


    created_at=“2014-02-25 12:55:29”

    感谢您的回答,并对延迟表示抱歉。我考虑过在API调用中使用资源,我在其他项目中也这样做。我有自己的理由在这个项目中使用常规控制器。您的解决方案需要我编写一个Javascript例程,将JSON表示的Carbon对象转换为JS日期对象并返回。我这样做了,但我希望找到一个更好的捆绑到Laravel解决方案中,因为这种行为在我看来相当标准。