Browse Source

Fix #19041: Fix PHP 8.1 issues

tags/2.0.45
Alexander Makarov 3 years ago committed by GitHub
parent
commit
1271bc419f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      .github/workflows/build.yml
  2. 6
      composer.json
  3. 14
      composer.lock
  4. 2
      framework/BaseYii.php
  5. 1
      framework/CHANGELOG.md
  6. 6
      framework/base/ArrayAccessTrait.php
  7. 6
      framework/base/ExitException.php
  8. 5
      framework/base/Model.php
  9. 2
      framework/base/Security.php
  10. 4
      framework/caching/Cache.php
  11. 4
      framework/console/controllers/HelpController.php
  12. 6
      framework/db/ArrayExpression.php
  13. 1
      framework/db/BaseActiveRecord.php
  14. 5
      framework/db/BatchQueryResult.php
  15. 7
      framework/db/Connection.php
  16. 6
      framework/db/DataReader.php
  17. 1
      framework/db/JsonExpression.php
  18. 2
      framework/db/Query.php
  19. 4
      framework/db/SqlToken.php
  20. 2
      framework/db/mysql/Schema.php
  21. 6
      framework/grid/Column.php
  22. 6
      framework/helpers/BaseConsole.php
  23. 7
      framework/helpers/BaseFileHelper.php
  24. 2
      framework/helpers/BaseHtml.php
  25. 12
      framework/helpers/BaseStringHelper.php
  26. 2
      framework/i18n/GettextMoFile.php
  27. 2
      framework/i18n/PhpMessageSource.php
  28. 3
      framework/mail/BaseMailer.php
  29. 4
      framework/rest/UrlRule.php
  30. 4
      framework/validators/FileValidator.php
  31. 1
      framework/validators/FilterValidator.php
  32. 6
      framework/web/CookieCollection.php
  33. 2
      framework/web/GroupUrlRule.php
  34. 9
      framework/web/HeaderCollection.php
  35. 2
      framework/web/HttpException.php
  36. 8
      framework/web/Request.php
  37. 2
      framework/web/Response.php
  38. 6
      framework/web/Session.php
  39. 2
      framework/web/UrlNormalizerRedirectException.php
  40. 4
      framework/web/UrlRule.php
  41. 4
      tests/data/base/ArrayAccessObject.php
  42. 6
      tests/data/base/TraversableObject.php
  43. 7
      tests/framework/base/SecurityTest.php
  44. 6
      tests/framework/caching/MemCachedTest.php
  45. 2
      tests/framework/filters/auth/BasicAuthTest.php
  46. 9
      tests/framework/helpers/ArrayHelperTest.php
  47. 1
      tests/framework/models/JsonModel.php
  48. 2
      tests/framework/rest/SerializerTest.php
  49. 2
      tests/framework/web/ControllerTest.php

2
.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

6
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"
}
}
}

14
composer.lock generated

@ -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",

2
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;
}

1
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

6
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]);

6
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);
}
}
}

5
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;

2
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()');
}

4
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);

4
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';
}

6
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();

1
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);

5
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);

7
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));

6
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;

1
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();

2
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 {

4
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);

2
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']);
}

6
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;
}
/**

6
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, '');

7
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.');
}

2
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);
}
/**

12
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;
}

2
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)) {

2
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) {

3
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';
}
/**

4
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();
}

4
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);
}

1
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);
}
}

6
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);

2
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();
}

9
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);

2
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);
}
/**

8
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;

2
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()) {

6
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();

2
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);
}
}

4
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);
}

4
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]);

6
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;

7
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));
}

6
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);

2
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);
}

9
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);

1
tests/framework/models/JsonModel.php

@ -24,6 +24,7 @@ class JsonModel extends DynamicModel implements \JsonSerializable
/**
* @return array
*/
#[\ReturnTypeWillChange]
public function jsonSerialize()
{
return $this->data;

2
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 [

2
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'];

Loading…
Cancel
Save