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




array values (7)

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 .


Answers

Por el gusto de hacerlo, así es como puedes hacer que funcione, usando Reflection :

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

Source


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.


El problema radica aquí :

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

La función date_object_get_properties se llama cuando se realiza cualquier volcado de datos ( print_r , var_dump , var_export ). La tabla hash se actualiza para los datos que representan, desafortunadamente esto se hace público.


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

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

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.


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.


Algo que no se menciona aquí y es útil: agregar un sufijo al día. Desacoplé la lógica del sufijo para que pueda usarlo para cualquier número que desee, no solo fechas.

import time

def num_suffix(n):
    '''
    Returns the suffix for any given int
    '''
    suf = ('th','st', 'nd', 'rd')
    n = abs(n) # wise guy
    tens = int(str(n)[-2:])
    units = n % 10
    if tens > 10 and tens < 20:
        return suf[0] # teens with 'th'
    elif units <= 3:
        return suf[units]
    else:
        return suf[0] # 'th'

def day_suffix(t):
    '''
    Returns the suffix of the given struct_time day
    '''
    return num_suffix(t.tm_mday)

# Examples
print num_suffix(123)
print num_suffix(3431)
print num_suffix(1234)
print ''
print day_suffix(time.strptime("1 Dec 00", "%d %b %y"))
print day_suffix(time.strptime("2 Nov 01", "%d %b %y"))
print day_suffix(time.strptime("3 Oct 02", "%d %b %y"))
print day_suffix(time.strptime("4 Sep 03", "%d %b %y"))
print day_suffix(time.strptime("13 Nov 90", "%d %b %y"))
print day_suffix(time.strptime("14 Oct 10", "%d %b %y"))​​​​​​​






php debugging datetime php-internals