Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

switch on gettype($var), then caseing on result, doesn't appear to take result into account #6901

Closed
pauljherring opened this issue Mar 24, 2022 · 4 comments · Fixed by phpstan/phpstan-src#1611

Comments

@pauljherring
Copy link

Bug report

  • php 8.1.3
  • phpstan 1.4.10

1. Did a quick search for gettype switch in issues - nothing stood out as similar (#1330 came close, but that was from 2018, and doesn't appear to be this 'use' case)
2. I'm aware that what I'm doing here is possibly a gross abuse of gettype(), and should probably be doing (and in fact probably will do) something saner here. Nevertheless - reporting this in case I'm not misunderstanding something more fundamental

I'm using a switch gettype($var) and caseing on the return values; the behavior changing depending on what was passed in.

At the point where gettype() has determined (in this example) integer and in that case clause, I'd presume the same behaviour after - say - branching on an is_int() on the same variable. However it seems the result of gettype() here isn't 'remembered,' or at least considered.

Code snippet that reproduces the problem

https://phpstan.org/r/545f326d-f332-4bd1-a5c4-a635edc47575

<?php declare(strict_types = 1);

/**
* Do-nothing function to be called from foo() below
* @param integer $x
* @return integer
*/
function bar(int $x){
	return (rand()%2 == $x)*2;
}

/**
* @param integer|string|array<string> $y
* @return integer
*/
function foo($y){
	switch (gettype($y)){
		case "integer":
			echo bar($y); // 19 Parameter #1 $x of function bar expects int, array<string>|int|string given.
			break;
		case "string":
			// do something with the string
			break;
		case "array":
			// foreach($y as $k => $v), do different stuff with each $v.
			break;
		default:
			/* - */
	}
	return 0;
}

Output

Line | Error
-- | --
19 | Parameter #1 $x of function bar expects int, array<string>\|int\|string given.

Expected output

No error

@staabm
Copy link
Contributor

staabm commented Mar 30, 2022

Phpstan will understand your code better when you use methods like is_int and friends.

the same is true for IDEs and their type inference

@pauljherring
Copy link
Author

Phpstan will understand your code better when you use methods like is_int and friends.

I don't disagree; did you read my point 2 in the intro, especially the parenthetical?

@ondrejmirtes
Copy link
Member

This is a question of adding support for this to TypeSpecifier similarly to how get_class is already handled there.

@github-actions
Copy link

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Sep 13, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants