In previous versions of WordPress, when you called get_userdata() or get_user_by(), you got a plain stdClass object, filled with all the fields from both wp_users and wp_usermeta tables. This had two disadvantages:
- dashes were removed, so that ‘my-custom-field’ became ‘mycustomfield’
- all fields were loaded and kept in memory, wasting precious resources
Since WordPress 3.3, all user-related functions return WP_User instances. This class has some magic methods that make it behave as if it contained all the custom fields.
Accessing a single custom field
For example, let’s try to display the user description of the currently logged in user:
$current_user = wp_get_current_user(); if ( isset( $current_user->bio ) ) echo '<p>' . $current_user->bio . '</p>';
This code works fine both in WP 3.2 and in WP 3.3. The difference is that in WP 3.3 that code is equivalent to this:
if ( $current_user->__isset( 'bio' ) ) ) echo '<p>' . $current_user->__get( 'bio' ) . '</p>';
Internally, the __isset() and __get() methods call get_user_meta().
If you have a variable key or a key with dashes, there are prettier aliases which you can use:
if ( $current_user->has_prop( 'my-field' ) ) ) echo '<p>' . $current_user->get( 'my-field' ) . '</p>';
Accessing all custom fields
Unfortunately, iterating over all the custom fields by casting to an array isn’t possible anymore:
foreach ( (array) $user as $key => $value ) { var_dump( $key, $value ); }
It will have to be replaced with this:
foreach ( get_user_meta( $user->ID ) as $key => $values ) { var_dump( $key, $values ); }
Note that, in the later case, $values is an array.

Real magic indeed!
This has been very useful! Thank you for posting. :)
Progress!
Thank you!