diff --git a/bin/functionMetadata_original.php b/bin/functionMetadata_original.php index ed5d223fa8..0ec28970b9 100644 --- a/bin/functionMetadata_original.php +++ b/bin/functionMetadata_original.php @@ -170,6 +170,41 @@ 'DateTimeImmutable::getTimestamp' => ['hasSideEffects' => false], 'DateTimeImmutable::getTimezone' => ['hasSideEffects' => false], + 'Memcached::add' => ['hasSideEffects' => true], + 'Memcached::addByKey' => ['hasSideEffects' => true], + 'Memcached::append' => ['hasSideEffects' => true], + 'Memcached::appendByKey' => ['hasSideEffects' => true], + 'Memcached::cas' => ['hasSideEffects' => true], + 'Memcached::casByKey' => ['hasSideEffects' => true], + 'Memcached::decrement' => ['hasSideEffects' => true], + 'Memcached::decrementByKey' => ['hasSideEffects' => true], + 'Memcached::delete' => ['hasSideEffects' => true], + 'Memcached::deleteByKey' => ['hasSideEffects' => true], + 'Memcached::deleteMulti' => ['hasSideEffects' => true], + 'Memcached::deleteMultiByKey' => ['hasSideEffects' => true], + 'Memcached::fetch' => ['hasSideEffects' => true], + 'Memcached::fetchAll' => ['hasSideEffects' => true], + 'Memcached::flush' => ['hasSideEffects' => true], + 'Memcached::get' => ['hasSideEffects' => true], + 'Memcached::getByKey' => ['hasSideEffects' => true], + 'Memcached::getDelayed' => ['hasSideEffects' => true], + 'Memcached::getDelayedByKey' => ['hasSideEffects' => true], + 'Memcached::getMulti' => ['hasSideEffects' => true], + 'Memcached::getMultiByKey' => ['hasSideEffects' => true], + 'Memcached::getServerByKey' => ['hasSideEffects' => true], + 'Memcached::increment' => ['hasSideEffects' => true], + 'Memcached::incrementByKey' => ['hasSideEffects' => true], + 'Memcached::prepend' => ['hasSideEffects' => true], + 'Memcached::prependByKey' => ['hasSideEffects' => true], + 'Memcached::replace' => ['hasSideEffects' => true], + 'Memcached::replaceByKey' => ['hasSideEffects' => true], + 'Memcached::set' => ['hasSideEffects' => true], + 'Memcached::setByKey' => ['hasSideEffects' => true], + 'Memcached::setMulti' => ['hasSideEffects' => true], + 'Memcached::setMultiByKey' => ['hasSideEffects' => true], + 'Memcached::touch' => ['hasSideEffects' => true], + 'Memcached::touchByKey' => ['hasSideEffects' => true], + // affects isConnected() 'Redis::connect' => ['hasSideEffects' => true], 'Redis::pconnect' => ['hasSideEffects' => true], diff --git a/resources/functionMetadata.php b/resources/functionMetadata.php index b58fa77c7f..f35b10e24f 100644 --- a/resources/functionMetadata.php +++ b/resources/functionMetadata.php @@ -434,6 +434,40 @@ 'JsonIncrementalParser::__construct' => ['hasSideEffects' => false], 'JsonIncrementalParser::get' => ['hasSideEffects' => false], 'JsonIncrementalParser::getError' => ['hasSideEffects' => false], + 'Memcached::add' => ['hasSideEffects' => true], + 'Memcached::addByKey' => ['hasSideEffects' => true], + 'Memcached::append' => ['hasSideEffects' => true], + 'Memcached::appendByKey' => ['hasSideEffects' => true], + 'Memcached::cas' => ['hasSideEffects' => true], + 'Memcached::casByKey' => ['hasSideEffects' => true], + 'Memcached::decrement' => ['hasSideEffects' => true], + 'Memcached::decrementByKey' => ['hasSideEffects' => true], + 'Memcached::delete' => ['hasSideEffects' => true], + 'Memcached::deleteByKey' => ['hasSideEffects' => true], + 'Memcached::deleteMulti' => ['hasSideEffects' => true], + 'Memcached::deleteMultiByKey' => ['hasSideEffects' => true], + 'Memcached::fetch' => ['hasSideEffects' => true], + 'Memcached::fetchAll' => ['hasSideEffects' => true], + 'Memcached::flush' => ['hasSideEffects' => true], + 'Memcached::get' => ['hasSideEffects' => true], + 'Memcached::getByKey' => ['hasSideEffects' => true], + 'Memcached::getDelayed' => ['hasSideEffects' => true], + 'Memcached::getDelayedByKey' => ['hasSideEffects' => true], + 'Memcached::getMulti' => ['hasSideEffects' => true], + 'Memcached::getMultiByKey' => ['hasSideEffects' => true], + 'Memcached::getServerByKey' => ['hasSideEffects' => true], + 'Memcached::increment' => ['hasSideEffects' => true], + 'Memcached::incrementByKey' => ['hasSideEffects' => true], + 'Memcached::prepend' => ['hasSideEffects' => true], + 'Memcached::prependByKey' => ['hasSideEffects' => true], + 'Memcached::replace' => ['hasSideEffects' => true], + 'Memcached::replaceByKey' => ['hasSideEffects' => true], + 'Memcached::set' => ['hasSideEffects' => true], + 'Memcached::setByKey' => ['hasSideEffects' => true], + 'Memcached::setMulti' => ['hasSideEffects' => true], + 'Memcached::setMultiByKey' => ['hasSideEffects' => true], + 'Memcached::touch' => ['hasSideEffects' => true], + 'Memcached::touchByKey' => ['hasSideEffects' => true], 'MemcachedException::__construct' => ['hasSideEffects' => false], 'MessageFormatter::__construct' => ['hasSideEffects' => false], 'MessageFormatter::format' => ['hasSideEffects' => false], diff --git a/tests/PHPStan/Rules/Comparison/StrictComparisonOfDifferentTypesRuleTest.php b/tests/PHPStan/Rules/Comparison/StrictComparisonOfDifferentTypesRuleTest.php index 75529afc48..6f872591ec 100644 --- a/tests/PHPStan/Rules/Comparison/StrictComparisonOfDifferentTypesRuleTest.php +++ b/tests/PHPStan/Rules/Comparison/StrictComparisonOfDifferentTypesRuleTest.php @@ -1040,4 +1040,9 @@ public function testBug11609(): void ]); } + public function testBug13444(): void + { + $this->analyse([__DIR__ . '/data/bug-13444.php'], []); + } + } diff --git a/tests/PHPStan/Rules/Comparison/data/bug-13444.php b/tests/PHPStan/Rules/Comparison/data/bug-13444.php new file mode 100644 index 0000000000..efc4048b56 --- /dev/null +++ b/tests/PHPStan/Rules/Comparison/data/bug-13444.php @@ -0,0 +1,597 @@ +get('key', null, \Memcached::GET_EXTENDED); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } + + if (!is_array($extendedReturn) || !isset($extendedReturn['value'], $extendedReturn['cas'])) { + return; + } + + $data = $extendedReturn['value']; + $cas = $extendedReturn['cas']; + \assert(is_float($cas)); + + // Do some work on the data.. + $memcached->cas($cas, 'key', $data); + + } while ($memcached->getResultCode() !== \Memcached::RES_SUCCESS); +} + +function checkStoreCasByKey(string $key): void +{ + $memcached = new \Memcached(); + + do { + $extendedReturn = $memcached->get($key, null, \Memcached::GET_EXTENDED); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } + + if (!is_array($extendedReturn) || !isset($extendedReturn['value'], $extendedReturn['cas'])) { + return; + } + + $data = $extendedReturn['value']; + $cas = $extendedReturn['cas']; + \assert(is_float($cas)); + + // Do some work on the data.. + $memcached->casByKey($cas, 'server', $key, $data); + + } while ($memcached->getResultCode() !== \Memcached::RES_SUCCESS); +} + +function checkAddMultiple(): void +{ + $memcached = new \Memcached(); + + $memcached->add('key', 'value'); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } + + $memcached->add('key', 'value'); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } +} + +function checkAddByKeyMultiple(): void +{ + $memcached = new \Memcached(); + + $memcached->addByKey('server', 'key', 'value'); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } + + $memcached->addByKey('server', 'key', 'value'); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } +} + +function checkAppendMultiple(): void +{ + $memcached = new \Memcached(); + + $memcached->append('key', 'value'); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } + + $memcached->append('key', 'value'); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } +} + +function checkAppendByKeyMultiple(): void +{ + $memcached = new \Memcached(); + + $memcached->appendByKey('server', 'key', 'value'); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } + + $memcached->appendByKey('server', 'key', 'value'); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } +} + +function checkDecrementMultiple(): void +{ + $memcached = new \Memcached(); + + $memcached->decrement('key'); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } + + $memcached->decrement('key'); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } +} + +function checkDecrementByKeyMultiple(): void +{ + $memcached = new \Memcached(); + + $memcached->decrementByKey('server', 'key'); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } + + $memcached->decrementByKey('server', 'key'); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } +} + +function checkDeleteMultiple(): void +{ + $memcached = new \Memcached(); + + $memcached->delete('key'); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } + + $memcached->delete('key'); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } +} + +function checkDeleteByKeyMultiple(): void +{ + $memcached = new \Memcached(); + + $memcached->deleteByKey('server', 'key'); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } + + $memcached->deleteByKey('server', 'key'); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } +} + +function checkDeleteMultiMultiple(): void +{ + $memcached = new \Memcached(); + + $memcached->deleteMulti(['key'], 'value'); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } + + $memcached->deleteMulti(['key'], 'value'); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } +} + +function checkDeleteMultiByKeyMultiple(): void +{ + $memcached = new \Memcached(); + + $memcached->deleteMultiByKey('server', ['key'], 'value'); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } + + $memcached->deleteMultiByKey('server', ['key'], 'value'); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } +} + +function checkFetchMultiple(): void +{ + $memcached = new \Memcached(); + + $memcached->fetch(); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } + + $memcached->fetch(); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } +} + +function checkFetchAllMultiple(): void +{ + $memcached = new \Memcached(); + + $memcached->fetchAll(); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } + + $memcached->fetchAll(); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } +} + +function checkFlushMultiple(): void +{ + $memcached = new \Memcached(); + + $memcached->flush(); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } + + $memcached->flush(); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } +} + +function checkGetMultiple(): void +{ + $memcached = new \Memcached(); + + $memcached->get('key'); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } + + $memcached->get('key'); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } +} + +function checkGetByKeyMultiple(): void +{ + $memcached = new \Memcached(); + + $memcached->getByKey('server', 'key'); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } + + $memcached->getByKey('server', 'key'); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } +} + +function checkGetDelayedMultiple(): void +{ + $memcached = new \Memcached(); + + $memcached->getDelayed(['key']); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } + + $memcached->getDelayed(['key']); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } +} + +function checkGetDelayedByKeyMultiple(): void +{ + $memcached = new \Memcached(); + + $memcached->getDelayedByKey('server', ['key']); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } + + $memcached->getDelayedByKey('server', ['key']); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } +} + +function checkGetMultiMultiple(): void +{ + $memcached = new \Memcached(); + + $memcached->getMulti(['key']); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } + + $memcached->getMulti(['key']); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } +} + +function checkGetMultiByKeyMultiple(): void +{ + $memcached = new \Memcached(); + + $memcached->getMultiByKey('server', ['key']); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } + + $memcached->getMultiByKey('server', ['key']); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } +} + +function checkGetServerByKeyMultiple(): void +{ + $memcached = new \Memcached(); + + $memcached->getServerByKey('key'); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } + + $memcached->getServerByKey('key'); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } +} + +function checkIncrementMultiple(): void +{ + $memcached = new \Memcached(); + + $memcached->increment('key'); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } + + $memcached->increment('key'); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } +} + +function checkIncrementByKeyMultiple(): void +{ + $memcached = new \Memcached(); + + $memcached->incrementByKey('server', 'key'); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } + + $memcached->incrementByKey('server', 'key'); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } +} + +function checkPrependMultiple(): void +{ + $memcached = new \Memcached(); + + $memcached->prepend('key'); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } + + $memcached->prepend('key'); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } +} + +function checkPrependByKeyMultiple(): void +{ + $memcached = new \Memcached(); + + $memcached->prependByKey('server', 'key'); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } + + $memcached->prependByKey('server', 'key'); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } +} + +function checkReplaceMultiple(): void +{ + $memcached = new \Memcached(); + + $memcached->replace('key', 'value'); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } + + $memcached->replace('key', 'value'); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } +} + +function checkReplaceByKeyMultiple(): void +{ + $memcached = new \Memcached(); + + $memcached->replaceByKey('server', 'key', 'value'); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } + + $memcached->replaceByKey('server', 'key', 'value'); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } +} + +function checkSetMultiple(): void +{ + $memcached = new \Memcached(); + + $memcached->set('key', 'value'); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } + + $memcached->set('key', 'value'); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } +} + +function checkSetByKeyMultiple(): void +{ + $memcached = new \Memcached(); + + $memcached->setByKey('server', 'key', 'value'); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } + + $memcached->setByKey('server', 'key', 'value'); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } +} + +function checkSetMultiMultiple(): void +{ + $memcached = new \Memcached(); + + $memcached->setMulti(['key'], 'value'); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } + + $memcached->setMulti(['key'], 'value'); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } +} + +function checkSetMultiByKeyMultiple(): void +{ + $memcached = new \Memcached(); + + $memcached->setMultiByKey('server', ['key'], 'value'); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } + + $memcached->setMultiByKey('server', ['key'], 'value'); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } +} + +function checkTouchMultiple(): void +{ + $memcached = new \Memcached(); + + $memcached->touch('key'); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } + + $memcached->touch('key'); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } +} + +function checkTouchByKeyMultiple(): void +{ + $memcached = new \Memcached(); + + $memcached->touchByKey('server', 'key', 0); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } + + $memcached->touchByKey('server', 'key', 0); + + if ($memcached->getResultCode() !== \Memcached::RES_SUCCESS) { + return; + } +}