How to pass a variable between filter/action functions?

I’m not sure if my use of globals is correct. I would prefer this
method as it seems simplest.

It’s not.

The problem is that wp_handle_upload_prefilter is occurring in a completely separate AJAX request. It has no access to any PHP variables (global or otherwise) defined on user-edit.php.

If you hard-code the value into the file, the way you’ve done, then it will work, but that’s only because the file is loaded for both requests. If you redefine the value in one hook it would still be the original value in the other, because that reassignment happened in a separate request.

Also, this won’t work:

$myuserid = 5;

function my_pre_upload($file, $myuserid){}

my_pre_upload() will only receive arguments passed by the filter. And wp_handle_upload_prefilter only passed a single parameter, for the file information.

The only way to pass data from user-edit.php to wp_handle_upload_prefilter is to somehow modify the AJAX request for the upload to include the data you need. Then you can access it with $_POST.

The good news is that there is a filter, plupload_default_params, that will let you add parameters to the AJAX request for a media upload. So inside this filter, check if you’re on a user edit screen or the profile screen, and if so, add the user ID to the parameters.

add_filter( 'plupload_default_params', function( $params ) {
    if ( ! is_admin() ) {
        return $params;
    }

    $screen_id = get_current_screen();

    if ( 'user-edit' === $screen_id ) {
        $params['user_id'] = $_GET['user_id'];
    } else if ( 'profile' === $screen_id ) {
        $params['user_id'] = get_current_user_id();
    }

    return $params;
} );

Then, in your wp_handle_upload_prefilter callback, check for this value and do your thing:

add_filter( 'wp_handle_upload_prefilter', function( $file ) {
    if ( isset( $_POST['user_id'] ) ) {
        $user_id = $_POST['user_id'];

        // Do what you want with the user.
    }

    return $file;
} );