diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index b30366e..47259a1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -33,7 +33,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - php: ['5.4', '5.5', '5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0'] + php: ['5.4', '5.5', '5.6', '7.0', '7.1', '7.2', '7.3', '7.4', '8.0', '8.1'] steps: - name: Generate french locale diff --git a/composer.json b/composer.json index 84af41a..240a682 100644 --- a/composer.json +++ b/composer.json @@ -118,9 +118,13 @@ "phpunit/phpunit-mock-objects": { "Fix PHP 7 and 8 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_mock_objects.patch" }, + "phpunit/php-file-iterator": { + "Fix PHP 8.1 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_path_file_iterator.patch" + }, "phpunit/phpunit": { "Fix PHP 7 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_php7.patch", - "Fix PHP 8 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_php8.patch" + "Fix PHP 8 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_php8.patch", + "Fix PHP 8.1 compatibility": "https://yiisoft.github.io/phpunit-patches/phpunit_php81.patch" } } } diff --git a/composer.lock b/composer.lock index 35d4dd1..6d56b84 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "8f9a4d7e645592f806605d32d676f54e", + "content-hash": "1dd00a91030b984d98f13fa6d6ecf7d9", "packages": [ { "name": "bower-asset/inputmask", @@ -1338,16 +1338,16 @@ }, { "name": "phpunit/phpunit", - "version": "4.8.34", + "version": "4.8.36", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "7eb45205d27edd94bd2b3614085ea158bd1e2bca" + "reference": "46023de9a91eec7dfb06cc56cb4e260017298517" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/7eb45205d27edd94bd2b3614085ea158bd1e2bca", - "reference": "7eb45205d27edd94bd2b3614085ea158bd1e2bca", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/46023de9a91eec7dfb06cc56cb4e260017298517", + "reference": "46023de9a91eec7dfb06cc56cb4e260017298517", "shasum": "" }, "require": { @@ -1408,9 +1408,9 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/4.8.34" + "source": "https://github.com/sebastianbergmann/phpunit/tree/4.8.36" }, - "time": "2017-01-26T16:15:36+00:00" + "time": "2017-06-21T08:07:12+00:00" }, { "name": "phpunit/phpunit-mock-objects", diff --git a/framework/BaseYii.php b/framework/BaseYii.php index 0aa00f7..8814e32 100644 --- a/framework/BaseYii.php +++ b/framework/BaseYii.php @@ -130,7 +130,7 @@ class BaseYii */ public static function getAlias($alias, $throwException = true) { - if (strncmp($alias, '@', 1) !== 0) { + if (strncmp((string)$alias, '@', 1) !== 0) { // not an alias return $alias; } diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md index ddf4b51..4f8b839 100644 --- a/framework/CHANGELOG.md +++ b/framework/CHANGELOG.md @@ -5,6 +5,7 @@ Yii Framework 2 Change Log ------------------------ - Bug #19138: Allow digits in language code (ntesic) +- Bug #19041: Fix PHP 8.1 issues (longthanhtran, samdark, pamparam83, sartor, githubjeka) 2.0.44 December 30, 2021 diff --git a/framework/base/ArrayAccessTrait.php b/framework/base/ArrayAccessTrait.php index 87a1db1..9c632bc 100644 --- a/framework/base/ArrayAccessTrait.php +++ b/framework/base/ArrayAccessTrait.php @@ -26,6 +26,7 @@ trait ArrayAccessTrait * It will be implicitly called when you use `foreach` to traverse the collection. * @return \ArrayIterator an iterator for traversing the cookies in the collection. */ + #[\ReturnTypeWillChange] public function getIterator() { return new \ArrayIterator($this->data); @@ -36,6 +37,7 @@ trait ArrayAccessTrait * This method is required by Countable interface. * @return int number of data elements. */ + #[\ReturnTypeWillChange] public function count() { return count($this->data); @@ -46,6 +48,7 @@ trait ArrayAccessTrait * @param mixed $offset the offset to check on * @return bool */ + #[\ReturnTypeWillChange] public function offsetExists($offset) { return isset($this->data[$offset]); @@ -56,6 +59,7 @@ trait ArrayAccessTrait * @param int $offset the offset to retrieve element. * @return mixed the element at the offset, null if no element is found at the offset */ + #[\ReturnTypeWillChange] public function offsetGet($offset) { return isset($this->data[$offset]) ? $this->data[$offset] : null; @@ -66,6 +70,7 @@ trait ArrayAccessTrait * @param int $offset the offset to set element * @param mixed $item the element value */ + #[\ReturnTypeWillChange] public function offsetSet($offset, $item) { $this->data[$offset] = $item; @@ -75,6 +80,7 @@ trait ArrayAccessTrait * This method is required by the interface [[\ArrayAccess]]. * @param mixed $offset the offset to unset element */ + #[\ReturnTypeWillChange] public function offsetUnset($offset) { unset($this->data[$offset]); diff --git a/framework/base/ExitException.php b/framework/base/ExitException.php index 4fde6a8..fe9f5e7 100644 --- a/framework/base/ExitException.php +++ b/framework/base/ExitException.php @@ -33,6 +33,10 @@ class ExitException extends \Exception public function __construct($status = 0, $message = null, $code = 0, $previous = null) { $this->statusCode = $status; - parent::__construct($message, $code, $previous); + if ($previous === null) { + parent::__construct((string)$message, $code); + } else { + parent::__construct((string)$message, $code, $previous); + } } } diff --git a/framework/base/Model.php b/framework/base/Model.php index e957a96..40c820e 100644 --- a/framework/base/Model.php +++ b/framework/base/Model.php @@ -995,6 +995,7 @@ class Model extends Component implements StaticInstanceInterface, IteratorAggreg * This method is required by the interface [[\IteratorAggregate]]. * @return ArrayIterator an iterator for traversing the items in the list. */ + #[\ReturnTypeWillChange] public function getIterator() { $attributes = $this->getAttributes(); @@ -1008,6 +1009,7 @@ class Model extends Component implements StaticInstanceInterface, IteratorAggreg * @param string $offset the offset to check on. * @return bool whether or not an offset exists. */ + #[\ReturnTypeWillChange] public function offsetExists($offset) { return isset($this->$offset); @@ -1020,6 +1022,7 @@ class Model extends Component implements StaticInstanceInterface, IteratorAggreg * @param string $offset the offset to retrieve element. * @return mixed the element at the offset, null if no element is found at the offset */ + #[\ReturnTypeWillChange] public function offsetGet($offset) { return $this->$offset; @@ -1032,6 +1035,7 @@ class Model extends Component implements StaticInstanceInterface, IteratorAggreg * @param string $offset the offset to set element * @param mixed $value the element value */ + #[\ReturnTypeWillChange] public function offsetSet($offset, $value) { $this->$offset = $value; @@ -1043,6 +1047,7 @@ class Model extends Component implements StaticInstanceInterface, IteratorAggreg * It is implicitly called when you use something like `unset($model[$offset])`. * @param string $offset the offset to unset element */ + #[\ReturnTypeWillChange] public function offsetUnset($offset) { $this->$offset = null; diff --git a/framework/base/Security.php b/framework/base/Security.php index 6276bf5..5c86ad8 100644 --- a/framework/base/Security.php +++ b/framework/base/Security.php @@ -298,7 +298,7 @@ class Security extends Component public function hkdf($algo, $inputKey, $salt = null, $info = null, $length = 0) { if (function_exists('hash_hkdf')) { - $outputKey = hash_hkdf($algo, $inputKey, $length, $info, $salt); + $outputKey = hash_hkdf((string)$algo, (string)$inputKey, $length, (string)$info, (string)$salt); if ($outputKey === false) { throw new InvalidArgumentException('Invalid parameters to hash_hkdf()'); } diff --git a/framework/caching/Cache.php b/framework/caching/Cache.php index a4afaee..dd2ae4e 100644 --- a/framework/caching/Cache.php +++ b/framework/caching/Cache.php @@ -526,6 +526,7 @@ abstract class Cache extends Component implements CacheInterface * @param string $key a key identifying the cached value * @return bool */ + #[\ReturnTypeWillChange] public function offsetExists($key) { return $this->get($key) !== false; @@ -537,6 +538,7 @@ abstract class Cache extends Component implements CacheInterface * @param string $key a key identifying the cached value * @return mixed the value stored in cache, false if the value is not in the cache or expired. */ + #[\ReturnTypeWillChange] public function offsetGet($key) { return $this->get($key); @@ -550,6 +552,7 @@ abstract class Cache extends Component implements CacheInterface * @param string $key the key identifying the value to be cached * @param mixed $value the value to be cached */ + #[\ReturnTypeWillChange] public function offsetSet($key, $value) { $this->set($key, $value); @@ -560,6 +563,7 @@ abstract class Cache extends Component implements CacheInterface * This method is required by the interface [[\ArrayAccess]]. * @param string $key the key of the value to be deleted */ + #[\ReturnTypeWillChange] public function offsetUnset($key) { $this->delete($key); diff --git a/framework/console/controllers/HelpController.php b/framework/console/controllers/HelpController.php index f61875f..a6e2cf0 100644 --- a/framework/console/controllers/HelpController.php +++ b/framework/console/controllers/HelpController.php @@ -473,8 +473,8 @@ class HelpController extends Controller */ protected function formatOptionHelp($name, $required, $type, $defaultValue, $comment) { - $comment = trim($comment); - $type = trim($type); + $comment = trim((string)$comment); + $type = trim((string)$type); if (strncmp($type, 'bool', 4) === 0) { $type = 'boolean, 0 or 1'; } diff --git a/framework/db/ArrayExpression.php b/framework/db/ArrayExpression.php index e473eb1..9cb1830 100644 --- a/framework/db/ArrayExpression.php +++ b/framework/db/ArrayExpression.php @@ -104,6 +104,7 @@ class ArrayExpression implements ExpressionInterface, \ArrayAccess, \Countable, * The return value will be casted to boolean if non-boolean was returned. * @since 2.0.14 */ + #[\ReturnTypeWillChange] public function offsetExists($offset) { return isset($this->value[$offset]); @@ -119,6 +120,7 @@ class ArrayExpression implements ExpressionInterface, \ArrayAccess, \Countable, * @return mixed Can return all value types. * @since 2.0.14 */ + #[\ReturnTypeWillChange] public function offsetGet($offset) { return $this->value[$offset]; @@ -137,6 +139,7 @@ class ArrayExpression implements ExpressionInterface, \ArrayAccess, \Countable, * @return void * @since 2.0.14 */ + #[\ReturnTypeWillChange] public function offsetSet($offset, $value) { $this->value[$offset] = $value; @@ -152,6 +155,7 @@ class ArrayExpression implements ExpressionInterface, \ArrayAccess, \Countable, * @return void * @since 2.0.14 */ + #[\ReturnTypeWillChange] public function offsetUnset($offset) { unset($this->value[$offset]); @@ -167,6 +171,7 @@ class ArrayExpression implements ExpressionInterface, \ArrayAccess, \Countable, * The return value is cast to an integer. * @since 2.0.14 */ + #[\ReturnTypeWillChange] public function count() { return count($this->value); @@ -181,6 +186,7 @@ class ArrayExpression implements ExpressionInterface, \ArrayAccess, \Countable, * @since 2.0.14.1 * @throws InvalidConfigException when ArrayExpression contains QueryInterface object */ + #[\ReturnTypeWillChange] public function getIterator() { $value = $this->getValue(); diff --git a/framework/db/BaseActiveRecord.php b/framework/db/BaseActiveRecord.php index 8ae0602..747ac1f 100644 --- a/framework/db/BaseActiveRecord.php +++ b/framework/db/BaseActiveRecord.php @@ -1219,6 +1219,7 @@ abstract class BaseActiveRecord extends Model implements ActiveRecordInterface * @param mixed $offset the offset to check on * @return bool whether there is an element at the specified offset. */ + #[\ReturnTypeWillChange] public function offsetExists($offset) { return $this->__isset($offset); diff --git a/framework/db/BatchQueryResult.php b/framework/db/BatchQueryResult.php index c473d0e..749a57a 100644 --- a/framework/db/BatchQueryResult.php +++ b/framework/db/BatchQueryResult.php @@ -114,6 +114,7 @@ class BatchQueryResult extends Component implements \Iterator * Resets the iterator to the initial state. * This method is required by the interface [[\Iterator]]. */ + #[\ReturnTypeWillChange] public function rewind() { $this->reset(); @@ -124,6 +125,7 @@ class BatchQueryResult extends Component implements \Iterator * Moves the internal pointer to the next dataset. * This method is required by the interface [[\Iterator]]. */ + #[\ReturnTypeWillChange] public function next() { if ($this->_batch === null || !$this->each || $this->each && next($this->_batch) === false) { @@ -197,6 +199,7 @@ class BatchQueryResult extends Component implements \Iterator * This method is required by the interface [[\Iterator]]. * @return int the index of the current row. */ + #[\ReturnTypeWillChange] public function key() { return $this->_key; @@ -207,6 +210,7 @@ class BatchQueryResult extends Component implements \Iterator * This method is required by the interface [[\Iterator]]. * @return mixed the current dataset. */ + #[\ReturnTypeWillChange] public function current() { return $this->_value; @@ -217,6 +221,7 @@ class BatchQueryResult extends Component implements \Iterator * This method is required by the interface [[\Iterator]]. * @return bool whether there is a valid dataset at the current position. */ + #[\ReturnTypeWillChange] public function valid() { return !empty($this->_batch); diff --git a/framework/db/Connection.php b/framework/db/Connection.php index 65fb8f7..6d13565 100644 --- a/framework/db/Connection.php +++ b/framework/db/Connection.php @@ -736,6 +736,11 @@ class Connection extends Component $this->pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, $this->emulatePrepare); } } + + if (PHP_VERSION_ID >= 80100 && $this->getDriverName() === 'sqlite') { + $this->pdo->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, true); + } + if (!$this->isSybase && in_array($this->getDriverName(), ['mssql', 'dblib'], true)) { $this->pdo->exec('SET ANSI_NULL_DFLT_ON ON'); } @@ -1004,7 +1009,7 @@ class Connection extends Component public function getDriverName() { if ($this->_driverName === null) { - if (($pos = strpos($this->dsn, ':')) !== false) { + if (($pos = strpos((string)$this->dsn, ':')) !== false) { $this->_driverName = strtolower(substr($this->dsn, 0, $pos)); } else { $this->_driverName = strtolower($this->getSlavePdo()->getAttribute(PDO::ATTR_DRIVER_NAME)); diff --git a/framework/db/DataReader.php b/framework/db/DataReader.php index 99427f9..d533fd9 100644 --- a/framework/db/DataReader.php +++ b/framework/db/DataReader.php @@ -196,6 +196,7 @@ class DataReader extends \yii\base\BaseObject implements \Iterator, \Countable * In this case, use "SELECT COUNT(*) FROM tableName" to obtain the number of rows. * @return int number of rows contained in the result. */ + #[\ReturnTypeWillChange] public function count() { return $this->getRowCount(); @@ -216,6 +217,7 @@ class DataReader extends \yii\base\BaseObject implements \Iterator, \Countable * This method is required by the interface [[\Iterator]]. * @throws InvalidCallException if this method is invoked twice */ + #[\ReturnTypeWillChange] public function rewind() { if ($this->_index < 0) { @@ -231,6 +233,7 @@ class DataReader extends \yii\base\BaseObject implements \Iterator, \Countable * This method is required by the interface [[\Iterator]]. * @return int the index of the current row. */ + #[\ReturnTypeWillChange] public function key() { return $this->_index; @@ -241,6 +244,7 @@ class DataReader extends \yii\base\BaseObject implements \Iterator, \Countable * This method is required by the interface [[\Iterator]]. * @return mixed the current row. */ + #[\ReturnTypeWillChange] public function current() { return $this->_row; @@ -250,6 +254,7 @@ class DataReader extends \yii\base\BaseObject implements \Iterator, \Countable * Moves the internal pointer to the next row. * This method is required by the interface [[\Iterator]]. */ + #[\ReturnTypeWillChange] public function next() { $this->_row = $this->_statement->fetch(); @@ -261,6 +266,7 @@ class DataReader extends \yii\base\BaseObject implements \Iterator, \Countable * This method is required by the interface [[\Iterator]]. * @return bool whether there is a row of data at current position. */ + #[\ReturnTypeWillChange] public function valid() { return $this->_row !== false; diff --git a/framework/db/JsonExpression.php b/framework/db/JsonExpression.php index 36b4603..9ee3967 100644 --- a/framework/db/JsonExpression.php +++ b/framework/db/JsonExpression.php @@ -86,6 +86,7 @@ class JsonExpression implements ExpressionInterface, \JsonSerializable * @since 2.0.14.2 * @throws InvalidConfigException when JsonExpression contains QueryInterface object */ + #[\ReturnTypeWillChange] public function jsonSerialize() { $value = $this->getValue(); diff --git a/framework/db/Query.php b/framework/db/Query.php index 857339f..fc614f7 100644 --- a/framework/db/Query.php +++ b/framework/db/Query.php @@ -921,7 +921,7 @@ PATTERN; */ public function andFilterCompare($name, $value, $defaultOperator = '=') { - if (preg_match('/^(<>|>=|>|<=|<|=)/', $value, $matches)) { + if (preg_match('/^(<>|>=|>|<=|<|=)/', (string)$value, $matches)) { $operator = $matches[1]; $value = substr($value, strlen($operator)); } else { diff --git a/framework/db/SqlToken.php b/framework/db/SqlToken.php index 2fc46d8..be15525 100644 --- a/framework/db/SqlToken.php +++ b/framework/db/SqlToken.php @@ -83,6 +83,7 @@ class SqlToken extends BaseObject implements \ArrayAccess * @param int $offset child token offset. * @return bool whether the token exists. */ + #[\ReturnTypeWillChange] public function offsetExists($offset) { return isset($this->_children[$this->calculateOffset($offset)]); @@ -95,6 +96,7 @@ class SqlToken extends BaseObject implements \ArrayAccess * @param int $offset child token offset. * @return SqlToken|null the child token at the specified offset, `null` if there's no token. */ + #[\ReturnTypeWillChange] public function offsetGet($offset) { $offset = $this->calculateOffset($offset); @@ -108,6 +110,7 @@ class SqlToken extends BaseObject implements \ArrayAccess * @param int|null $offset child token offset. * @param SqlToken $token token to be added. */ + #[\ReturnTypeWillChange] public function offsetSet($offset, $token) { $token->parent = $this; @@ -125,6 +128,7 @@ class SqlToken extends BaseObject implements \ArrayAccess * It is implicitly called when you use something like `unset($token[$offset])`. * @param int $offset child token offset. */ + #[\ReturnTypeWillChange] public function offsetUnset($offset) { $offset = $this->calculateOffset($offset); diff --git a/framework/db/mysql/Schema.php b/framework/db/mysql/Schema.php index 90ecd31..87ae9ad 100644 --- a/framework/db/mysql/Schema.php +++ b/framework/db/mysql/Schema.php @@ -297,7 +297,7 @@ SQL; && preg_match('/^current_timestamp(?:\(([0-9]*)\))?$/i', $info['default'], $matches)) { $column->defaultValue = new Expression('CURRENT_TIMESTAMP' . (!empty($matches[1]) ? '(' . $matches[1] . ')' : '')); } elseif (isset($type) && $type === 'bit') { - $column->defaultValue = bindec(trim($info['default'], 'b\'')); + $column->defaultValue = bindec(trim(isset($info['default']) ? $info['default'] : '', 'b\'')); } else { $column->defaultValue = $column->phpTypecast($info['default']); } diff --git a/framework/grid/Column.php b/framework/grid/Column.php index 465a855..829747e 100644 --- a/framework/grid/Column.php +++ b/framework/grid/Column.php @@ -26,7 +26,7 @@ class Column extends BaseObject */ public $grid; /** - * @var string the header cell content. Note that it will not be HTML-encoded. + * @var null|string the header cell content. Note that it will not be HTML-encoded. */ public $header; /** @@ -127,7 +127,7 @@ class Column extends BaseObject */ protected function renderHeaderCellContent() { - return trim($this->header) !== '' ? $this->header : $this->getHeaderCellLabel(); + return $this->header !== null && trim($this->header) !== '' ? $this->header : $this->getHeaderCellLabel(); } /** @@ -149,7 +149,7 @@ class Column extends BaseObject */ protected function renderFooterCellContent() { - return trim($this->footer) !== '' ? $this->footer : $this->grid->emptyCell; + return $this->footer !== null && trim($this->footer) !== '' ? $this->footer : $this->grid->emptyCell; } /** diff --git a/framework/helpers/BaseConsole.php b/framework/helpers/BaseConsole.php index 2852762..fe84a88 100644 --- a/framework/helpers/BaseConsole.php +++ b/framework/helpers/BaseConsole.php @@ -331,7 +331,7 @@ class BaseConsole */ public static function stripAnsiFormat($string) { - return preg_replace(self::ansiCodesPattern(), '', $string); + return preg_replace(self::ansiCodesPattern(), '', (string)$string); } /** @@ -370,9 +370,9 @@ class BaseConsole return ''; } - $textItems = preg_split(self::ansiCodesPattern(), $string); + $textItems = preg_split(self::ansiCodesPattern(), (string)$string); - preg_match_all(self::ansiCodesPattern(), $string, $colors); + preg_match_all(self::ansiCodesPattern(), (string)$string, $colors); $colors = count($colors) ? $colors[0] : []; array_unshift($colors, ''); diff --git a/framework/helpers/BaseFileHelper.php b/framework/helpers/BaseFileHelper.php index a9c2434..fbd8059 100644 --- a/framework/helpers/BaseFileHelper.php +++ b/framework/helpers/BaseFileHelper.php @@ -161,6 +161,11 @@ class BaseFileHelper throw new InvalidConfigException('The fileinfo PHP extension is not installed.'); } + + if (PHP_VERSION_ID >= 80100) { + return static::getMimeTypeByExtension($file, $magicFile); + } + $info = finfo_open(FILEINFO_MIME_TYPE, $magicFile); if ($info) { @@ -900,7 +905,7 @@ class BaseFileHelper */ public static function changeOwnership($path, $ownership, $mode = null) { - if (!file_exists($path)) { + if (!file_exists((string)$path)) { throw new InvalidArgumentException('Unable to change ownerhip, "' . $path . '" is not a file or directory.'); } diff --git a/framework/helpers/BaseHtml.php b/framework/helpers/BaseHtml.php index 1e66c31..0a9d905 100644 --- a/framework/helpers/BaseHtml.php +++ b/framework/helpers/BaseHtml.php @@ -115,7 +115,7 @@ class BaseHtml */ public static function encode($content, $doubleEncode = true) { - return htmlspecialchars($content, ENT_QUOTES | ENT_SUBSTITUTE, Yii::$app ? Yii::$app->charset : 'UTF-8', $doubleEncode); + return htmlspecialchars((string)$content, ENT_QUOTES | ENT_SUBSTITUTE, Yii::$app ? Yii::$app->charset : 'UTF-8', $doubleEncode); } /** diff --git a/framework/helpers/BaseStringHelper.php b/framework/helpers/BaseStringHelper.php index 738147e..3c1e0ff 100644 --- a/framework/helpers/BaseStringHelper.php +++ b/framework/helpers/BaseStringHelper.php @@ -29,7 +29,7 @@ class BaseStringHelper */ public static function byteLength($string) { - return mb_strlen($string, '8bit'); + return mb_strlen((string)$string, '8bit'); } /** @@ -148,7 +148,7 @@ class BaseStringHelper return static::truncateHtml($string, $count, $suffix); } - $words = preg_split('/(\s+)/u', trim($string), null, PREG_SPLIT_DELIM_CAPTURE); + $words = preg_split('/(\s+)/u', trim($string), 0, PREG_SPLIT_DELIM_CAPTURE); if (count($words) / 2 > $count) { return implode('', array_slice($words, 0, ($count * 2) - 1)) . $suffix; } @@ -316,7 +316,7 @@ class BaseStringHelper */ public static function countWords($string) { - return count(preg_split('/\s+/u', $string, null, PREG_SPLIT_NO_EMPTY)); + return count(preg_split('/\s+/u', $string, 0, PREG_SPLIT_NO_EMPTY)); } /** @@ -436,7 +436,7 @@ class BaseStringHelper $pattern .= 'i'; } - return preg_match($pattern, $string) === 1; + return preg_match($pattern, (string)$string) === 1; } /** @@ -450,8 +450,8 @@ class BaseStringHelper */ public static function mb_ucfirst($string, $encoding = 'UTF-8') { - $firstChar = mb_substr($string, 0, 1, $encoding); - $rest = mb_substr($string, 1, null, $encoding); + $firstChar = mb_substr((string)$string, 0, 1, $encoding); + $rest = mb_substr((string)$string, 1, null, $encoding); return mb_strtoupper($firstChar, $encoding) . $rest; } diff --git a/framework/i18n/GettextMoFile.php b/framework/i18n/GettextMoFile.php index 43b5afa..f632d2d 100644 --- a/framework/i18n/GettextMoFile.php +++ b/framework/i18n/GettextMoFile.php @@ -106,7 +106,7 @@ class GettextMoFile extends GettextFile $messages = []; for ($i = 0; $i < $count; ++$i) { $id = $this->readString($fileHandle, $sourceLengths[$i], $sourceOffsets[$i]); - $separatorPosition = strpos($id, chr(4)); + $separatorPosition = strpos((string)$id, chr(4)); if ((!$context && $separatorPosition === false) || ($context && $separatorPosition !== false && strncmp($id, $context, $separatorPosition) === 0)) { diff --git a/framework/i18n/PhpMessageSource.php b/framework/i18n/PhpMessageSource.php index dc9f2cf..92dfa1b 100644 --- a/framework/i18n/PhpMessageSource.php +++ b/framework/i18n/PhpMessageSource.php @@ -72,7 +72,7 @@ class PhpMessageSource extends MessageSource $messageFile = $this->getMessageFilePath($category, $language); $messages = $this->loadMessagesFromFile($messageFile); - $fallbackLanguage = substr($language, 0, 2); + $fallbackLanguage = substr((string)$language, 0, 2); $fallbackSourceLanguage = substr($this->sourceLanguage, 0, 2); if ($fallbackLanguage !== '' && $language !== $fallbackLanguage) { diff --git a/framework/mail/BaseMailer.php b/framework/mail/BaseMailer.php index 63b6904..1b20058 100644 --- a/framework/mail/BaseMailer.php +++ b/framework/mail/BaseMailer.php @@ -342,8 +342,9 @@ abstract class BaseMailer extends Component implements MailerInterface, ViewCont public function generateMessageFileName() { $time = microtime(true); + $timeInt = (int) $time; - return date('Ymd-His-', $time) . sprintf('%04d', (int) (($time - (int) $time) * 10000)) . '-' . sprintf('%04d', random_int(0, 10000)) . '.eml'; + return date('Ymd-His-', $timeInt) . sprintf('%04d', (int) (($time - $timeInt) * 10000)) . '-' . sprintf('%04d', random_int(0, 10000)) . '.eml'; } /** diff --git a/framework/rest/UrlRule.php b/framework/rest/UrlRule.php index d90ccf5..e1a0e2f 100644 --- a/framework/rest/UrlRule.php +++ b/framework/rest/UrlRule.php @@ -62,7 +62,7 @@ use yii\web\UrlRuleInterface; class UrlRule extends CompositeUrlRule { /** - * @var string the common prefix string shared by all patterns. + * @var string|null the common prefix string shared by all patterns. */ public $prefix; /** @@ -158,7 +158,7 @@ class UrlRule extends CompositeUrlRule } $this->controller = $controllers; - $this->prefix = trim($this->prefix, '/'); + $this->prefix = trim((string)$this->prefix, '/'); parent::init(); } diff --git a/framework/validators/FileValidator.php b/framework/validators/FileValidator.php index b86b6c4..b094821 100644 --- a/framework/validators/FileValidator.php +++ b/framework/validators/FileValidator.php @@ -188,7 +188,7 @@ class FileValidator extends Validator $this->tooSmall = Yii::t('yii', 'The file "{file}" is too small. Its size cannot be smaller than {formattedLimit}.'); } if (!is_array($this->extensions)) { - $this->extensions = preg_split('/[\s,]+/', strtolower($this->extensions), -1, PREG_SPLIT_NO_EMPTY); + $this->extensions = preg_split('/[\s,]+/', strtolower((string)$this->extensions), -1, PREG_SPLIT_NO_EMPTY); } else { $this->extensions = array_map('strtolower', $this->extensions); } @@ -196,7 +196,7 @@ class FileValidator extends Validator $this->wrongMimeType = Yii::t('yii', 'Only files with these MIME types are allowed: {mimeTypes}.'); } if (!is_array($this->mimeTypes)) { - $this->mimeTypes = preg_split('/[\s,]+/', strtolower($this->mimeTypes), -1, PREG_SPLIT_NO_EMPTY); + $this->mimeTypes = preg_split('/[\s,]+/', strtolower((string)$this->mimeTypes), -1, PREG_SPLIT_NO_EMPTY); } else { $this->mimeTypes = array_map('strtolower', $this->mimeTypes); } diff --git a/framework/validators/FilterValidator.php b/framework/validators/FilterValidator.php index 873e1b1..b896e33 100644 --- a/framework/validators/FilterValidator.php +++ b/framework/validators/FilterValidator.php @@ -75,6 +75,7 @@ class FilterValidator extends Validator { $value = $model->$attribute; if (!$this->skipOnArray || !is_array($value)) { + $value = isset($value) ? $value : ''; $model->$attribute = call_user_func($this->filter, $value); } } diff --git a/framework/web/CookieCollection.php b/framework/web/CookieCollection.php index 2e9bef2..938c2b7 100644 --- a/framework/web/CookieCollection.php +++ b/framework/web/CookieCollection.php @@ -54,6 +54,7 @@ class CookieCollection extends BaseObject implements \IteratorAggregate, \ArrayA * It will be implicitly called when you use `foreach` to traverse the collection. * @return ArrayIterator an iterator for traversing the cookies in the collection. */ + #[\ReturnTypeWillChange] public function getIterator() { return new ArrayIterator($this->_cookies); @@ -65,6 +66,7 @@ class CookieCollection extends BaseObject implements \IteratorAggregate, \ArrayA * It will be implicitly called when you use `count($collection)`. * @return int the number of cookies in the collection. */ + #[\ReturnTypeWillChange] public function count() { return $this->getCount(); @@ -198,6 +200,7 @@ class CookieCollection extends BaseObject implements \IteratorAggregate, \ArrayA * @param string $name the cookie name * @return bool whether the named cookie exists */ + #[\ReturnTypeWillChange] public function offsetExists($name) { return $this->has($name); @@ -211,6 +214,7 @@ class CookieCollection extends BaseObject implements \IteratorAggregate, \ArrayA * @param string $name the cookie name * @return Cookie the cookie with the specified name, null if the named cookie does not exist. */ + #[\ReturnTypeWillChange] public function offsetGet($name) { return $this->get($name); @@ -224,6 +228,7 @@ class CookieCollection extends BaseObject implements \IteratorAggregate, \ArrayA * @param string $name the cookie name * @param Cookie $cookie the cookie to be added */ + #[\ReturnTypeWillChange] public function offsetSet($name, $cookie) { $this->add($cookie); @@ -236,6 +241,7 @@ class CookieCollection extends BaseObject implements \IteratorAggregate, \ArrayA * This is equivalent to [[remove()]]. * @param string $name the cookie name */ + #[\ReturnTypeWillChange] public function offsetUnset($name) { $this->remove($name); diff --git a/framework/web/GroupUrlRule.php b/framework/web/GroupUrlRule.php index 4ce3b19..7ad9965 100644 --- a/framework/web/GroupUrlRule.php +++ b/framework/web/GroupUrlRule.php @@ -77,7 +77,7 @@ class GroupUrlRule extends CompositeUrlRule */ public function init() { - $this->prefix = trim($this->prefix, '/'); + $this->prefix = trim((string)$this->prefix); $this->routePrefix = $this->routePrefix === null ? $this->prefix : trim($this->routePrefix, '/'); parent::init(); } diff --git a/framework/web/HeaderCollection.php b/framework/web/HeaderCollection.php index b7a3324..737e2b5 100644 --- a/framework/web/HeaderCollection.php +++ b/framework/web/HeaderCollection.php @@ -33,6 +33,7 @@ class HeaderCollection extends BaseObject implements \IteratorAggregate, \ArrayA * It will be implicitly called when you use `foreach` to traverse the collection. * @return \ArrayIterator an iterator for traversing the headers in the collection. */ + #[\ReturnTypeWillChange] public function getIterator() { return new \ArrayIterator($this->_headers); @@ -44,6 +45,7 @@ class HeaderCollection extends BaseObject implements \IteratorAggregate, \ArrayA * It will be implicitly called when you use `count($collection)`. * @return int the number of headers in the collection. */ + #[\ReturnTypeWillChange] public function count() { return $this->getCount(); @@ -53,6 +55,7 @@ class HeaderCollection extends BaseObject implements \IteratorAggregate, \ArrayA * Returns the number of headers in the collection. * @return int the number of headers in the collection. */ + #[\ReturnTypeWillChange] public function getCount() { return count($this->_headers); @@ -64,7 +67,7 @@ class HeaderCollection extends BaseObject implements \IteratorAggregate, \ArrayA * @param mixed $default the value to return in case the named header does not exist * @param bool $first whether to only return the first header of the specified name. * If false, all headers of the specified name will be returned. - * @return string|array the named header(s). If `$first` is true, a string will be returned; + * @return string|array|null the named header(s). If `$first` is true, a string will be returned; * If `$first` is false, an array will be returned. */ public function get($name, $default = null, $first = true) @@ -189,6 +192,7 @@ class HeaderCollection extends BaseObject implements \IteratorAggregate, \ArrayA * @param string $name the header name * @return bool whether the named header exists */ + #[\ReturnTypeWillChange] public function offsetExists($name) { return $this->has($name); @@ -202,6 +206,7 @@ class HeaderCollection extends BaseObject implements \IteratorAggregate, \ArrayA * @param string $name the header name * @return string the header value with the specified name, null if the named header does not exist. */ + #[\ReturnTypeWillChange] public function offsetGet($name) { return $this->get($name); @@ -215,6 +220,7 @@ class HeaderCollection extends BaseObject implements \IteratorAggregate, \ArrayA * @param string $name the header name * @param string $value the header value to be added */ + #[\ReturnTypeWillChange] public function offsetSet($name, $value) { $this->set($name, $value); @@ -227,6 +233,7 @@ class HeaderCollection extends BaseObject implements \IteratorAggregate, \ArrayA * This is equivalent to [[remove()]]. * @param string $name the header name */ + #[\ReturnTypeWillChange] public function offsetUnset($name) { $this->remove($name); diff --git a/framework/web/HttpException.php b/framework/web/HttpException.php index f7f6ac5..15ad444 100644 --- a/framework/web/HttpException.php +++ b/framework/web/HttpException.php @@ -45,7 +45,7 @@ class HttpException extends UserException public function __construct($status, $message = null, $code = 0, \Exception $previous = null) { $this->statusCode = $status; - parent::__construct($message, $code, $previous); + parent::__construct((string)$message, $code, $previous); } /** diff --git a/framework/web/Request.php b/framework/web/Request.php index 3d41c9e..a7511be 100644 --- a/framework/web/Request.php +++ b/framework/web/Request.php @@ -564,7 +564,7 @@ class Request extends \yii\base\Request } $rawContentType = $this->getContentType(); - if (($pos = strpos($rawContentType, ';')) !== false) { + if (($pos = strpos((string)$rawContentType, ';')) !== false) { // e.g. text/html; charset=UTF-8 $contentType = substr($rawContentType, 0, $pos); } else { @@ -790,7 +790,7 @@ class Request extends \yii\base\Request public function getHostName() { if ($this->_hostName === null) { - $this->_hostName = parse_url($this->getHostInfo(), PHP_URL_HOST); + $this->_hostName = parse_url((string)$this->getHostInfo(), PHP_URL_HOST); } return $this->_hostName; @@ -1467,7 +1467,7 @@ class Request extends \yii\base\Request * contained in [[getRawBody()]] or, in the case of the HEAD method, the * media type that would have been sent had the request been a GET. * For the MIME-types the user expects in response, see [[acceptableContentTypes]]. - * @return string request content-type. Null is returned if this information is not available. + * @return string request content-type. Empty string is returned if this information is not available. * @link https://tools.ietf.org/html/rfc2616#section-14.17 * HTTP 1.1 header field definitions */ @@ -1478,7 +1478,7 @@ class Request extends \yii\base\Request } //fix bug https://bugs.php.net/bug.php?id=66606 - return $this->headers->get('Content-Type'); + return $this->headers->get('Content-Type') ?: ''; } private $_languages; diff --git a/framework/web/Response.php b/framework/web/Response.php index 4928eaf..eebb0cc 100644 --- a/framework/web/Response.php +++ b/framework/web/Response.php @@ -892,7 +892,7 @@ class Response extends \yii\base\Response if ($checkAjax) { if ($request->getIsAjax()) { - if (in_array($statusCode, [301, 302]) && preg_match('/Trident\/|MSIE[ ]/', $request->userAgent)) { + if (in_array($statusCode, [301, 302]) && preg_match('/Trident\/|MSIE[ ]/', (string)$request->userAgent)) { $statusCode = 200; } if ($request->getIsPjax()) { diff --git a/framework/web/Session.php b/framework/web/Session.php index e121ea1..118a7e8 100644 --- a/framework/web/Session.php +++ b/framework/web/Session.php @@ -660,6 +660,7 @@ class Session extends Component implements \IteratorAggregate, \ArrayAccess, \Co * This method is required by the interface [[\IteratorAggregate]]. * @return SessionIterator an iterator for traversing the session variables. */ + #[\ReturnTypeWillChange] public function getIterator() { $this->open(); @@ -681,6 +682,7 @@ class Session extends Component implements \IteratorAggregate, \ArrayAccess, \Co * This method is required by [[\Countable]] interface. * @return int number of items in the session. */ + #[\ReturnTypeWillChange] public function count() { return $this->getCount(); @@ -962,6 +964,7 @@ class Session extends Component implements \IteratorAggregate, \ArrayAccess, \Co * @param int|string $offset the offset to check on * @return bool */ + #[\ReturnTypeWillChange] public function offsetExists($offset) { $this->open(); @@ -974,6 +977,7 @@ class Session extends Component implements \IteratorAggregate, \ArrayAccess, \Co * @param int|string $offset the offset to retrieve element. * @return mixed the element at the offset, null if no element is found at the offset */ + #[\ReturnTypeWillChange] public function offsetGet($offset) { $this->open(); @@ -986,6 +990,7 @@ class Session extends Component implements \IteratorAggregate, \ArrayAccess, \Co * @param int|string $offset the offset to set element * @param mixed $item the element value */ + #[\ReturnTypeWillChange] public function offsetSet($offset, $item) { $this->open(); @@ -996,6 +1001,7 @@ class Session extends Component implements \IteratorAggregate, \ArrayAccess, \Co * This method is required by the interface [[\ArrayAccess]]. * @param int|string $offset the offset to unset element */ + #[\ReturnTypeWillChange] public function offsetUnset($offset) { $this->open(); diff --git a/framework/web/UrlNormalizerRedirectException.php b/framework/web/UrlNormalizerRedirectException.php index 88147cf..ed33f9f 100644 --- a/framework/web/UrlNormalizerRedirectException.php +++ b/framework/web/UrlNormalizerRedirectException.php @@ -47,6 +47,6 @@ class UrlNormalizerRedirectException extends \yii\base\Exception $this->url = $url; $this->scheme = $scheme; $this->statusCode = $statusCode; - parent::__construct($message, $code, $previous); + parent::__construct((string)$message, $code, $previous); } } diff --git a/framework/web/UrlRule.php b/framework/web/UrlRule.php index f5c96e8..673c2d6 100644 --- a/framework/web/UrlRule.php +++ b/framework/web/UrlRule.php @@ -79,7 +79,7 @@ class UrlRule extends BaseObject implements UrlRuleInterface */ public $pattern; /** - * @var string the pattern used to parse and create the host info part of a URL (e.g. `http://example.com`). + * @var string|null the pattern used to parse and create the host info part of a URL (e.g. `http://example.com`). * @see pattern */ public $host; @@ -336,7 +336,7 @@ class UrlRule extends BaseObject implements UrlRuleInterface $this->pattern = '#^' . trim(strtr($this->_template, $tr), '/') . '$#u'; // if host starts with relative scheme, then insert pattern to match any - if (strncmp($this->host, '//', 2) === 0) { + if ($this->host !== null && strncmp($this->host, '//', 2) === 0) { $this->pattern = substr_replace($this->pattern, '[\w]+://', 2, 0); } diff --git a/tests/data/base/ArrayAccessObject.php b/tests/data/base/ArrayAccessObject.php index bf62ef2..1fe0b34 100644 --- a/tests/data/base/ArrayAccessObject.php +++ b/tests/data/base/ArrayAccessObject.php @@ -29,6 +29,7 @@ class ArrayAccessObject extends TraversableObject implements \ArrayAccess * The return value will be casted to boolean if non-boolean was returned. * @since 2.0.14.1 */ + #[\ReturnTypeWillChange] public function offsetExists($offset) { return isset($this->data[$offset]); @@ -44,6 +45,7 @@ class ArrayAccessObject extends TraversableObject implements \ArrayAccess * @return mixed Can return all value types. * @since 2.0.14.1 */ + #[\ReturnTypeWillChange] public function offsetGet($offset) { return $this->data[$offset]; @@ -62,6 +64,7 @@ class ArrayAccessObject extends TraversableObject implements \ArrayAccess * @return void * @since 2.0.14.1 */ + #[\ReturnTypeWillChange] public function offsetSet($offset, $value) { $this->data[$offset] = $value; @@ -77,6 +80,7 @@ class ArrayAccessObject extends TraversableObject implements \ArrayAccess * @return void * @since 2.0.14.1 */ + #[\ReturnTypeWillChange] public function offsetUnset($offset) { unset($this->data[$offset]); diff --git a/tests/data/base/TraversableObject.php b/tests/data/base/TraversableObject.php index c8686b1..037fe73 100644 --- a/tests/data/base/TraversableObject.php +++ b/tests/data/base/TraversableObject.php @@ -28,6 +28,7 @@ class TraversableObject implements \Iterator, \Countable * @throws \Exception * @since 5.1.0 */ + #[\ReturnTypeWillChange] public function count() { throw new \Exception('Count called on object that should only be traversed.'); @@ -36,6 +37,7 @@ class TraversableObject implements \Iterator, \Countable /** * {@inheritdoc} */ + #[\ReturnTypeWillChange] public function current() { return $this->data[$this->position]; @@ -44,6 +46,7 @@ class TraversableObject implements \Iterator, \Countable /** * {@inheritdoc} */ + #[\ReturnTypeWillChange] public function next() { $this->position++; @@ -52,6 +55,7 @@ class TraversableObject implements \Iterator, \Countable /** * {@inheritdoc} */ + #[\ReturnTypeWillChange] public function key() { return $this->position; @@ -60,6 +64,7 @@ class TraversableObject implements \Iterator, \Countable /** * {@inheritdoc} */ + #[\ReturnTypeWillChange] public function valid() { return array_key_exists($this->position, $this->data); @@ -68,6 +73,7 @@ class TraversableObject implements \Iterator, \Countable /** * {@inheritdoc} */ + #[\ReturnTypeWillChange] public function rewind() { $this->position = 0; diff --git a/tests/framework/base/SecurityTest.php b/tests/framework/base/SecurityTest.php index 215999c..70b958c 100644 --- a/tests/framework/base/SecurityTest.php +++ b/tests/framework/base/SecurityTest.php @@ -1046,7 +1046,12 @@ TEXT; */ public function testHkdf($hash, $ikm, $salt, $info, $l, $prk, $okm) { - $dk = $this->security->hkdf($hash, hex2bin($ikm), hex2bin($salt), hex2bin($info), $l); + $dk = $this->security->hkdf( + (string)$hash, + hex2bin((string)$ikm), + hex2bin((string)$salt), + hex2bin((string)$info), + $l); $this->assertEquals($okm, bin2hex($dk)); } diff --git a/tests/framework/caching/MemCachedTest.php b/tests/framework/caching/MemCachedTest.php index 78f6678..c71a019 100644 --- a/tests/framework/caching/MemCachedTest.php +++ b/tests/framework/caching/MemCachedTest.php @@ -27,6 +27,12 @@ class MemCachedTest extends CacheTestCase $this->markTestSkipped('memcached not installed. Skipping.'); } + if (PHP_VERSION_ID >= 80100 && version_compare(phpversion('memcached'), '3.1.5', '<=')) { + $php_version = phpversion(); + $memcached_version = phpversion('memcached'); + $this->markTestSkipped("memcached version $memcached_version is not ready for PHP $php_version. Skipping."); + } + // check whether memcached is running and skip tests if not. if (!@stream_socket_client('127.0.0.1:11211', $errorNumber, $errorDescription, 0.5)) { $this->markTestSkipped('No memcached server running at ' . '127.0.0.1:11211' . ' : ' . $errorNumber . ' - ' . $errorDescription); diff --git a/tests/framework/filters/auth/BasicAuthTest.php b/tests/framework/filters/auth/BasicAuthTest.php index f5d5524..498f145 100644 --- a/tests/framework/filters/auth/BasicAuthTest.php +++ b/tests/framework/filters/auth/BasicAuthTest.php @@ -78,7 +78,7 @@ class BasicAuthTest extends AuthTest $filter = [ 'class' => HttpBasicAuth::className(), 'auth' => function ($username, $password) { - if (preg_match('/\d$/', $username)) { + if (preg_match('/\d$/', (string)$username)) { return UserIdentity::findIdentity($username); } diff --git a/tests/framework/helpers/ArrayHelperTest.php b/tests/framework/helpers/ArrayHelperTest.php index 614d074..11f6ead 100644 --- a/tests/framework/helpers/ArrayHelperTest.php +++ b/tests/framework/helpers/ArrayHelperTest.php @@ -1477,6 +1477,7 @@ class ArrayAccessibleObject implements ArrayAccess $this->container = $container; } + #[\ReturnTypeWillChange] public function offsetSet($offset, $value) { if (is_null($offset)) { @@ -1486,16 +1487,19 @@ class ArrayAccessibleObject implements ArrayAccess } } + #[\ReturnTypeWillChange] public function offsetExists($offset) { return array_key_exists($offset, $this->container); } + #[\ReturnTypeWillChange] public function offsetUnset($offset) { unset($this->container[$offset]); } + #[\ReturnTypeWillChange] public function offsetGet($offset) { return $this->offsetExists($offset) ? $this->container[$offset] : null; @@ -1519,26 +1523,31 @@ class TraversableArrayAccessibleObject extends ArrayAccessibleObject implements return array_key_exists($keyIndex, $keys) ? $keys[$keyIndex] : false; } + #[\ReturnTypeWillChange] public function rewind() { $this->position = 0; } + #[\ReturnTypeWillChange] public function current() { return $this->offsetGet($this->getContainerKey($this->position)); } + #[\ReturnTypeWillChange] public function key() { return $this->getContainerKey($this->position); } + #[\ReturnTypeWillChange] public function next() { ++$this->position; } + #[\ReturnTypeWillChange] public function valid() { $key = $this->getContainerKey($this->position); diff --git a/tests/framework/models/JsonModel.php b/tests/framework/models/JsonModel.php index f30dfce..89c43ef 100644 --- a/tests/framework/models/JsonModel.php +++ b/tests/framework/models/JsonModel.php @@ -24,6 +24,7 @@ class JsonModel extends DynamicModel implements \JsonSerializable /** * @return array */ + #[\ReturnTypeWillChange] public function jsonSerialize() { return $this->data; diff --git a/tests/framework/rest/SerializerTest.php b/tests/framework/rest/SerializerTest.php index 6fd7097..b88c09c 100644 --- a/tests/framework/rest/SerializerTest.php +++ b/tests/framework/rest/SerializerTest.php @@ -540,6 +540,7 @@ class TestModel3 extends Model implements \JsonSerializable return static::$extraFields; } + #[\ReturnTypeWillChange] public function jsonSerialize() { return $this->getAttributes(); @@ -550,6 +551,7 @@ class TestModel4 implements \JsonSerializable public $field5 = 'test5'; public $field6 = 'test6'; + #[\ReturnTypeWillChange] public function jsonSerialize() { return [ diff --git a/tests/framework/web/ControllerTest.php b/tests/framework/web/ControllerTest.php index 2d9b92a..4280a7b 100644 --- a/tests/framework/web/ControllerTest.php +++ b/tests/framework/web/ControllerTest.php @@ -80,7 +80,6 @@ class ControllerTest extends TestCase ], ], ])); - $this->mockWebApplication(['controller' => $this->controller]); $injectionAction = new InlineAction('injection', $this->controller, 'actionNullableInjection'); $params = []; @@ -195,7 +194,6 @@ class ControllerTest extends TestCase ], ], ])); - $this->mockWebApplication(['controller' => $this->controller]); $injectionAction = new InlineAction('injection', $this->controller, 'actionInjection'); $params = ['between' => 'test', 'after' => 'another', 'before' => 'test'];