Problem/Motivation
In PHP 8.0 imagecreatefrom* functions no longer return a resource. They return a \GdImage object.
Proposed resolution
Change \Drupal\system\Plugin\ImageToolkit\GDToolkit to support both a resource and a \GdImage object.
See https://github.com/php/php-src/blob/master/UPGRADING#L249
I think this issue will be okay for PHP 7.0 because it's really only loosening what we expect in \Drupal\system\Plugin\ImageToolkit\GDToolkit::$resource but testing this will be harder without all fixes from #3156595: Make Drupal 9 installable on PHP8
Remaining tasks
User interface changes
None
API changes
\Drupal\system\Plugin\ImageToolkit\GDToolkit::getResource() will return different things depending on PHP version.
\Drupal\system\Plugin\ImageToolkit\GDToolkit::setResource() will expect different things depending on PHP version.
Data model changes
None
Release notes snippet
@todo
| Comment | File | Size | Author |
|---|---|---|---|
| #23 | 3156887-23.patch | 3.35 KB | andypost |
| #23 | interdiff.txt | 671 bytes | andypost |
| #19 | 3156887-19.patch | 3.35 KB | ayushmishra206 |
Comments
Comment #2
alexpottHere's what worked on #3156595: Make Drupal 9 installable on PHP8 but it needs work to tighten up the API.
Comment #3
alexpottComment #4
mondrakeWhat should be done in the
__destructor of the toolkit then? Isimagedestroyrelevant at all in PHP 8?Comment #5
alexpott@mondrake that's a good question. I don't know the answer to that. Well now I do! https://github.com/php/php-src/blob/92c4b0651368a4135f692af48f4716c96de4...
Comment #6
andypostAdded type-hints
Comment #7
mondrakeThe purpose of
testResourceDestruction()is to check that once Drupal's Image objects are losing scope, the memory allocated to the image is cleaned up. See #2531570: Image objects should release memory when losing scope.The test would still be useful, so I changed it to test memory allocated at various stages.
Comment #8
ayesh commented`is_resource()` can accept any data type, but PHP 7.2 and older versions will fatal error on `instanceOf` checks. So for PHP 7.2 and older version compatibility, we will need a `is_object()` check too: https://php.watch/versions/8.0/gdimage#gdimage-is-resourceFurther, `imagedestroy()` function is still available in PHP 8. I think we can simply call `imagedestroy()` without any additional checks because PHP internally no-ops it anyway.
Comment #9
andypostConfirm as no-op https://github.com/php/php-src/blob/master/ext/gd/gd.c#L2040-L2052
Fixed check as suggested #8 if we need to backport it to PHP < 7.3 https://3v4l.org/lJnKN
Also replaced deprecated 'toInt()' usage for Bytes
Now it needs follow-up to finish @todo
Comment #10
mondrakethis @todo needs to be moved above into the docblock of the method.
it would be nicer to use the service provided by #3000050: Replace \Drupal\Component\Utility\Environment::checkMemoryLimit with a PHP memory checking helper class and service but, alas, that is still NR.
could use some comments
same
Comment #11
andypostFiled follow-up #3173031: Clean-up \Drupal\system\Plugin\ImageToolkit\GDToolkit when core require php 8.0
Did not change #3000050 because
checkMemoryLimit()is not getting current usage, will dig this issue laterComment #12
mondrakeRTBC +1 but I cannot. Thanks @andypost
Comment #13
andypostit could use
EnvironmentMemory::getUsed()but not sure it better or more intuitive then one function call? ref #3000050-43: Replace \Drupal\Component\Utility\Environment::checkMemoryLimit with a PHP memory checking helper class and serviceMaybe it more useful to get limits...
Comment #14
alexpottI'm not a huge fan of the memory usage testing. It looks fragile and the type of thing that'll fail when PHP makes memory optimisations or changes to garbage collection. I really don't think it is in scope to add this here and should be in follow-up were we can discuss. This would the first instance of testing memory usage like this in core. Also I'm not 100% convinced the changes added here will pass on PHP 8 - again due to the vagaries of garbage collection.
Comment #15
gábor hojtsyRetitling so it does not sound like a feature request :)
Comment #16
alexpottThe current code introduces some coding standards errors
Comment #17
andypostThis test makes sense only while GD using resources, so I reverted test change to #2 and added another todo
PS patch smaller then interdiff
Comment #18
alexpottUnused use.
Also https://www.drupal.org/pift-ci-job/1836885 shows that the memory testing introduced by earlier patches would not have worked.
Comment #19
ayushmishra206 commentedMade the changes pointed out in #18. Please review.
Comment #20
mondrake#14 IMO we should have a followup opened and referred to in the comment. I see the point in #14, but the root cause for entire test to be developed was memory management issues that were addressed in #2531570: Image objects should release memory when losing scope. The memory was filled up by not gc'ed resources, and the solution was to destroy the resources in __destruct. Now we will be losing test coverage of the root cause.
Comment #21
andypostThere's test which makes sense only for php7, personally instead of measuring RAM I'd converted test to unit-test to make sure destructor executes resource destroy.
Measuring memory is bad idea because it's PHP GC territory to decide when and how reclaim RAM
There's follow-up already to get rid of method and test, so could be used to improve test
Comment #23
andypostFiled another follow-up #3179058: Remove ToolkitGdTest::testResourceDestruction() when core require PHP 8.0
So clean-up of destructor and fate of the test are separate issues
Comment #24
longwaveChanges look OK as per the PHP 8 upgrade notes. I checked for other uses of
is_resource()and there are a few GD related ones but on closer inspection they all relate to destroying images after use so is_resource() alone is still OK and these can be removed when we have PHP 8 as a minimum dependency.Comment #25
alexpottThis is a critical because without it we get deprecation notices on PHP 8.0
Comment #28
catchThis looks great as do the follow-ups.
Committed/pushed to 9.2.x and cherry-picked to 9.1.x, thanks!