[英]Is there a logic problem or a bug in PhpStorm?
Is there a logic error/case that I'm not seeing?是否存在我没有看到的逻辑错误/案例?
I'm using PhpStorm 2017.1 with PHP language level 7.1 and CLI Interpreter PHP 7.1.8我正在使用 PHP 语言级别 7.1 和 CLI Interpreter PHP 7.1.8 的 PhpStorm 2017.1
I tried the following cases:我尝试了以下情况:
User
with carrinho(DB)
and with and without carrinho_id
on request
User
与carrinho(DB)
和有和没有carrinho_id
上request
User
without carrinho(DB)
and with and without carrinho_id
on request
User
无需carrinho(DB)
和有和没有carrinho_id
上request
carrinho_id
on request
with no user
carrinho_id
request
,没有user
carrinho_id
with wrong user(not logged)
carrinho_id
user(not logged)
错误user(not logged)
$user = Auth::guard('api')->user();
if(!(isset($user) && ($carrinho = $user->getCarrinho()) != null)){
if(!isset($data['carrinho_id']) || (($carrinho = Carrinho::find($data['carrinho_id'])) == null) || ($carrinho->usuario_id != null))
$carrinho = Carrinho::salvar([]);
if(isset($user))
$carrinho->setUsuario($user->id);
}
if($carrinho->addProduto($data)) //"$carrinho" Variable might have not been defined
return response()->json([
'carrinho_id' => $carrinho->id
]);
return response()->json(['msg' => "O produto já está no seu carrinho"],422);
Two possible cases两种可能的情况
$user
exist $user
存在
if(!(true && ($carrinho = $user->getCarrinho()) != null))
2 two possible path 2 两种可能的路径
1 - Has $carrinho
1 - 有
$carrinho
if(!(true && true)) -> !(true && true) -> !(true) -> false -> skip if and load the $carrinho from the user
2 - doesn't have $carrinho
2 - 没有
$carrinho
if(!(true && false)) -> !(true && false) -> !(false) -> true -> Go inside the if and define the $carrinho
The code inside the first if
will allways have a $carrinho
第一个
if
的代码总是有一个$carrinho
The problem lies on the first if
.问题在于第一个
if
。 How do i know that?我怎么知道? Because if I do this, the warning goes off.
因为如果我这样做,警告就会消失。
if(!(isset($user) && ($carrinho = $user->getCarrinho()) != null)){
if(!isset($data['carrinho_id']) || (($carrinho = Carrinho::find($data['carrinho_id'])) == null) || ($carrinho->usuario_id != null))
$carrinho = Carrinho::salvar([]);
if(isset($user))
$carrinho->setUsuario($user->id);
}else{
$carrinho = Carrinho::salvar([]);
}
Your code may have a problem during execution and PHPStorm says about it.您的代码可能在执行过程中出现问题,PHPStorm 对此进行了说明。 You won't have
$carrinho
object for some cases, for example, if $user
variable exists在某些情况下,您不会有
$carrinho
对象,例如,如果$user
变量存在
if(!(isset($user) && ($carrinho = $user->getCarrinho()) != null)){
if(!isset($data['carrinho_id']) || (($carrinho = Carrinho::find($data['carrinho_id'])) == null) || ($carrinho->usuario_id != null))
$carrinho = Carrinho::salvar([]);
if(isset($user))
$carrinho->setUsuario($user->id);
}
and code $carrinho->addProduto($data)
will fail.并且代码
$carrinho->addProduto($data)
将失败。
You need to fix it.你需要修复它。 For example, you сan move your code into conditions block
例如,您可以将代码移动到条件块中
if(!(isset($user) && ($carrinho = $user->getCarrinho()) != null)){
if(!isset($data['carrinho_id']) || (($carrinho = Carrinho::find($data['carrinho_id'])) == null) || ($carrinho->usuario_id != null)) {
$carrinho = Carrinho::salvar([]);
}
if(isset($user)) {
carrinho->setUsuario($user->id);
}
if($carrinho->addProduto($data)) {
return response()->json([
'carrinho_id' => $carrinho->id
]);
}
}
return response()->json(['msg' => "O produto já está no seu carrinho"],422);
This code is extremely hard to read, because you've combined side effects (assignments) with complex conditions involving multiple boolean operators.这段代码极难阅读,因为您将副作用(赋值)与涉及多个布尔运算符的复杂条件结合在一起。 Let's try to write it out as a set of discrete operations:
让我们试着把它写成一组离散操作:
// First condition to be evaluated is isset($user)
$haveUser = isset($user);
// If that condition is false, the && will lazily skip the next part
if ( $haveUser ) {
// Now we conditionally assign $carrinho ...
$carrinho = $user->getCarrinho();
// ... and test its value
$haveCarrinho = ($carrinho != null);
}
// Having done all that, we combine the two conditions
$haveBoth = $haveUser && $haveCarrinho;
// Now we invert that condition for our if statement
if ( ! $haveBoth ) {
// We know here that $carrinho has either never been set (because $haveUser was false) ...
// ... or it was null (setting $haveCarrinho to false)
// Line 3 - another if statement to unpack
$haveIdInData = isset($data['carrinho_id']);
// If that condition is false, the || will shortcut
if ( ! $haveIdInData ) {
$carrinho = Carrinho::salvar([]);
}
// If we don't short-cut, the rest of line 3 runs
else {
// Try finding it by the ID in $data
$carrinho = Carrinho::find($data['carrinho_id']);
// If it's null, we short-cut at the next ||
if ($carrinho == null) {
$carrinho = Carrinho::salvar([]);
}
else {
// Else we make the next check
if ($carrinho->usuario_id != null) {
$carrinho = Carrinho::salvar([]);
}
}
}
// On to line 4! Reusing our condition from above, since the state of $user won't have changed
if ( $haveUser ) {
// This will give a horrible error if $carrinho is null
$carrinho->setUsuario($user->id);
}
}
// We've reached line 5, and expect $carrinho to be set, but we have no guarantee of that at all!
That's a lot of logic for 4 lines of code!对于 4 行代码来说,这是很多逻辑!
Tidying up a little bit, without making it as cryptic as the original, I think this is equivalent:稍微整理一下,不要让它像原来一样神秘,我认为这是等效的:
$carrinho = null;
if ( isset($user) ) {
// Now we conditionally assign $carrinho ...
$carrinho = $user->getCarrinho();
}
if ( $carrinho == null ) {
if ( isset($data['carrinho_id']) ) {
$carrinho = Carrinho::find($data['carrinho_id']);
if ($carrinho == null || $carrinho->usuario_id != null) {
$carrinho = Carrinho::salvar([]);
}
}
if(isset($user)) {
$carrinho->setUsuario($user->id);
}
}
Now we can see what was probably intended: the Carrinho::salvar
line should be the fallback for any other undefined state, rather than nested inside other conditions.现在我们可以看到可能的意图:
Carrinho::salvar
行应该是任何其他未定义状态的后备,而不是嵌套在其他条件中。
With a bit of effort, we can eliminate nested conditions altogether, giving something much more readable like this:通过一些努力,我们可以完全消除嵌套条件,从而提供更具可读性的内容,如下所示:
// Initialise variables to a known state
$carrinho = null;
$loadedFromUser = false;
// Try on user object
if ( isset($user) ) {
$carrinho = $user->getCarrinho();
$loadedFromUser = ($carrinho != null);
}
// Not found? Try looking up by input data
if ( $carrinho == null && isset($data['carrinho_id']) ) {
$carrinho = Carrinho::find($data['carrinho_id']);
}
// Discard if it already has a user ID, but wasn't loaded from user
if (!$loadedFromUser && $carrinho != null && $carrinho->usuario_id != null) {
$carrinho = null;
}
// Still not found? Create an empty one
if ($carrinho == null) {
$carrinho = Carrinho::salvar([]);
}
// Now we know we have an object some way or another, and can assign a user ID to it
if(isset($user) && !$loadedFromUser) {
$carrinho->setUsuario($user->id);
}
Some of these conditions might not be quite what was intended, but by splitting them out, we can now follow the logic much more easily and make changes as appropriate.其中一些条件可能并不完全符合预期,但通过将它们分开,我们现在可以更轻松地遵循逻辑并进行适当的更改。
After some questioning and some reseach, I came to the conclusion that hard code does not help anyone, in tearms of team work and project growth.经过一些质疑和研究,我得出的结论是,在团队合作和项目增长的情况下,硬编码对任何人都没有帮助。 I decided to implement the code in the following way:
我决定以下列方式实现代码:
$user = Auth::guard('api')->user();
$hasUser = isset($user);
if($hasUser)
$carrinho = $user->getCarrinho();
if(!isset($carrinho)){
if(isset($data['carrinho_id']))
$carrinho = Carrinho::find($data['carrinho_id']);
if(!isset($carrinho) || $carrinho->usuario_id != null)
$carrinho = Carrinho::salvar([]);
if($hasUser)
$carrinho->setUsuario($user->id);
}
if($carrinho->addProduto($data))
return response()->json([
'carrinho_id' => $carrinho->id
]);
return response()->json(['msg' => "O produto já está no seu carrinho"],422);
I will not accept this anwser because I'm still not conviced that the code had errors because no one could find any.我不会接受这个答案,因为我仍然不相信代码有错误,因为没有人能找到任何错误。 But I will leave this here to show that hard code does no help.
但我将把它留在这里以表明硬编码没有帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.