Multiple fields with add_settings_field callback

It depends on what the fields do. If they are all of the same type – a label and a text input for example – then, yes, that’s a good approach. You can just use the sixth parameter to create a different output.

But if these fields are different, need different escaping methods (esc_textarea() versus esc_attr()) and different HTML code, then you should use different callbacks.

Let’s say you have stored your data in an array.

Now you have a function or a method in your controller class to create a data object and multiple view objects for the different outputs:

class Settings_Controller
{
    public function __construct()
    {
        $data       = new Settings_Data( 'wpse_123635' ); // option name
        $textarea   = new Textarea( $data, 's1' ); // data plus field id
        $checkbox   = new Checkbox( $data, 's2' );
        $text_field = new Text_field( $data, 's3' );

        add_settings_field(
            's1',
            'A textarea',
            array ( $textarea, 'render' ),
            'my_page',
            'my_section'
        );

        add_settings_field(
            's2',
            'A textarea',
            array ( $checkbox, 'render' ),
            'my_page',
            'my_section'
        );

        add_settings_field(
            's3',
            'A textarea',
            array ( $text_field, 'render' ),
            'my_page',
            'my_section'
        );
    }
}

The views will get their data now from the model $data. They are separately testable, reusable and nicely decoupled. You can use the same view class for multiple fields with other data providers and so on.

When in doubt, keep it simple. But if you realize one function has to do too much, separate its tasks.