Replies: 1 comment
-
I'm not familiar with the versioning policy of the libraries, but wouldn't it be easiest to just increase the major version when something like this happens? That way you don't have to worry about breaking changes. In the case of your example, it could also be possible that new properties are appended as new constructor arguments, but that you fix the order in the constructor body: public function __construct(bool $is_eaten, int $ripeness = null)
{
parent::__construct([
'ripeness' => $ripeness,
'is_eaten' => $is_eaten,
]);
} Only I'm not sure if this is possible since these classes are generated, like you said. Classic case where a generic solution does not necessarily produce the best result. |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
In PHP 8.0, PHP introduced Named Arguments. These have a lot of advantages, from readability to an improved developer experience, and the dedicated group of PHP advocates at Google would love to take advantage of them. But PHP's implementation is not without problems. PHP named arguments are unique because they are entirely controlled by the caller; the library author has no control over how or when named arguments are used. This can be a problem. We have visibility and mutability control structures such as
private
,protected
,final
, andreadonly
to help us define opinionated ways their libraries can be used in order to protect library consumers from potential breaking changes, but we do not have similar control structures for named arguments versus positional arguments.If a library author in another language implements positional arguments, one advantage is the argument names can change. If a library author in another language implements named arguments, one advantage is the position these arguments are defined can change. But now in the case of PHP, anyone who writes arguments to a function now must maintain backwards compatibility with both that argument's position and name, as only the user can choose how their function is called.
A concrete example of how this is a problem for us is with Protobuf (Protocol Buffers). We use protobuf to generate all our Client Libraries, and Protobuf guarantees backwards compatibility by promising a distinct number and name for each property of a message.
But as the order of these arguments is not guaranteed, the following change to the protobuf message is considered non-breaking, but would break any implementation in PHP which tries to use named arguments:
Library authors may instead resort to using parameter arrays in the constructor, which removes native type safety, has a poorer developer experience, and requires argument validation to be handled by the library author:
Setters could be used instead of constructor arguments, which works in this case, but not for class methods. In a situation where argument names can change but the position is guaranteed, library authors cannot guarantee backwards compatibility. A solution for this case, as far as I know, doesn't exist.
One thing the community can do is standardize DocBlock attributes such as
@no-named-arguments
(and a corresponding@only-named-arguments
) in a PSR to provide standards for named arguments and guidance for developers and static analyzers. Similar to visibility, providing more control to library authors to allow opinionated use of their exposed APIs will help both the author and the consumer.Are there any other potential solutions, and has anyone else encountered this as an issue?
Beta Was this translation helpful? Give feedback.
All reactions