If I do this I get many properties shown, including display_name, but the first and last names are NOT shown
$user = get_userdata( 4 );
print_r( $user );
However they clearly exist because if I immediately afterwards do this, I am shown the proper last name. The Wordpress docs also mention last_name as being a property.
echo $user->last_name;
So why doesn't print_r show all of the properties? This casts a lot of doubt on being able to use print_r to discover information.
last_name
is not a real property of WP_User
, but it's made available via magic methods for backwards compatibility.
It's listed as a public property in the docs, but this is a little misleading. More accurately, you can access it as a public property. But when you look at the code, it's being retrieved and set using magic methods.
Here's an excerpt of the most relevant code, showing how Wordpress actually keeps a list of several of these backward-compatibility properties, including last_name
, in a private, static property called back_compat_keys
. When the user requests one of these properties, the magic method __get
is called. The magic method uses get_user_meta()
to actually retrieve the data for that property. In other words, the data isn't actually stored in the WP_User
object; Wordpress just lets you pretend that it is, and it only fetches it when explicitly requested. Here's the code:
<?php
class WP_User {
// ...
/**
* @static
* @since 3.3.0
* @access private
* @var array
*/
private static $back_compat_keys;
public function __construct( $id = 0, $name = '', $blog_id = '' ) {
if ( ! isset( self::$back_compat_keys ) ) {
$prefix = $GLOBALS['wpdb']->prefix;
self::$back_compat_keys = array(
'user_firstname' => 'first_name',
'user_lastname' => 'last_name',
'user_description' => 'description',
'user_level' => $prefix . 'user_level',
$prefix . 'usersettings' => $prefix . 'user-settings',
$prefix . 'usersettingstime' => $prefix . 'user-settings-time',
);
}
// ...
}
// ...
/**
* Magic method for accessing custom fields.
*
* @since 3.3.0
* @access public
*
* @param string $key User meta key to retrieve.
* @return mixed Value of the given user meta key (if set). If `$key` is 'id', the user ID.
*/
public function __get( $key ) {
// ...
if ( isset( $this->data->$key ) ) {
$value = $this->data->$key;
} else {
if ( isset( self::$back_compat_keys[ $key ] ) )
$key = self::$back_compat_keys[ $key ];
$value = get_user_meta( $this->ID, $key, true );
}
// ...
return $value;
}
/**
* Magic method for setting custom user fields.
*
* This method does not update custom fields in the database. It only stores
* the value on the WP_User instance.
*
* @since 3.3.0
* @access public
*
* @param string $key User meta key.
* @param mixed $value User meta value.
*/
public function __set( $key, $value ) {
if ( 'id' == $key ) {
_deprecated_argument( 'WP_User->id', '2.1.0',
sprintf(
/* translators: %s: WP_User->ID */
__( 'Use %s instead.' ),
'<code>WP_User->ID</code>'
)
);
$this->ID = $value;
return;
}
$this->data->$key = $value;
}
/**
* Magic method for unsetting a certain custom field.
*
* @since 4.4.0
* @access public
*
* @param string $key User meta key to unset.
*/
public function __unset( $key ) {
// ...
if ( isset( $this->data->$key ) ) {
unset( $this->data->$key );
}
if ( isset( self::$back_compat_keys[ $key ] ) ) {
unset( self::$back_compat_keys[ $key ] );
}
}
// ...
}