-
-
Notifications
You must be signed in to change notification settings - Fork 62
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ImageStream implementation #147
ImageStream implementation #147
Conversation
`ImageStream` is an extension of `Stream`, with the following key differences: - The `$resource` property is documented as being `null|GdIamge` - The constructor accepts a `GdImage` **only**, and assigns it to the `$resource` property - The `detach()` method no declares a return type of `null|GdImage` - The `attach()` method documents via annotation that the `$resource` it accepts can only be of type `GdImage`; the method raises an exception for any other argument. Signed-off-by: Matthew Weier O'Phinney <matthew@weierophinney.net>
When a `GdImage` is used, the class will now issue an `E_USER_DEPRECATED` indicating the user should use `ImageStream` instead. Signed-off-by: Matthew Weier O'Phinney <matthew@weierophinney.net>
…with GdImage Updates `createStreamFromResource()` to detect `GdImage` resources, and, when detected, create and return an `ImageStream` instead of a `Stream`. Signed-off-by: Matthew Weier O'Phinney <matthew@weierophinney.net>
* allow it to extend Stream. If defined here with a type, PHP will raise a | ||
* fatal error complaining that it must not define a type for the property. | ||
*/ | ||
class ImageStream extends Stream |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should not extend Stream at all. It is not compatible with any of its methods.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree here, extending Stream
makes no sense as we have to handle almost every method in a specific way.
Especially due to the GdImage
/resource
problematic, we could also just provide GdImageStream
as it is for GdImage
only.
Not sure if some1 wants to use this for anything else, so renaming it might be helpful but I do not insist on this.
@@ -359,6 +361,14 @@ private function isValidStreamResourceType(mixed $resource): bool | |||
} | |||
|
|||
if ($resource instanceof GdImage) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I get type errors for pretty much all methods in Stream when GdImage is used as resource.
Uncaught TypeError: stream_get_contents(): Argument #1 ($stream) must be of type resource, GdImage given
Uncaught TypeError: stream_get_meta_data(): Argument #1 ($stream) must be of type resource, GdImage given
Uncaught TypeError: fseek(): Argument #1 ($stream) must be of type resource, GdImage given
and so on
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It did not work at all for a long time. I suggest "support" is dropped without deprecation as no actual users will be affected.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yah, there were no proper tests for PHP 8.1
Thats why I raised the whole concerns in the first place.
Also stream seeking on gdimage
resources never worked and plenty of other stuff (i.e. writing to that stream).
Thats why the new ImageStream
implementation has to return false
for isSeekable
, isWritable
, etc.
Has to throw exceptions for getMetadata
, etc.
* | ||
* @param resource|GdImage $resource | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure if this is good. Expanding parameter types is considered type safe. The problem is anyone needing GdImage
support can no longer depend on PSR factory interface because that would not be type safe.
Wouldn't that go against interoperability goal between libraries since this will be creating dependency on diactoros and this implementation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
GdImage
is considered an opaque resource type. The general assumption of PSR-7 and PSR-17's stream support is that it can work with resources of any type. However, both pre-date the opaque resource types.
This suggests two things to me:
- They should allow usage with opaque resource types where they make sense. Since you can have image resources spit out content, I'd argue they make sense here, and, in some ways, are better than normal file-based resources where you lose idempotency.
- Alternately, PSR-7 and/or PSR-17 need updates to either explicitly allow or disallow usage with opaque resource types.
For now, I don't think this patch violates interoperability, as PSR-7 and PSR-17 do talk about resources, and this is a type of resource.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would not support GdImage
via StreamFactory
TBH
PSR is clear here:
https://github.com/php-fig/http-factory/blob/e616d01114759c4c489f93b099585439f795fe35/src/StreamFactoryInterface.php#L44
If some1 wants to use GdImage
with StreamFactoryInterface
they are already lost. If they hardly depend on laminas as an implementation, they don't need PSR and thus can directly instantiate ImageStream
rather than using the interchangeable factory. The whole point of using the StreamFactory
is to provide interchangeability and if we now decide to support GdImage
that would only fork for laminas but not for guzzle for example. Having these kind of incompatibility is super annoying and thus, I'd say we should not allow that at all.
@@ -67,12 +71,29 @@ public function testCanInstantiateWithStreamResource(): void | |||
$this->assertInstanceOf(Stream::class, $stream); | |||
} | |||
|
|||
/** | |||
* @todo For version 3, this test should verify that a GdImage raises an exception. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
with v3 we should verify if either string
or resource
is passed, everything else should throw an exception.
@@ -359,6 +361,14 @@ private function isValidStreamResourceType(mixed $resource): bool | |||
} | |||
|
|||
if ($resource instanceof GdImage) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yah, there were no proper tests for PHP 8.1
Thats why I raised the whole concerns in the first place.
Also stream seeking on gdimage
resources never worked and plenty of other stuff (i.e. writing to that stream).
Thats why the new ImageStream
implementation has to return false
for isSeekable
, isWritable
, etc.
Has to throw exceptions for getMetadata
, etc.
* | ||
* @param resource|GdImage $resource | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would not support GdImage
via StreamFactory
TBH
PSR is clear here:
https://github.com/php-fig/http-factory/blob/e616d01114759c4c489f93b099585439f795fe35/src/StreamFactoryInterface.php#L44
If some1 wants to use GdImage
with StreamFactoryInterface
they are already lost. If they hardly depend on laminas as an implementation, they don't need PSR and thus can directly instantiate ImageStream
rather than using the interchangeable factory. The whole point of using the StreamFactory
is to provide interchangeability and if we now decide to support GdImage
that would only fork for laminas but not for guzzle for example. Having these kind of incompatibility is super annoying and thus, I'd say we should not allow that at all.
Summing up Slack discussion: Currently, neither PHP 7.4 nor 8.0 with both
For PHP 8.0 and So the whole |
Based on the Slack conversation and the feedback here, I'm going to close this patch, and then open a new one against 3.0.x to drop support for GD images in |
Description
Per discussion in #57, this patch does the following:
ImageStream
class as an extension ofStream
that only works withGdImage
resources.Stream
to emit anE_USER_DEPRECATED
error when used with aGdImage
resource, pointing users to the newImageStream
implementation.StreamFactory::createStreamFromResource()
to detectGdImage
resources, and to create and return anImageStream
when it does.The plan will be for 3.0.0 to remove support for
GdImage
fromStream
.