19

次のコード サンプルを検討してください。

$m_oDate = new DateTime('2013-06-12 15:54:25');
print_r($m_oDate);
echo $m_oDate->date;

PHP 5.3 以降、これは次の出力 (のようなもの) を生成します。

DateTime Object
(
    [date] => 2013-06-12 15:54:25
    [timezone_type] => 3
    [timezone] => Europe/Amsterdam
)
2013-06-12 15:54:25

ただし、次のコード:

$m_oDate = new DateTime('2013-06-12 15:54:25');
echo $m_oDate->date;

...単にエラーを出力します:

Notice: Undefined property: DateTime::$date in ...

print_r()これらのプロパティをオブジェクトに「追加」するのはなぜですか? これらはマニュアルページDateTimeのクラスの一部として定義されていないことに注意してください。

4

7 に答える 7

14

これは、PHPのバグ #49382 として報告されています。

PHP 5.3 では、デバッグを支援するために、print_r()のインスタンスが保持する基になるタイムスタンプ値の詳細を表示できる内部機能が追加されました。DateTimeこの変更の副作用は、オブジェクトがテキストにダンプされるときに、これらのファントム パブリック プロパティがインスタンスに追加されることです。

リフレクションを使用してこれらのプロパティにアクセスすることで同じ効果を得ることができます。プロパティにアクセスする必要がある場合は、リフレクションを使用する方法が適しているため、エラーは発生しません。

ただし、これらのプロパティを実際に使用するべきではないことに注意してください。これらのプロパティはオブジェクトのメンバーとして定義されていないため、将来の PHP バージョンで同じデータを保持し続ける (または存在する) という保証はありません。情報にアクセスする必要がある場合は、代わりに API の一部として定義されている次のメソッドを使用します。

// $obj->date
$obj->format('Y-m-d H:i:s');

// $obj->timezone
$obj->getTimezone()->getName();
// or...
$obj->getTimezone()->getOffset();
// or...
$obj->getTimezone()->listAbbreviations(); // returns an array, so may need 
                                          // further processing to be of use

注意: timezone_typePHP API を介してプロパティにアクセスすることはできません。これは内部値であり、ユーザーランドでは役に立ちません。これはtimezone、オブジェクトがダンプされるときに保持される文字列のタイプを記述するためです。つまり、上記のコード サンプルでタイムゾーン情報を取得する 3 つのメソッドの 1 つです。完全を期すために、可能な値は次のように定義されています。

値 | タイプ | ユーザーランド相当
------+--------------------------------------+---------------------------------- ---------------
  1 | 時間オフセット | DateTimeZone::getOffset() 
  2 | タイムゾーンの略語 | DateTimeZone::listAbbreviations() 
  3 | タイムゾーン識別子 | DateTimeZone::getName()
于 2013-06-12T13:01:42.763 に答える
9

いくつかの魔法が発生していますが、それは非常に単純です。

クラスDateTimeには、アクセスするためのパブリック変数 'date' がありません。ただし、PHP の動作の副作用として、そのクラスで print_r または var_dump を呼び出すと変数が作成されます。

その魔法が起こった後、「日付」が利用可能になりますが、利用できないはずです。コードを確実に機能させるには、getTimestamp 関数を使用する必要があります。

于 2013-06-12T13:03:44.310 に答える
9

There's no date property in DateTime; 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.

于 2013-06-12T12:58:33.817 に答える
5

問題はここにあります

static HashTable *date_object_get_properties(zval *object TSRMLS_DC)
{
    // ...
    zend_hash_update(props, "date", 5, &zv, sizeof(zval), NULL);
    // ...

この関数date_object_get_propertiesは、データのダンプが行われたときに呼び出されます ( print_rvar_dumpvar_export)。ハッシュテーブルはデータを表すために更新されますが、残念ながらこれは公開されています。

于 2013-06-12T13:18:55.143 に答える
1

楽しみのために、これを使用して機能させる方法を次に示しますReflection

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

ソース

于 2013-06-12T13:06:15.367 に答える