php - var_dump - print_r() agrega propiedades a los objetos DateTime



var_dump($_post) (5)

Esta pregunta ya tiene una respuesta aquí:

Considere el siguiente ejemplo de código:

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

Desde PHP 5.3, esto produce (algo como) la siguiente salida:

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

Sin embargo el siguiente código:

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

... simplemente emite un error:

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

¿Por qué print_r() "agrega" estas propiedades al objeto? Tenga en cuenta que no están definidos como parte de la clase DateTime en la página del manual .

https://code.i-harness.com


Considere el siguiente ejemplo de código:

$m_oDate = new DateTime('2013-06-12 15:54:25');
some_func($m_oDate);
echo $m_oDate->{'ROXXOR_IS_BACK!!'};

La diferencia más obvia a la suya es que, en lugar de la función print_r , se llama a una función diferente de some_func . Las expectativas pueden diferir porque sabe print_r pero no conoce some_func pero eso es solo para agudizar sus sentidos. Esperemos un momento hasta que muestre la definición de esa función.

La segunda diferencia es el nombre de la propiedad que se está haciendo eco. Aquí elegí un nombre que es realmente excepcional: {'ROXXOR_IS_BACK!!'} , nuevamente para agudizar tus sentidos.

Este nombre es el loco que debe ser obvio al no ser parte de DateTime aunque cuando se ejecute el ejemplo anterior, está totalmente claro que esta propiedad roxxor debe existir . Salida del programa:

PHP never lets you down.

Entonces, ¿cómo es que? Sí, seguro que ya tienes una idea de cómo funciona eso. La función some_func() debe haberla agregado. Así que echemos un vistazo a la definición de funciones:

function some_func($m_oDate) {
    $m_oDate->{'ROXXOR_IS_BACK!!'} = 'PHP never lets you down.';
}

Sí, ahora es claramente visible que esta función ha agregado una propiedad al objeto. Y también muestra que esto es totalmente posible con cualquier objeto en PHP.

Compare con una matriz en PHP, también puede agregar nuevas claves cuando lo desee.

Este ejemplo no se ha elegido de la nada, porque es de donde provienen los objetos en PHP: son simplemente azúcar sintáctica alrededor de las matrices y esto tiene que ver con el momento en que los objetos en PHP se introdujeron nuevamente en PHP 3:

En el momento en que se introdujeron las clases en el árbol de origen de lo que se convertiría en PHP 3.0, se agregaron como azúcar sintáctica para acceder a las colecciones. PHP ya tenía la noción de colecciones de matrices asociativas, y las nuevas criaturas no eran más que una nueva forma de acceder a ellas. Sin embargo, como el tiempo ha demostrado, esta nueva sintaxis demostró tener un efecto de mucho mayor alcance en PHP del que se pretendía originalmente.

- Zeev Suraski sobre el objeto estándar desde PHP 3 ( copia archivada ) - a través de ¿Por qué devolver el objeto en lugar de la matriz?

Esta es también la explicación simple de por qué es totalmente común en PHP que las funciones pueden agregar variables miembro que no se han definido anteriormente en la clase. Esos son siempre públicos.

Entonces, cuando haga suposiciones sobre si un objeto tiene una propiedad o no, mire de dónde viene. No debe ser parte de la clase, pero podría haberse agregado más tarde.

Y ten en cuenta lo siguiente:

No utilice print_r y var_dump en el código de producción.


Debe usar DateTime::format o DateTimeImmutable::format según sea el caso.

$m_oDate = new DateTime('NOW');
echo $m_oDate->format("r");

Esto ha sido reportado como Bug # 49382 en PHP.

En PHP 5.3, se agregó la funcionalidad interna para permitir que print_r() muestre los detalles del valor de marca de tiempo subyacente mantenido por una instancia de DateTime , para ayudar con la depuración. Un efecto secundario de este cambio es que cuando el objeto se vuelca en texto, estas propiedades públicas fantasmas se agregan a la instancia.

El mismo efecto se puede lograr usando la reflection para acceder a estas propiedades, y si necesita acceder a las propiedades, entonces usar la reflexión sería el camino a seguir, por lo que no provoca el error.

Sin embargo, debe tenerse en cuenta que realmente no debería usar estas propiedades, ya que no están definidas como miembros del objeto, no hay garantía de que continuarán llevando la misma información (o incluso que existan) en futuras versiones de PHP. Si necesita acceder a la información, utilice los siguientes métodos, definidos como parte de la API, en su lugar:

// $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

NB: la propiedad timezone_type no es accesible a través de la API de PHP. Es un valor interno y no es útil en la zona de usuario, ya que describe el tipo de cadena que contiene la timezone cuando se descarga el objeto, es decir, uno de los tres métodos para obtener información de la zona horaria en el ejemplo de código anterior. Para completar, sus posibles valores se defined de la siguiente manera:

Value | Type                  | Userland equivalent
------+-----------------------+----------------------------------
  1   | time offset           | DateTimeZone::getOffset()
  2   | TimeZone abbreviation | DateTimeZone::listAbbreviations()
  3   | TimeZone identifier   | DateTimeZone::getName()

No hay propiedad de date en DateTime ; es por eso que está recibiendo (Undefined property: DateTime::$date).

print_r() realiza alguna introspection en el objeto para mostrar su contenido; esto hace que el objeto cree mágicamente la propiedad ::date . Sin embargo, esto no está documentado, por lo que usarlo puede romper tu código en el futuro.

Necesita algo como $m_oDate->format('md-Y'); en lugar.


Se está produciendo algo de magia pero es bastante simple.

La clase DateTime no tiene una variable pública "fecha" a la que está destinado a acceder. Sin embargo, como efecto secundario de cómo funciona PHP, se crea una variable cuando se llama a print_r o var_dump en esa clase.

Después de que ocurra la magia, "fecha" está disponible, pero no debería estarlo. Solo debe utilizar la función getTimestamp para que su código funcione de manera confiable.





php-internals