diff --git a/src/wp-includes/class-wp-widget.php b/src/wp-includes/class-wp-widget.php
index fa206e7d35..e91f5cd9f9 100644
--- a/src/wp-includes/class-wp-widget.php
+++ b/src/wp-includes/class-wp-widget.php
@@ -365,7 +365,7 @@ class WP_Widget {
 		$this->_set( $widget_args['number'] );
 		$instances = $this->get_settings();
 
-		if ( array_key_exists( $this->number, $instances ) ) {
+		if ( isset( $instances[ $this->number ] ) ) {
 			$instance = $instances[ $this->number ];
 
 			/**
diff --git a/tests/phpunit/tests/widgets.php b/tests/phpunit/tests/widgets.php
index 679d2b7a59..36e9b684f6 100644
--- a/tests/phpunit/tests/widgets.php
+++ b/tests/phpunit/tests/widgets.php
@@ -590,6 +590,47 @@ class Tests_Widgets extends WP_UnitTestCase {
 
 	// @todo Test WP_Widget::display_callback().
 
+	/**
+	 * @ticket 52728
+	 */
+	function test_widget_display_callback_handles_arrayobject() {
+		$widget = new WP_Widget_Text();
+
+		register_widget( $widget );
+
+		add_filter(
+			"pre_option_{$widget->option_name}",
+			static function() {
+				return new ArrayObject(
+					array(
+						2              => array( 'title' => 'Test Title' ),
+						'_multiwidget' => 1,
+						'__i__'        => true,
+					)
+				);
+			}
+		);
+
+		// Effectively ignore the output until retrieving it later via `getActualOutput()`.
+		$this->expectOutputRegex( '`.`' );
+
+		$widget->display_callback(
+			array(
+				'before_widget' => '<section>',
+				'after_widget'  => "</section>\n",
+				'before_title'  => '<h2>',
+				'after_title'   => "</h2>\n",
+			),
+			2
+		);
+
+		$actual = $this->getActualOutput();
+
+		unregister_widget( $widget );
+
+		$this->assertStringContainsString( 'Test Title', $actual );
+	}
+
 	/**
 	 * @see WP_Widget::is_preview()
 	 */