Skip to content

PHPC-2699: Add typed, read-only properties for value objects and events#1979

Merged
alcaeus merged 18 commits intomongodb:v2.xfrom
alcaeus:phpc-2699-typed-properties
Apr 13, 2026
Merged

PHPC-2699: Add typed, read-only properties for value objects and events#1979
alcaeus merged 18 commits intomongodb:v2.xfrom
alcaeus:phpc-2699-typed-properties

Conversation

@alcaeus
Copy link
Copy Markdown
Member

@alcaeus alcaeus commented Apr 8, 2026

PHPC-2699; continuation of #1973

This PR adds public, read-only properties to the stub files for the following classes:

  • MongoDB\Driver\ReadConcern
  • MongoDB\Driver\ReadPreference
  • MongoDB\Driver\WriteConcern
  • MongoDB\Driver\WriteError
  • MongoDB\Driver\WriteResult
  • MongoDB\Driver\Exception\CommandException (make existing property public readonly)
  • MongoDB\Driver\Exception\BulkWriteException (make existing property public readonly)
  • MongoDB\Driver\Monitoring\CommandFailedEvent
  • MongoDB\Driver\Monitoring\CommandStartedEvent
  • MongoDB\Driver\Monitoring\CommandSucceededEvent
  • MongoDB\Driver\Monitoring\ServerChangedEvent
  • MongoDB\Driver\Monitoring\ServerClosedEvent
  • MongoDB\Driver\Monitoring\ServerHeartbeatFailedEvent
  • MongoDB\Driver\Monitoring\ServerHeartbeatStartedEvent
  • MongoDB\Driver\Monitoring\ServerHeartbeatSucceededEvent
  • MongoDB\Driver\Monitoring\ServerOpeningEvent
  • MongoDB\Driver\Monitoring\TopologyChangedEvent
  • MongoDB\Driver\Monitoring\TopologyClosedEvent
  • MongoDB\Driver\Monitoring\TopologyOpeningEvent

This allows us to rely on PHP's default handling for several things:

  • The __serialize implementation falls away for classes that implement it, as our property table now contains serialisable properties
  • The get_debug_info handler falls away as it exposes properties by default
  • By extension, the get_properties_hash function in these classes falls away; bsonSerialize implementations instead use the standard property table
  • No get_properties_for handler needs to be implemented (makes PHPC-1622 obsolete for these classes)
  • For ReadConcern, ReadPreference, and WriteConcern, we no longer need to implement a compare handler to make them comparable as there's now a property table to compare (this makes PHPC-2234 obsolete)

I strongly recommend a review of individual commits.

This PR opens avenues for further simplification. For example, the various event classes copy data from the libmongoc event object into the internal structure, and also store them in the property table as zval. By making the getters return the values of the property, we could do away with the internal structure for all these objects and only store data in the zval.

In future, we can also deprecate the various getters for removal in 3.0. I've left this out of this PR as the changes are already quite verbose due to the occasional change in debug output.

Other classes, such as BSON objects and "functional" objects like MongoDB\Driver\Server or MongoDB\Driver\Cursor, will be handled at a separate time.

@alcaeus alcaeus requested a review from a team as a code owner April 8, 2026 13:23
@alcaeus alcaeus requested review from GromNaN and Copilot and removed request for a team April 8, 2026 13:23
@alcaeus alcaeus force-pushed the phpc-2699-typed-properties branch from a1c8020 to 49a976f Compare April 8, 2026 13:25
class BulkWriteException extends ServerException
{
/** @var \MongoDB\Driver\WriteResult */
protected $writeResult;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's technically a breaking change if anyone extends the BulkWriteException and overrides this property, which is highly unlikely.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm willing to take the risk :)

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR continues the work to expose typed, public readonly properties for MongoDB driver value objects, write results/errors, and APM/SDAM monitoring events. It updates the C implementations and PHPT expectations so these objects rely more on PHP’s standard property table behavior (debug output, serialization, comparisons) instead of custom handlers.

Changes:

  • Add typed public readonly properties to multiple driver stubs (value objects, exceptions, write result/error types, and monitoring events) and regenerate arginfo.
  • Update corresponding C code to populate declared properties (and remove now-redundant debug/property handlers).
  • Update/add PHPTs to assert property access, updated debug output, serialization, and comparison behavior.

Reviewed changes

Copilot reviewed 158 out of 158 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tests/writeResult/writeresult-getwriteerrors-002.phpt Asserts WriteResult exposes writeErrors property equivalent to getter
tests/writeResult/writeresult-getwriteerrors-001.phpt Asserts WriteResult exposes writeErrors property equivalent to getter
tests/writeResult/writeresult-getwriteconcernerror-002.phpt Asserts WriteResult exposes writeConcernError property
tests/writeResult/writeresult-getwriteconcernerror-001.phpt Asserts WriteResult exposes writeConcernError property
tests/writeResult/writeresult-getupsertedids-002.phpt Asserts WriteResult exposes upsertedIds property
tests/writeResult/writeresult-getupsertedids-001.phpt Asserts WriteResult exposes upsertedIds property
tests/writeResult/writeresult-getupsertedcount-002.phpt Asserts upsertedCount property behavior for unacknowledged writes
tests/writeResult/writeresult-getupsertedcount-001.phpt Asserts upsertedCount property matches getter
tests/writeResult/writeresult-getserver-001.phpt Asserts WriteResult exposes server property
tests/writeResult/writeresult-getmodifiedcount-002.phpt Asserts modifiedCount property behavior for unacknowledged writes
tests/writeResult/writeresult-getmodifiedcount-001.phpt Asserts modifiedCount property matches getter
tests/writeResult/writeresult-getmatchedcount-002.phpt Asserts matchedCount property behavior for unacknowledged writes
tests/writeResult/writeresult-getmatchedcount-001.phpt Asserts matchedCount property matches getter
tests/writeResult/writeresult-getinsertedcount-002.phpt Asserts insertedCount property behavior for unacknowledged writes
tests/writeResult/writeresult-getinsertedcount-001.phpt Asserts insertedCount property matches getter
tests/writeResult/writeresult-getErrorReplies-001.phpt Asserts WriteResult exposes errorReplies property and element access
tests/writeResult/writeresult-getdeletedcount-002.phpt Asserts deletedCount property behavior for unacknowledged writes
tests/writeResult/writeresult-getdeletedcount-001.phpt Asserts deletedCount property matches getter
tests/writeResult/writeresult-debug-002.phpt Updates var_dump expectations for new public properties
tests/writeResult/writeresult-debug-001.phpt Updates var_dump expectations for new public properties
tests/writeConcern/writeconcern-var_export-001.phpt Updates var_export output to include declared properties
tests/writeConcern/writeconcern-set_state-001.phpt Updates __set_state output expectations for declared properties
tests/writeConcern/writeconcern-getwtimeout-001.phpt Asserts wtimeout property matches getter
tests/writeConcern/writeconcern-getw-001.phpt Asserts w property matches getter
tests/writeConcern/writeconcern-getjournal-001.phpt Asserts j property matches getter
tests/writeConcern/writeconcern-debug-003.phpt Updates debug output expectations for WriteConcern properties
tests/writeConcern/writeconcern-debug-002.phpt Updates debug output expectations for WriteConcern properties
tests/writeConcern/writeconcern-debug-001.phpt Updates debug output expectations for WriteConcern properties
tests/writeConcern/writeconcern-ctor-002.phpt Updates constructor debug output expectations
tests/writeConcern/writeconcern-ctor-001.phpt Updates constructor debug output expectations
tests/writeConcern/writeconcern-compare-001.phpt Adds comparison tests for WriteConcern objects
tests/writeConcern/bug1598-002.phpt Updates GC cycle expectations after property changes
tests/standalone/writeresult-isacknowledged-003.phpt Updates debug output expectations for unacknowledged WriteResult
tests/standalone/writeresult-isacknowledged-002.phpt Updates debug output expectations for unacknowledged WriteResult
tests/standalone/writeresult-isacknowledged-001.phpt Updates debug output expectations for acknowledged WriteResult
tests/session/session-getTransactionOptions-001.phpt Updates ReadPreference/WriteConcern dump expectations in transaction options
tests/session/session-debug-006.phpt Updates nested ReadPreference/WriteConcern dump expectations
tests/session/session-debug-005.phpt Updates nested ReadPreference dump expectations
tests/server/server-executeBulkWrite-001.phpt Updates WriteResult dump expectations after property changes
tests/replicaset/writeresult-getserver-002.phpt Updates WriteResult dump expectations and includes server
tests/readPreference/readpreference-var_export-001.phpt Updates var_export output to include new ReadPreference properties
tests/readPreference/readpreference-set_state-001.phpt Updates __set_state output expectations for ReadPreference properties
tests/readPreference/readpreference-getTagSets-002.phpt Asserts tags property behavior alongside getTagSets()
tests/readPreference/readpreference-getTagSets-001.phpt Asserts tags property behavior alongside getTagSets()
tests/readPreference/readpreference-getModeString-001.phpt Asserts mode property matches getModeString()
tests/readPreference/readpreference-getMaxStalenessMS-002.phpt Asserts maxStalenessSeconds property matches getter
tests/readPreference/readpreference-getMaxStalenessMS-001.phpt Asserts maxStalenessSeconds property matches getter
tests/readPreference/readpreference-getHedge-001.phpt Asserts deprecated hedge property access emits deprecation
tests/readPreference/readpreference-debug-001.phpt Updates debug output expectations for ReadPreference properties
tests/readPreference/readpreference-ctor-002.phpt Updates constructor dump expectations for ReadPreference properties
tests/readPreference/readpreference-ctor-001.phpt Updates constructor dump expectations for ReadPreference properties
tests/readPreference/readpreference-compare-001.phpt Adds comparison tests for ReadPreference objects
tests/readPreference/bug1698-001.phpt Updates dump expectations for ReadPreference properties
tests/readPreference/bug1598-002.phpt Updates GC expectations and documents typed-property GC behavior
tests/readPreference/bug0851-001.phpt Updates dump expectations for ReadPreference properties
tests/readPreference/bug0146-001.phpt Updates Cursor dump expectations for embedded ReadPreference properties
tests/readConcern/readconcern-var_export-001.phpt Updates var_export output to include level property
tests/readConcern/readconcern-set_state-001.phpt Updates __set_state output expectations for level
tests/readConcern/readconcern-serialization-002.phpt Updates serialization expectations after introducing level property
tests/readConcern/readconcern-getlevel-001.phpt Asserts level property matches getLevel()
tests/readConcern/readconcern-debug-001.phpt Updates debug output expectations for level
tests/readConcern/readconcern-ctor-001.phpt Updates constructor dump expectations for level
tests/readConcern/readconcern-compare-001.phpt Adds comparison tests for ReadConcern objects
tests/readConcern/bug1598-002.phpt Updates GC cycle expectations after property changes
tests/manager/manager-getwriteconcern-001.phpt Updates Manager getWriteConcern() dump expectations
tests/manager/manager-getreadpreference-001.phpt Updates Manager getReadPreference() dump expectations
tests/manager/manager-getreadconcern-001.phpt Updates Manager getReadConcern() dump expectations
tests/manager/manager-executeBulkWrite_error-005.phpt Updates BulkWriteException/WriteResult dump expectations
tests/manager/manager-ctor-write_concern-006.phpt Updates URI write concern parsing dump expectations
tests/manager/manager-ctor-write_concern-005.phpt Updates 64-bit wtimeoutms parsing dump expectations
tests/manager/manager-ctor-write_concern-004.phpt Updates multiple write concern parsing dump expectations
tests/manager/manager-ctor-write_concern-003.phpt Updates journaling parsing dump expectations
tests/manager/manager-ctor-write_concern-002.phpt Updates wtimeout parsing dump expectations
tests/manager/manager-ctor-write_concern-001.phpt Updates baseline write concern parsing dump expectations
tests/manager/manager-ctor-read_preference-002.phpt Updates ReadPreference parsing dump expectations
tests/manager/manager-ctor-read_preference-001.phpt Updates ReadPreference parsing dump expectations
tests/manager/bug0851-001.phpt Updates dump expectations for ReadPreference properties
tests/exception/bulkwriteexception-getwriteresult-001.phpt Updates WriteResult dump expectations under BulkWriteException
tests/apm/topologyOpeningEvent-001.phpt Asserts topologyId property access
tests/apm/topologyClosedEvent-001.phpt Asserts topologyId property access
tests/apm/topologyChangedEvent-001.phpt Asserts new/previous description properties and renames oldDescription→previousDescription
tests/apm/serverOpeningEvent-001.phpt Asserts host/port/topologyId property access
tests/apm/serverHeartbeatSucceededEvent-001.phpt Asserts heartbeat succeeded event property access
tests/apm/serverHeartbeatStartedEvent-001.phpt Asserts heartbeat started event property access
tests/apm/serverHeartbeatFailedEvent-001.phpt Asserts heartbeat failed event property access
tests/apm/serverClosedEvent-001.phpt Asserts host/port/topologyId property access
tests/apm/serverChangedEvent-001.phpt Asserts new/previous description properties and renames oldDescription→previousDescription
tests/apm/commandSucceededEvent-debug-001.phpt Updates debug output expectations for added properties
tests/apm/commandSucceededEvent-002.phpt Asserts operationId/requestId match between getter and property
tests/apm/commandSucceededEvent-001.phpt Asserts CommandSucceededEvent property access mirrors getters
tests/apm/commandStartedEvent-debug-001.phpt Updates debug output expectations for added properties
tests/apm/commandStartedEvent-002.phpt Switches to property-based access for commandName
tests/apm/commandStartedEvent-001.phpt Asserts CommandStartedEvent property access mirrors getters
tests/apm/commandFailedEvent-debug-001.phpt Updates debug output expectations for added properties
tests/apm/commandFailedEvent-002.phpt Asserts operationId/requestId match between getter and property
tests/apm/commandFailedEvent-001.phpt Asserts CommandFailedEvent property access mirrors getters
src/phongo_structs.h Removes cached properties HashTables from select internal structs
src/phongo_execute.c Passes write concern into WriteResult initialization
src/phongo_apm.h Declares event init helpers for APM/SDAM event objects
src/MongoDB/WriteResult.stub.php Adds typed readonly properties for WriteResult
src/MongoDB/WriteResult.h Updates WriteResult init signature to accept write concern
src/MongoDB/WriteResult_arginfo.h Regenerated arginfo for WriteResult properties
src/MongoDB/WriteError.stub.php Adds typed readonly properties for WriteError
src/MongoDB/WriteError.c Populates declared properties (replaces custom debug handler usage)
src/MongoDB/WriteError_arginfo.h Regenerated arginfo for WriteError properties
src/MongoDB/WriteConcern.stub.php Adds typed readonly properties; removes __serialize stub
src/MongoDB/WriteConcern_arginfo.h Regenerated arginfo for WriteConcern properties
src/MongoDB/ReadPreference.stub.php Adds typed readonly properties (incl. deprecated hedge) and removes __serialize stub
src/MongoDB/ReadPreference_arginfo.h Regenerated arginfo for ReadPreference properties
src/MongoDB/ReadConcern.stub.php Adds typed readonly level property and removes __serialize stub
src/MongoDB/ReadConcern.c Updates property syncing and bsonSerialize implementation for declared properties
src/MongoDB/ReadConcern_arginfo.h Regenerated arginfo for ReadConcern properties
src/MongoDB/Monitoring/TopologyOpeningEvent.stub.php Adds typed readonly topologyId property
src/MongoDB/Monitoring/TopologyOpeningEvent.c Syncs declared properties; removes custom debug_info
src/MongoDB/Monitoring/TopologyOpeningEvent_arginfo.h Regenerated arginfo for TopologyOpeningEvent properties
src/MongoDB/Monitoring/TopologyClosedEvent.stub.php Adds typed readonly topologyId property (nullable in stub)
src/MongoDB/Monitoring/TopologyClosedEvent.c Syncs declared properties; removes custom debug_info
src/MongoDB/Monitoring/TopologyClosedEvent_arginfo.h Regenerated arginfo for TopologyClosedEvent properties
src/MongoDB/Monitoring/TopologyChangedEvent.stub.php Adds typed readonly topology/description properties
src/MongoDB/Monitoring/TopologyChangedEvent.c Syncs declared properties; removes custom debug_info
src/MongoDB/Monitoring/TopologyChangedEvent_arginfo.h Regenerated arginfo for TopologyChangedEvent properties
src/MongoDB/Monitoring/ServerOpeningEvent.stub.php Adds typed readonly host/port/topologyId properties
src/MongoDB/Monitoring/ServerOpeningEvent.c Syncs declared properties; removes custom debug_info
src/MongoDB/Monitoring/ServerOpeningEvent_arginfo.h Regenerated arginfo for ServerOpeningEvent properties
src/MongoDB/Monitoring/ServerHeartbeatSucceededEvent.stub.php Adds typed readonly properties and fixes method signature formatting
src/MongoDB/Monitoring/ServerHeartbeatSucceededEvent.c Syncs declared properties; removes custom debug_info
src/MongoDB/Monitoring/ServerHeartbeatSucceededEvent_arginfo.h Regenerated arginfo for ServerHeartbeatSucceededEvent properties
src/MongoDB/Monitoring/ServerHeartbeatStartedEvent.stub.php Adds typed readonly host/port/awaited properties
src/MongoDB/Monitoring/ServerHeartbeatStartedEvent.c Syncs declared properties; removes custom debug_info
src/MongoDB/Monitoring/ServerHeartbeatStartedEvent_arginfo.h Regenerated arginfo for ServerHeartbeatStartedEvent properties
src/MongoDB/Monitoring/ServerHeartbeatFailedEvent.stub.php Adds typed readonly properties incl. error/duration
src/MongoDB/Monitoring/ServerHeartbeatFailedEvent.c Syncs declared properties; moves error conversion into init
src/MongoDB/Monitoring/ServerHeartbeatFailedEvent_arginfo.h Regenerated arginfo for ServerHeartbeatFailedEvent properties
src/MongoDB/Monitoring/ServerClosedEvent.stub.php Adds typed readonly host/port/topologyId properties
src/MongoDB/Monitoring/ServerClosedEvent.c Syncs declared properties; removes custom debug_info
src/MongoDB/Monitoring/ServerClosedEvent_arginfo.h Regenerated arginfo for ServerClosedEvent properties
src/MongoDB/Monitoring/ServerChangedEvent.stub.php Adds typed readonly properties incl. previousDescription
src/MongoDB/Monitoring/ServerChangedEvent.c Syncs declared properties; removes custom debug_info
src/MongoDB/Monitoring/ServerChangedEvent_arginfo.h Regenerated arginfo for ServerChangedEvent properties
src/MongoDB/Monitoring/CommandSucceededEvent.stub.php Adds typed readonly properties (incl. databaseName/serviceId/serverConnectionId)
src/MongoDB/Monitoring/CommandSucceededEvent.c Syncs declared properties; removes custom debug_info
src/MongoDB/Monitoring/CommandSucceededEvent_arginfo.h Regenerated arginfo for CommandSucceededEvent properties
src/MongoDB/Monitoring/CommandStartedEvent.stub.php Adds typed readonly properties (incl. databaseName/serviceId/serverConnectionId)
src/MongoDB/Monitoring/CommandStartedEvent.c Syncs declared properties; removes custom debug_info
src/MongoDB/Monitoring/CommandStartedEvent_arginfo.h Regenerated arginfo for CommandStartedEvent properties
src/MongoDB/Monitoring/CommandFailedEvent.stub.php Adds typed readonly properties (incl. databaseName/error/reply)
src/MongoDB/Monitoring/CommandFailedEvent.c Syncs declared properties; moves error conversion into init
src/MongoDB/Monitoring/CommandFailedEvent_arginfo.h Regenerated arginfo for CommandFailedEvent properties
src/MongoDB/Exception/CommandException.stub.php Makes resultDocument a public readonly typed property
src/MongoDB/Exception/CommandException_arginfo.h Regenerated arginfo for CommandException property change
src/MongoDB/Exception/BulkWriteException.stub.php Makes writeResult a public readonly typed property
src/MongoDB/Exception/BulkWriteException_arginfo.h Regenerated arginfo for BulkWriteException property change
Comments suppressed due to low confidence (1)

src/MongoDB/Monitoring/TopologyClosedEvent.stub.php:18

  • Property type is nullable (ObjectId|null) but getTopologyId() is declared to always return ObjectId. Either make $topologyId non-nullable (and ensure it is always initialized), or update the getter signature/implementation to allow null and ensure the property is set to null when appropriate; otherwise, this creates an inconsistent API surface for the same value.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

public readonly string $commandName;
public readonly string $databaseName;
public readonly int $durationMicros;
public readonly \Exception $error;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should it be more specific? MongoDB\Driver\Exception or MongoDB\Driver\RuntimeException

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reused the return type of getError. I'll take a look to see if we can make it more specific.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm now using the MongoDB\Driver\Exception\Exception interface as it's the only common ancestor between the various exceptions that could be added: phongo_exception_from_mongoc_domain might return a RuntimeException or LogicException. The only problem is that this interface only extends \Throwable but does not share an ancestor with \Exception. It should be fine, but I suspect that's why getError originally used \Exception for its return type instead of a more specific type.

Copy link
Copy Markdown
Member

@GromNaN GromNaN Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So that's a case for an intersection type \Exception&MongoDB\Driver\Exception\Exception

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MongoDB\Driver\Exception\Exception doesn't provide any method or property, that's not worth the change.
Alternatively, a union of MongoDB\Driver\Exception\RuntimeException| MongoDB\Driver\Exception\LogicException.

Copy link
Copy Markdown
Member Author

@alcaeus alcaeus Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the intersection type and made the change :)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The intersection type doesn't work.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May be too easy to fix: php/php-src#21717

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed the intersection type for the time being. We can clarify that in a later version once the arginfo generator has been fixed.

@alcaeus alcaeus force-pushed the phpc-2699-typed-properties branch from 49a976f to 8c22f43 Compare April 8, 2026 13:54
Copilot AI review requested due to automatic review settings April 8, 2026 13:57
@alcaeus alcaeus force-pushed the phpc-2699-typed-properties branch from 8c22f43 to 5135991 Compare April 8, 2026 13:57
@alcaeus
Copy link
Copy Markdown
Member Author

alcaeus commented Apr 8, 2026

GitHub Copilot had one low-confidence comment it suppressed:

Property type is nullable (ObjectId|null) but getTopologyId() is declared to always return ObjectId. Either make $topologyId non-nullable (and ensure it is always initialized), or update the getter signature/implementation to allow null and ensure the property is set to null when appropriate; otherwise, this creates an inconsistent API surface for the same value.

I'm looking at this to see what the discrepancy is about.

@alcaeus alcaeus force-pushed the phpc-2699-typed-properties branch from 5135991 to 343e07d Compare April 8, 2026 14:02
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 158 out of 158 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@alcaeus alcaeus force-pushed the phpc-2699-typed-properties branch from 343e07d to 5ee7b1a Compare April 8, 2026 14:09
Copilot AI review requested due to automatic review settings April 9, 2026 07:18
@alcaeus alcaeus force-pushed the phpc-2699-typed-properties branch from 5ee7b1a to 0a3c66b Compare April 9, 2026 07:18
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 158 out of 158 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +142 to +146
ZEND_HASH_FOREACH_STR_KEY_VAL_IND(HASH_OF(getThis()), string_key, val)
{
if (Z_TYPE_P(val) == IS_NULL) {
continue;
}
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ReadConcern::bsonSerialize() now iterates over HASH_OF(getThis()), which will include dynamic properties (see tests/readPreference/bug1598-002.phpt setting $rp->a). That means user-defined properties can be injected into the serialized BSON document, which is not part of ReadConcern’s BSON representation. Consider explicitly serializing only the declared "level" property (or whitelisting allowed keys) instead of iterating over all object properties.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We decided to ignore this for the time being as dynamic property assignments are done. We can also switch to read-only classes when dropping support for PHP 8.1: https://3v4l.org/BaU6M

Comment on lines +438 to +443
ZEND_HASH_FOREACH_STR_KEY_VAL_IND(HASH_OF(getThis()), string_key, val)
{
if (
(Z_TYPE_P(val) == IS_NULL) || (!strcmp(ZSTR_VAL(string_key), "maxStalenessSeconds") && Z_TYPE_P(val) == IS_LONG && Z_LVAL_P(val) == MONGOC_NO_MAX_STALENESS)) {
continue;
}
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ReadPreference::bsonSerialize() iterates over HASH_OF(getThis()), which can include dynamic properties. This allows unrelated user-defined properties to be included in the serialized BSON document, changing the object’s BSON representation unexpectedly. Consider building the BSON document from a fixed set of declared properties (mode/tags/maxStalenessSeconds/hedge) and ignoring dynamic properties.

Copilot uses AI. Check for mistakes.
Copilot AI review requested due to automatic review settings April 9, 2026 14:28
@alcaeus alcaeus force-pushed the phpc-2699-typed-properties branch from 837e6a1 to 9a3c037 Compare April 9, 2026 14:28
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 158 out of 158 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 158 out of 158 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@alcaeus alcaeus merged commit 2f18e42 into mongodb:v2.x Apr 13, 2026
77 checks passed
@alcaeus alcaeus deleted the phpc-2699-typed-properties branch April 13, 2026 09:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants