Есть ли проблема в логи c или ошибка в PhpStorm? - PullRequest
1 голос
/ 23 января 2020

Есть ли лог / 1062 * ошибка / случай, который я не вижу?

Я использую PhpStorm 2017.1 с PHP языковым уровнем 7.1 и CLI Interpreter PHP 7.1.8

Я пробовал следующие случаи:

  1. User с carrinho(DB) и с carrinho_id и без request
  2. User без carrinho(DB) и с и без carrinho_id в request
  3. carrinho_id в request без user
  4. carrinho_id с неправильным 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);

Два возможных варианта

$user Существуют

if(!(true && ($carrinho = $user->getCarrinho()) != null))

2 Два возможных пути

1 - Имеет $carrinho

if(!(true && true)) -> !(true && true) -> !(true) -> false -> skip if and load the $carrinho from the user

2 - не имеет $carrinho

if(!(true && false)) -> !(true && false) -> !(false) -> true -> Go inside the if and define the $carrinho

Код внутри первого if будет всегда есть $carrinho

Проблема заключается в первом if. Откуда я это знаю? Потому что, если я сделаю это, предупреждение сработает.

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

Ответы [ 3 ]

1 голос
/ 23 января 2020

Этот код чрезвычайно трудно читать, потому что вы объединили побочные эффекты (назначения) со сложными условиями, включающими несколько логических операторов. Давайте попробуем записать это в виде набора отдельных операций:

// 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!

Это много логики c для 4 строк кода!

Немного убирая, не делая это как crypti c как оригинал, я думаю, что это эквивалентно:

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

Теперь мы можем видеть то, что, вероятно, предполагалось: строка Carrinho::salvar должна быть резервной для любого другого неопределенного состояния, скорее чем вложенный в других условиях.

Приложив немного усилий, мы можем полностью устранить вложенные условия, предоставив нечто гораздо более читабельное, например:

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

Некоторые из этих условий могут быть не совсем такими, как предполагалось, но разделив их, теперь мы можем намного проще следовать логике c и вносить соответствующие изменения.

1 голос
/ 23 января 2020

Ваш код может иметь проблемы во время выполнения, и PHPStorm говорит об этом. В некоторых случаях у вас не будет объекта $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);
}

и код $carrinho->addProduto($data) не будет выполнен.

Вам необходимо исправить это , Например, вы можете переместить свой код в блок условий

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);
0 голосов
/ 24 января 2020

После некоторых вопросов и исследований я пришел к выводу, что жесткий код никому не помогает, в слезах командной работы и роста проекта. Я решил реализовать код следующим образом:

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

Я не приму этот ответ, потому что я все еще не убежден, что в коде были ошибки, потому что никто не мог их найти. Но я оставлю это здесь, чтобы показать, что жесткий код не помогает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...