Tại sao tôi không thể truy cập DateTime-> date trong lớp DateTime của PHP?


94

Sử dụng DateTimelớp, nếu tôi cố gắng chạy mã sau:

$mydate = new DateTime();
echo $mydate->date;

Tôi sẽ nhận lại thông báo lỗi này

Lưu ý: Thuộc tính không xác định: DateTime :: $ date ...

Điều này không có ý nghĩa vì khi chạy var_dump()trên biến $mydate, nó cho thấy rõ ràng rằng thuộc tính này tồn tại và có thể truy cập công khai:

var_dump($mydate);

object(DateTime)[1]
  public 'date' => string '2012-12-29 17:19:25' (length=19)
  public 'timezone_type' => int 3
  public 'timezone' => string 'UTC' (length=3)

Đây có phải là một lỗi trong PHP hay tôi đang làm gì đó sai? Tôi đang sử dụng PHP 5.4.3.


1
Câu hỏi hay. Tôi nghĩ trong giây lát rằng tôi không hiểu ... bất cứ điều gì.
regularmike

Câu trả lời:


147

Đây là một vấn đề đã biết .

Ngày có sẵn thực sự là một tác dụng phụ của việc hỗ trợ var_dump()tại đây - obsck@php.net

Vì một số lý do, bạn không thể truy cập vào tài sản nhưng vẫn var_dumphiển thị nó. Nếu bạn thực sự muốn lấy ngày ở định dạng đó, hãy sử dụng DateTime::format()hàm.

echo $mydate->format('Y-m-d H:i:s');

1
Tại sao người ta không muốn định dạng chính xác này? Nó có định dạng giống như MySQL cho ngày tháng.
Elia Iliashenko

@HelgaIliashenko Tôi không chắc mình hiểu. Tôi chưa bao giờ nói rằng người ta sẽ không muốn định dạng chính xác này.
jeremy

Điều này cũng tương tự nếu sử dụng var_dump hoặc print_r.
AndyGaskell

15

Bên cạnh việc gọi điện, DateTime::format()bạn có thể truy cập tài sản bằng cách sử dụng phản chiếu:

<?php

$dt = new DateTime();
$o = new ReflectionObject($dt);
$p = $o->getProperty('date');
$date = $p->getValue($dt);

Điều này nhanh hơn một chút so với việc sử dụng format()format()định dạng một mốc thời gian đã được định dạng. Đặc biệt nếu bạn thực hiện nhiều lần trong một vòng lặp.

Tuy nhiên đây không phải là một hành vi thường xuyên của PHP. Một báo cáo lỗi đã được gửi với tên @Nile được đề cập trong các nhận xét ở trên.


2

Như đã lưu ý trong các câu trả lời khác, đó là một vấn đề với PHP chưa được giải quyết cho đến ngày hôm nay nhưng nếu nó là 'tác dụng phụ' của var_dump()tôi thì tôi không chắc lắm ..

echo ((array) new DateTime())['date']; // Works in PHP 7.

Điều tôi chắc chắn là nếu các thuộc tính của DateTimenơi được sử dụng bởi chúng tôi, nó sẽ có sẵn. Nhưng giống như nhiều lớp nội bộ, chúng không phải vậy và bạn không nên dựa vào các phương pháp "hacky" hoặc "trục trặc" để sửa mã của mình. Thay vào đó, bạn nên sử dụng API của họ .

echo (new DateTime())->format('Y-m-d H:i:s');

Nếu bạn không hài lòng, bạn có thể mở rộng lớp hoặc có thể sử dụng Carbon để mở rộng nó cho bạn.

echo (new Carbon())->toDateTimeString();

Nếu bạn hiểu cách var_dump()tạo đầu ra giả của một đối tượng, hãy xem__debugInfo()


2

Thuộc tính ngày của DateTime được bảo vệ.

Bạn có thể hiển thị ngày với chức năng định dạng.

<?php

try {
    $time = new DateTime();
    echo($time->format("Y-m-d H:i:s"));
} catch (Exception $e) {
}

Hoặc bạn có thể chuyển đổi thành mảng:

<?php

try {
    $time = (array) new DateTime();
    var_dump($time["date"]);
} catch (Exception $e) {
}

Anh ấy muốn biết tại sao anh ấy không thể truy cập thuộc tính ngày tháng của đối tượng DateTime ... Bạn thấy anh ấy muốn định dạng các giá trị Datetime được lưu trữ ở đâu? "Ymd H: i: s" là định dạng phù thủy ngày theo mặc định!
filipe

Chuyển đổi đối tượng thành mảng - như bạn đề xuất - có lẽ là cách dễ nhất để thực hiện.
Jeffz

0

Nếu bạn chỉ sử dụng var_Dump trước khi hỏi ngày thuộc tính, mọi thứ hoạt động ổn:

$mydate = new DateTime();
var_Dump($mydate);
echo '<br>';
echo $mydate->date;

Điều này mang lại:

object(DateTime)#1 (3) { ["date"]=> string(26) "2017-04-11 08:44:54.000000" ["timezone_type"]=> int(3) ["timezone"]=> string(16) "America/New_York" }
2017-04-11 08:44:54.000000

Vì vậy, bạn thấy ngày thuộc tính tồn tại ngay cả đối với đối tượng. Tôi không thể hiểu được hành vi này. Chỉ cần nhận xét var_Dump và bạn sẽ gặp lại lỗi.


error_reporting (0); echo date ("Ymd H: i: s", strtotime ($ mydate-> date));
Kaushik Das
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.