Comment gérer L'Offset Non défini dans laravel?

j'obtiens cette erreur quand j'atterris sur la page après la connexion:

ErrorException dans compilé.ligne php 11573: décalage Non défini: 0 (voir: C:xampphtdocscampusgururesourcesviewshome.lame.php)

je sais que la cause de cette erreur est la variable vide que j'ai passé à la vue.

j'ai déjà essayé:

if(isset($blog)) { do something }
<!-Et dans la vue de la lame comme:

{{ $blogs[0]->title or '' }}

Est-il de toute façon je pouvais gérer ce erreur. Ou est-il une meilleure façon de le faire?

15
demandé sur Z.Lin 2015-04-12 13:51:47

5 réponses

Le problème est que $blogs est en fait défini, et sa valeur est [] (c'est à dire vide array) donc, cela signifie que isset($blogs) déclaration évaluera true. La même chose est valable pour les collections. Si la collection est vide (c'est à dire n'a pas d'éléments mais il est défini) isset($blogs) va encore évaluer true mais l'accès $blogs[0] causera un Undefined offset: 0 erreur.

Vous pouvez essayer les solutions suivantes:

en utilisant count

if(count($blogs)) { /* do something */ }

si $blogs = [] ou $blogs = null la fonction count sera de retour à zéro, ce qui signifie qu' $blogs est vide.

en utilisant empty

if(!empty($blogs)) { /* do something */ }

C'est l'équivalent de l'écriture !isset($var) || $var == false comme décrit dans la Manuel PHP - vide:

Retourne FALSE si var n'existe et est non vide, non-zéro valeur. Sinon renvoie TRUE.

Les éléments suivants sont considérés comme vides:

  • "" (un chaîne vide)
  • 0 (0 comme un entier)
  • 0.0 (0 en tant que flotteur)
  • "0" (0, comme une chaîne de caractères)
  • NULL
  • FALSE
  • array() (un tableau vide)
  • $var; (a variable déclarée, mais sans valeur)
  • Vérifier si la collection est vide

    Si $blogs est un Collection est suffisant pour vérifier si elle n'est pas vide à l'aide de ' isNotEmpty () méthode:

    @if($blogs->isNotEmpty()) <!-- Do your stuff --> @endif
    

    EDIT

    j'ai oublié d'ajouter la lame de la syntaxe:

    @if(count($blogs)) <!-- Do whatever you like --> @endif
    

    ou

    @if(!empty($blogs)) <!-- Do whatever you like --> @endif
    

    EDIT 2

    j'ajoute plus de contenu à cette réponse afin d'aborder certains des questions dans les commentaires. Je pense que votre problème est le suivant:

    $blogs est une collection vide, donc elle est définie mais elle n'a pas d'éléments. Pour cette raison, le if(isset($blogs)) déclaration évaluera true passage de la première if condition. Dans votre modèle de lame vous faites la vérification {{ $blogs[0]->title or '' }}absolument pas égal à<?php isset($blogs[0]->title) ? $blogs[0]->title : '' ?> comme indiqué dans les commentaires, mais c'est une expression qui va retourner true ou false, donc, il ne sera jamais imprimer title paramètre même si $blogs[0] existe. Le problème ici est que lors de la vérification de la condition $blogs[0]->title vous accédez en fait à l'élément 0$blogs collection qui va déclencher l'exception Undefined offset: 0 parce que la collection est en fait vide. Ce que je disais c'est qu'en plus de l'

    if(count($blogs)) { /* do something */ }
    

    (qui vérifie que $blogs est réglé et que sa longueur est plus grande que 0) dans votre modèle, vous ne devez faire

    {{ isset($blogs[0]->title) ? $blogs[0]->title : '' }}
    

    ou de façon plus concise

    {{ $blogs[0]->title ?: '' }}
    

    en supposant que le flux de contrôle y arrivera seulement si le $blogs passé le premier if. Si le problème persiste, le problème est ailleurs dans votre code IMHO.

    7
    répondu Desh901 2017-08-31 07:57:48

    essayez la procédure suivante:

    {{ isset($blogs[0]) ? $blogs[0]->title : '' }}
    

    si vous utilisez un foreach pour obtenir chaque $ blog - > titre utiliser

    @foreach ($blogs as $blog)
      {{ $blog->title }}
    @endforeach
    
    5
    répondu iisurge 2015-04-12 11:43:24

    vous pouvez simplement résoudre cela avec le data_get() helper.

    Par exemple:

    php artisan tink
    Psy Shell v0.8.11 (PHP 7.0.22-0ubuntu0.16.04.1 — cli) by Justin Hileman
    >>> 
    >>> $a = collect([[], null, App\Models\User::find(1)]);
    => Illuminate\Support\Collection {#887
         all: [
           [],
           null,
           App\Models\User {#896
             id: 1,
             name: "user1",
             email: "user1@thisisdevelopment.nl",
             last_name: "Gabrielle",
             first_name: "Rempel",
             deleted_at: null,
             created_at: "2017-08-12 15:32:01",
             updated_at: "2017-09-05 12:23:54",
           },
         ],
       }
    >>> data_get($a[0], 'name', 'nope');
    => "nope"
    >>> data_get($a[1], 'name', 'nope');
    => "nope"
    >>> data_get($a[2], 'name', 'nope');
    => "user1"
    >>> 
    

    alors dans ce cas:

    {{ data_get($blogs[0], 'title', '') }}
    

    data_get() fonctionnera à la fois sur les tableaux et les objets, retournant la clé ou l'attribut défini dans le second param (cela peut être laravel.dot.notation.style, ou juste un tableau), Le 3ème paramètre sera la valeur de retour par défaut si l'objet / tableau ou la clé / attribut n'existe pas, la valeur par défaut est NULL.


    Edit:

    je viens de voir la demande d'explication supplémentaire sur les raisons pour lesquelles le code original ne fonctionnait pas.

    Index 0 n'existe tout simplement pas sur le tableau/collection qui est passé à la vue.

    >>> $a = [1 => App\Models\User::find(1)];
    => [
         1 => App\Models\User {#890
           id: 1,
           name: "user1",
           // ... etc
         },
       ]
    >>> $a[0]->name ?: 'nope';
    PHP error:  Undefined offset: 0 on line 1
    >>> $a[1]->name ?: 'nope';
    => "user1"
    

    Il n'a pas d'importance si l'OP a utilisé la lame or default, il n'arrive même pas à la déclaration ternaire à cause de l'index 0 manquant sur $blogs.


    Edit 2 as demande:

    Donc la raison pour laquelle vous obtenez l' Undefined offset: x l'erreur est due à L'ordre dans lequel PHP évalue le code.

    Lame or default est derrière les coulisses rien de plus qu'un ternaire déclaration:

    return preg_replace('/^(?=$)(.+?)(?:\s+or\s+)(.+?)$/si', 'isset() ?  : ', $value);
    

    ce qui permettra de faire:

    isset($blogs[0]->title) ? $blogs[0]->title : ''
    

    isset() vérifiera si le titre de l'objet est défini, mais pour ce faire, il faudra $blogs[0] pour être un objet valide. Pour ce faire, il va essayer et obtenir l'objet de l' $blogs array à index 0. Mais comme cet indice n'existe pas, il déclenchera L'Exception avec un Undefined offset: 0.

    pour faire ce travail avec la Lame or default, il faut d'abord s'assurer que $blogs[0] est défini (et de préférence aussi vérifier que c'est un objet, sinon vous obtiendrez la propriété essayer d'obtenir l'erreur non-object, veuillez noter que cela ne devrait pas être de la responsabilité de la vue.), vous pourrez ensuite utiliser le or default comme vous le feriez pour tout d'autres temps.

    @if (isset($blogs[0]) && is_object($blogs[0]))
        {{ $blogs[0]->title or '' }}
    @else
        // some other default placeholder
    @endif
    

    en gros, vous obtiendrez la même erreur de décalage en utilisant data_get(), parce que l'indice 0 n'existe pas encore.

    {{ data_get($blogs[0], 'title', '') }} // Undefined offset: 0
    

    Vous pouvez jouer de sale et de le faire ( cela ne ferait passer aucun examen de code n'importe où et je n'aurais pas du taper ceci du tout, ceci est juste pour illustrer)

    {{ data_get($blogs, '0.title', '') }} // Will display '' as it will check if key 0 exists
    

    en tout cas, avec data_get() vous finiront par faire quelque chose comme cela, vous devez vous assurer d' $blogs[0] est quelque chose que vous peut travailler avec:

    @if (isset($blogs[0]))
        {{ data_get($blogs[0], 'title', '') }}
    @else
        // some other default placeholder
    @endif
    

    au Fond, le meilleur choix serait la de s'appuyer sur des indices comme ce à votre avis, ce n'est tout simplement pas la responsabilité de votre point de vue.

    Lame or default fonctionne parfaitement sur des variables individuelles, mais lorsque vous traitez avec les attributs de l'objet, vous devez vous assurer que l'objet (parent) existe.

    3
    répondu Robert 2017-09-05 21:58:36

    Si vous avez un objet qui est passé à la vue, et disons que vos données sont "posts" qui se déroule à l'intérieur d'un objet comme celui-ci: $obj->posts.

    si vous allez ensuite faire une boucle foreach qui itérerait à chaque poste et imprimerait ses paramètres comme dans l'exemple ci-dessous il fonctionne parfaitement bien quand vous avez réellement des postes.

    @foreach($obj->posts as $post)
       <h1>$post->title</h1>
       <p>$post->content</p>
    @endforeach
    

    Avant de faire la boucle que vous voulez vérifier si l'attribut a été défini avec des valeurs. Vous pouvez utiliser isset () pour cela, et puisque c'est une forme spéciale, il peut être utilisé comme isset($obj->posts) ou isset($obj->messages[0]). La différence est que ce dernier ne vérifiera que si la clé du tableau a une valeur alors si votre clé d'index est autre chose que 0, elle retournera false. Par exemple, vous devez:

    $foo = ['first' => somevalue1, 'second' => somevalue2];
    isset($foo[0]); //returns false
    isset($foo['first']); //returns true
    isset($foo); //returns true
    

    La façon dont je ferais le vérifier est la suivante:

    @if(isset($obj->posts))
       @foreach($obj->posts as $post)
          ...
       @endoforeach
    @endif
    
    1
    répondu Nino Korent 2017-08-29 09:54:15

    je le fais de cette façon dans le contrôleur:

     if (empty($allFares) || count($allFares)==0){
                return back()->withError('No Fare Found For The City!');
            }
    

    OU de la lame:

       @if (!empty($allFares) || count($allFares)>0)
                   @foreach(allFares as $key=>$value)
    
                    @endforeach
       @endif
    
    0
    répondu Fawel 2017-12-02 12:51:57