This question already has an answer here:
Consider the following code sample:
$m_oDate = new DateTime('2013-06-12 15:54:25');
print_r($m_oDate);
echo $m_oDate->date;
Since PHP 5.3, this produces (something like) the following output:
DateTime Object
(
[date] => 2013-06-12 15:54:25
[timezone_type] => 3
[timezone] => Europe/Amsterdam
)
2013-06-12 15:54:25
However the following code:
$m_oDate = new DateTime('2013-06-12 15:54:25');
echo $m_oDate->date;
...simply emits an error:
Notice: Undefined property: DateTime::$date in ...
Why does print_r()
"add" these properties to the object? Note that they are not defined as part of the DateTime
class on the manual page.
You should use
DateTime::format
orDateTimeImmutable::format
as the case may be insteadThere's no
date
property inDateTime
; that's why you're getting(Undefined property: DateTime::$date).
print_r()
performs some introspection on the object to display its contents; this causes the object to magically create the::date
property. This is not documented though, so using this may break your code in the future.You need something like
$m_oDate->format('m-d-Y');
instead.This has been reported as Bug #49382 in PHP.
In PHP 5.3, internal functionality was added to allow
print_r()
to show details of the underlying timestamp value held by an instance ofDateTime
, to assist with debugging. A side effect of this change is that when the object is dumped to text, these phantom public properties are added to the instance.The same effect can be achieved by using reflection to access these properties, and if you need to access the properties then using reflection would be the way to go, so you don't provoke the error.
However, it should be noted that you shouldn't really use these properties - since they are not defined as members of the object, there is no guarantee they will continue to carry the same data (or even exist) in future PHP versions. If you need to access the information, use the following methods, defined as part of the API, instead:
NB: The
timezone_type
property is not accessible through the PHP API. It is an internal value and not useful in userland, because it describes the type of string thattimezone
holds when the object is dumped - i.e. one of the three methods for obtaining timezone information in the code sample above. For completeness, its possible values are defined in the following way:The problem lies here:
The function
date_object_get_properties
is called when any data dumping is made (print_r
,var_dump
,var_export
). The hash table is updated for data representing, unfortunately this is made public.Consider the following code-example:
The most obvious difference to yours is that instead of the
print_r
function a different onesome_func
is called. The expectations might differ because you knowprint_r
but you don't knowsome_func
but that is only to sharpen your senses. Let's wait a moment until I show the definition of that function.The second difference is the name of the property that is getting echoed. Here I've choosen a name that is really exceptional:
{'ROXXOR_IS_BACK!!'}
, again to sharpen your senses.This name is that crazy that is must be obvious not being part of
DateTime
albeit when the example above is executed, it's totally clear that this roxxor property must exists. Program Output:So how come? Yes, you sure already have an idea how that works. The
some_func()
function must have added it. So let's take a look into the functions definition:Yes, it's now clearly visible that this function has added a property to the object. And it also shows that this is totally easily possible with any object in PHP.
Compare with an array in PHP, you can also add new keys when you want to.
This example has not been chosen out of nothing, because this is where objects in PHP come from: They are just syntactic sugar around arrays and this has to with the time when objects in PHP were introduced back in PHP 3:
This is also the simple explanation why it's totally common in PHP that functions can add member variables which have not been defined earlier in the class. Those are always public.
So when you do assumptions about some object having a property or not, take a look where it comes from. It must not be part of the class but might have been added later.
And keep the following in mind:
There is some magic occurring but it's pretty simple.
The class DateTime doesn't have a public variable 'date' that you're meant to access. However, as a side effect of how PHP works, there is a variable created when you call print_r or var_dump on that class.
After that magic happens 'date' is available, but it shouldn't be. You should just use the getTimestamp function to make your code work reliably.