如何处理Laravel上包含碳日期的模型的JSON响应?
-
21-12-2019 - |
题
我正在写一个非常简单的应用程序,需要骨干。js模型和Laravel4模型要同步。当我的Laravel模型涉及到 碳 日期。我的Laravel控制器看起来像这样:
class OrderController extends \BaseController {
...
public function update($id = null) {
...
if (Request::ajax())
return $order;
...
}
}
这成功地响应了一个json表示形式的order order,客户端使用它来保持同步。但是,碳日期作为碳对象表示形式返回,如下所示:
{
"delivered_at":{"date":"2014-02-25 12:55:29","timezone_type":3,"timezone":"America\/Argentina\/Buenos_Aires"}
}
我可以很容易地将其解释为javascript Date对象,但是,当此对象返回到laravel时,JSON会删除 Carbon
类和雄辩未能阅读,作为一个日期:
[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类以将碳日期转换为字符串表示。
- 扩展Eloquent类以解释
Carbon
类结构到日期。 - 做一些我显然错过的事情,Laravel4声称在休息时很棒,所以我想我错过了一些东西。
解决方案
首先,我建议您将API与控制器分开。使用资源进行API调用。
对于返回Laravel的对象,我不知道如何处理它以获得错误,但如果您想要碳日期,您应该启动新的碳实例。否则您只能将日期作为字符串返回,Laravel的模型将处理其余的。
假设返回的对象是:
{
"delivered_at":{"date":"2014-02-25 12:55:29","timezone_type":3,"timezone":"America\/Argentina\/Buenos_Aires"}
}
.
和变量$数据将具有当前响应,您可以简单地覆盖reparted_at:
$data->delivered_at = $data->delivered_at->date;
.
或者如果您想要碳对象:
$data->delivered_at = new \Carbon\Carbon($data->delivered_at->date, $data->delivered_at->timezone);
. 其他提示
这可能会有点晚,但我通常会使用访问器和突变器来实现这一点。例如,如果我想要所有 created_at
和 updated_at
总是要以ATOM格式返回的字段,我创建了一个基模型类。 Eloquent
其他模型都继承了:
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();
}
}
这可能不一样,但是在使用时间戳和碳时,我会收到此错误,但使用我传递的数据上的strtotime(),可以帮助您。
如何处理两个骨干和小牛的日期会产生影响。
您需要选择一个日期格式并坚持下去。然后,确保双方在向后传递数据时转换为该格式并转发到JS和控制器。
如果您发送纯javasscript日期对象,那么它会返回一个看起来像这样的日期字符串
"Sat Apr 19 2014 00:00:00 GMT+0200 (South Africa Standard Time)"
这不是那么好的,因为PHP的strtotime
结束了一个时髦的东西。
这是一个例子:
$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碳中应该能够在没有问题的情况下处理它
如果要在字符串格式中获取模型(created_at
)的日期列:
$response['created_at'] = Carbon::parse($model->created_at)->toDateString();
.
这将改变
created_at = {"date":"2014-02-25 12:55:29","timezone_type":3,"timezone":"America\/Argentina\/Buenos_Aires"}
为此:
created_at = "2014-02-25 12:55:29"