yii2-gii
yii2-gii copied to clipboard
Generator trim validator causes exception in PHP 8.1.9
What steps will reproduce the problem?
Using gii, try to Preview a Model.
What's expected?
The typical results with new model code and chance to see diff if there is a difference
What do you get instead?
PHP Deprecated Warning – [yii\base\ErrorException] (https://www.yiiframework.com/doc-2.0/yii-base-errorexception.html) trim(): Passing null to parameter #1 ($string) of type string is deprecated
in /var/www/html/nd4c_web/vendor/yiisoft/yii2/validators/FilterValidator.php at line 81
Additional info
This works in PHP 8.0.22, but fails in PHP 8.1.9
Debugging this I found that the following:
$model = yii\gii\generators\model\Generator $this->filter = trim $attribute = queryClass $value = null
In PHP 8.0 the $value of 'queryClass' is also null, but the trim filter does not cause an exception.
I believe this worked fine in earlier versions of PHP 8.1, but I don't know at what version it started.
If I select "Generate ActiveQuery" and the queryClass field becomes visible this works fine, because queryClass is not null.
Q | A |
---|---|
Yii version | 2.0.46 |
PHP version | 8.1.9 |
Database version | 10.3.34-MariaDB-0ubuntu0.20.04.1 |
Operating system | Linux Mint 20.3 with Kernel Linux 5.15.0-46-generic |
I tried this on another computer running MInt 21 but with similar specs. It ran fine, then I ran composer update with a newer version of the composer.json file and it failed.
I was having problems with PHPUnit and changed my composer.json file - it is not the default settings for Yii2. These are the sections that changed: Previous:
"require": {
"php": ">=8.0",
"yiisoft/yii2": "~2.0.14",
"yiisoft/yii2-bootstrap": "~2.0.0",
"yiisoft/yii2-swiftmailer": "~2.1.0",
"yiisoft/yii2-queue": "^2.1",
"yiisoft/yii2-jui": "~2.0.0",
"yiisoft/yii2-imagine": "~2.2.0",
"mpdf/mpdf": "^8.0",
"himiklab/yii2-colorbox-widget": "*",
"slavkovrn/yii2-lightbox": "^1.0",
"kekaadrenalin/yii2-imap": "dev-master",
"2amigos/yii2-date-time-picker-widget" : "*",
"2amigos/yii2-tinymce-widget": "*",
"kartik-v/yii2-widget-datetimepicker": "*",
"php-mime-mail-parser/php-mime-mail-parser": "^7.0",
"yiisoft/yii2-symfonymailer": "^2.0"
},
"require-dev": {
"yiisoft/yii2-debug": "~2.1.0",
"yiisoft/yii2-gii": "~2.1.0",
"yiisoft/yii2-faker": "~2.0.0",
"codeception/codeception": "^4.0",
"codeception/verify": "~0.5.0 || ~1.1.0",
"codeception/specify": "~0.4.6",
"symfony/browser-kit": ">=2.7 <=4.2.4",
"codeception/module-filesystem": "^1.0.0",
"codeception/module-yii2": "^1.0.0",
"codeception/module-asserts": "^1.0.0",
"rector/rector": "^0.12.12"
},
New:
"require": {
"php": ">=8.0",
"yiisoft/yii2": "~2.0.14",
"yiisoft/yii2-bootstrap": "~2.0.0",
"yiisoft/yii2-swiftmailer": "~2.1.0",
"yiisoft/yii2-queue": "^2.1",
"yiisoft/yii2-jui": "~2.0.0",
"yiisoft/yii2-imagine": "~2.2.0",
"mpdf/mpdf": "^8.0",
"bower-asset/jquery-colorbox": "*",
"kekaadrenalin/yii2-imap": "dev-master",
"2amigos/yii2-date-time-picker-widget" : "*",
"2amigos/yii2-tinymce-widget": "*",
"kartik-v/yii2-widget-datetimepicker": "*",
"php-mime-mail-parser/php-mime-mail-parser": "^7.0",
"yiisoft/yii2-symfonymailer": "^2.0"
},
"require-dev": {
"yiisoft/yii2-debug": "~2.1.0",
"yiisoft/yii2-gii": "~2.1.0",
"yiisoft/yii2-faker": "~2.0.0",
"codeception/codeception": "^5.0.0-RC6",
"codeception/verify": "~0.5.0 || ~1.1.0",
"codeception/specify": "^2.0",
"symfony/browser-kit": ">=2.7",
"codeception/module-filesystem": "^3",
"codeception/module-yii2": "^1.1.7",
"codeception/module-asserts": "^3.0",
"rector/rector": "^0.12.12"
},
I reverted my composer back to the older version, ran composer update, but I still get the exception in gii.
At this point I have no idea what the problem is...
Try replacing "yiisoft/yii2-gii": "~2.1.0"
with "yiisoft/yii2-gii": "~2.2.0"
- your current constraint blocks update to the most recent version of yiisoft/yii2-gii
.
Thanks. I did try that but I still get the same error if I do not select "Generate ActiveQuery" which leaves the queryClass field as null, because the form will not return it because it's disabled.
I tried a completely different project and matched the composer.json and it still works fine. So I'm guessing that I've done something in this project that's making PHP more strict in it's error handling - or I've broken the Yii error handler somehow.
Passing null to trim is a real PHP Deprecated Warning. I'm guessing my index.php entry script is too strict.
Arrghhh! I have this in my site config file for dev: error_reporting(E_ALL & ~E_STRICT & ~E_DEPRECATED & ~E_NOTICE);
This project is very old since before 2011 (originally Yii1), and I've been caught several times by things deprecated suddenly disappearing...
But, seriously, Thanks for the gii version tip. I'd seen the newer version in newer projects and hadn't dawned on me that I should upgrade this project.
My thinking is that the FilterValidator -> validateAttribute should check whether the filter is trim or not. Or have some way to handle or a mechanizm for null values and filters that cannot handle null. Some filters might just be skipped, some may need the null converted to a real value, and some might fail the filter on null.
Actually the code calling the Filter Validator needs to be adjusted as per it's comments:
/**
* FilterValidator converts the attribute value according to a filter.
*
* FilterValidator is actually not a validator but a data processor.
* It invokes the specified filter callback to process the attribute value
* and save the processed value back to the attribute. The filter must be
* a valid PHP callback with the following signature:
*
* ```php
* function foo($value) {
* // compute $newValue here
* return $newValue;
* }
* ```
*
* Many PHP functions qualify this signature (e.g. `trim()`).
* If the callback function requires non-null argument (important since PHP 8.1)
* remember to set [[skipOnEmpty]] to `true` otherwise you may trigger an error.
*
* To specify the filter, set [[filter]] property to be the callback.
*
* @author Qiang Xue <[email protected]>
* @since 2.0
*/
Solved by https://github.com/yiisoft/yii2/pull/19539
Need to use trim
validator instead of callback.
https://github.com/yiisoft/yii2-gii/commit/c9efc088cd7003353125b2a2cc696d4b1028eafc