EDIT
I updated the function to check for role for which we want to make changes for, if the current user role is not within our roles_to_change
array then the function exits.
Note that I haven't tested for bugs, so if you find any, just report them here.
@Malisa's answer is a good approach. However, if you still want to hook on page load, you could try the template_redirect
hook.
You would need some kind logic to only run the code on specific use case. So assuming you already have that logic AND that the user is already logged in when you try to change his role.
something like this should work
add_action( 'template_redirect', 'my_change_user_role' );
function my_change_user_role(){
$current_user = wp_get_current_user();
// Bail if no one is logged in
if( 0 == $current_user->ID )
return;
// Fetch the WP_User object of our user.
$cur_user = new WP_User( $current_user->ID );
// Only Apply to users within these roles
$roles_to_change = array(
'role_x',
'role_y',
'role_z'
);
$make_change = false; // Flag telling to make the changes or not
// Check if we can make the change to the current user
foreach( $roles_to_change as $change ){
foreach ( $cur_user->roles as $user_role ){
if( $change == $user_role ){
$make_change = true;
continue;
}
}
}
// Bail if role is not within those we want to make a change for
if( ! $make_change )
return;
// Replace the current role with our 'new_role' role
$cur_user->set_role( 'new_role' );
}
If you use this in a form you could use the $_GET
or $_POST
superglobal to pass on some information about the user (like is ID for instance).