Skip to content
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

PHP ^7.4 Compatibility (Including 8.1) #1805

Merged
merged 42 commits into from
Dec 13, 2021
Merged

Conversation

oojacoboo
Copy link
Contributor

@oojacoboo oojacoboo commented Dec 5, 2021

This PR includes support for PHP >= 7.4, resolving all type errors and deprecation warnings.

I should further add that PHP 7.3 is no longer receiving security updates - it's unmaintained. And, 7.4 will be unmaintained next year.

It appears evident that there is a lot of nullable behavior tied to business logic throughout the lib. It's quite unfortunate. I was able to strictly type and enforce in many places. However, in others, there were some business logic decisions that had to be made. And without greater knowledge of how some of these classes are instantiated and used, these decisions were typically permissive.

I’ve gone ahead and conformed with your code-sniffer rules @dereuromark. I will say though, I disagree with the requirement to include a docblock with PHP 8.1. Going forward, now that we have support to fully type a function, they are self documenting. If a function doesn’t require additional comments, for the function - itself, it’s arguments, return value, throws, etc - a docblock shouldn’t be required.

This PR actually took significantly more time than I expected. There were a lot of little things, especially to get all the tests passing.

The docs need updating to make clear only PHP 7.4 and greater is supported. I didn’t see them in the repo. It’d be nice to have the docs in the repo with a static site generator. I’ve used docusaurus on other OSS libs.

Closes #1795

@oojacoboo oojacoboo mentioned this pull request Dec 5, 2021
@dereuromark
Copy link
Contributor

Isn't it a bit too early for this?
Propel was always a bit more on the conservative side of PHP dependency to allow also older projects to still be compatible with latest release.
So at this time, we are PHP7.3+ but we could discuss to at least keep the latest minor of 7.x, so PHP7.4+ maybe.
One more release at least here, and in a few months we could still discuss 8.0+ then?

@oojacoboo
Copy link
Contributor Author

Isn't it a bit too early for this? Propel was always a bit more on the conservative side of PHP dependency to allow also older projects to still be compatible with latest release. So at this time, we are PHP7.3+ but we could discuss to at least keep the latest minor of 7.x, so PHP7.4+ maybe. One more release at least here, and in a few months we could still discuss 8.0+ then?

@dereuromark I have no problem with continuing to target ^7.4. Do you have suggestions on how that's going to be achieved though? I outlined the issue in the original comment:

Firstly, the mixed type isn’t supported in versions prior to 8.0, and 8.1 has strictly typed interfaces that require the mixed return type. We’d have to implement a custom namespaced shimmed interface instead of the core interfaces, update any logic that is typed or checking for instances of this interface, and then hope there aren’t any other side-effects in user-land from reliance on those interfaces.

@dereuromark
Copy link
Contributor

We will not be able to add any such types, thats fine though.
We can do that once we cross that bridge, it should be still before declaring a stable version so that we can actually add this in semver compliance.

// Accessor visibility
$visibility = $this->getMethodVisibility('accessorVisibility', 'defaultAccessorVisibility');
// Accessor visibility - no idea why this returns null, or the use case for that
$visibility = $this->getMethodVisibility('accessorVisibility', 'defaultAccessorVisibility') ?: '';
Copy link
Contributor

Choose a reason for hiding this comment

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

But is continuing with an empty string better then?
Shouldnt this throw an exception or default to a sensible value instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm all for throwing Exceptions. But, this lib has a ton of business logic around null values. I don't know if it's the tests, or these values are encountered during normal model generation, or what. In many cases, null is being passed to a core string function that converts it to an empty string. However, with PHP 8, that's not allowed, as there are more strict type checks. In this case, we're just passing an empty string into strtolower instead of null. But there are quite a few cases like this through the codebase.

The best solution here is to type our internal methods/properties. This will prevent most of these issues and start to narrow down the actual source of the issue.

Copy link
Contributor

Choose a reason for hiding this comment

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

True
But then I would rather have string|null here, what do you think?
As checking against null vs non empty string sounds a bit cleaner from the API level.

Copy link
Contributor Author

@oojacoboo oojacoboo Dec 9, 2021

Choose a reason for hiding this comment

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

I'm not really sure I'm following you. $visibility ends up null in some cases. It's then passed to strtolower which results in a type error on PHP 8. Before PHP8, that'd just get converted to an empty string. I'm simply converting to an empty string earlier to avoid a type error.

Copy link
Contributor

Choose a reason for hiding this comment

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

Fair enough

@@ -29,6 +29,7 @@ public function testUniqueValidatorPass()
$publisher = new Publisher();
$publisher->setName('Happy Reading');
$publisher->setWebsite('http://www.happyreading.com');
$publisher->save();
Copy link
Contributor

Choose a reason for hiding this comment

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

Why does it need to be saved before validating?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It was failing before saving, and other examples all saved, so I assumed so.

Copy link
Contributor

Choose a reason for hiding this comment

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

After saving I wouldnt expect validation to do anything, so we might actually "cloak" the issue here this way.
It was working before, we should find out how it will work again now without the save() part.

Copy link
Contributor Author

@oojacoboo oojacoboo Dec 9, 2021

Choose a reason for hiding this comment

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

Propel\Tests\Generator\Behavior\Validate\UniqueConstraintTest::testUniqueValidatorPass
Failed asserting that false is true.

Without the save, we get the above. I don't know what's failing validation or how validation works. Additionally, it fails on master branch as well for me, locally. So, I'm guessing the issue is unrelated to this PR.

Copy link
Contributor

Choose a reason for hiding this comment

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

Interesting..

phpstan-baseline.neon Outdated Show resolved Hide resolved
@dereuromark
Copy link
Contributor

@mringler What do you think?
I think the changes look good so far and show a general improvement towards the type safe future we would like to see.
A good first step - of many to come.

composer.json Outdated Show resolved Hide resolved
src/Propel/Generator/Config/GeneratorConfig.php Outdated Show resolved Hide resolved
@dereuromark
Copy link
Contributor

Any second review please? So we can move forward?

@dereuromark dereuromark merged commit 61c7657 into propelorm:master Dec 13, 2021
@oojacoboo oojacoboo deleted the php8 branch January 6, 2022 04:25
@dereuromark dereuromark mentioned this pull request Mar 23, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

PHP 8.0
4 participants