Ich erhalte diese Fehlermeldung, wenn ich nach dem Einloggen auf der Seite lande:
ErrorException in compiled.php Zeile 11573: Undefinierter Offset: 0 (Ansicht: C:\xampp\htdocs\campusguru\resources\views\home.blade.php)
Ich weiß, dass die Ursache dieses Fehlers die leere Variable ist, die ich an die Ansicht übergeben habe.
Ich habe schon versucht:
if(isset($blog)) { do something }
und in der Blattsicht als:
{{ $blogs[0]->title or '' }}
Gibt es sowieso ich könnte diesen Fehler behandeln. Oder gibt es einen besseren Weg, dies zu tun?
Das Problem ist, dass $blogs
tatsächlich definiert ist und der Wert []
(d. H. Leer array
) ist. Dies bedeutet, dass die isset($blogs)
-Anweisung zu true
ausgewertet wird. Gleiches gilt für Sammlungen. Wenn eine Auflistung leer ist (d. H. Keine Elemente enthält, aber definiert ist), wird isset($blogs)
weiterhin in true
ausgewertet, der Zugriff auf $blogs[0]
führt jedoch zu einem Undefined offset: 0
-Fehler.
Sie können die folgenden Lösungen ausprobieren:
count
verwenden
if(count($blogs)) { /* do something */ }
wenn $blogs = []
oder $blogs = null
die Funktion count
Null zurückgibt, bedeutet dies, dass $blogs
leer ist.
empty
verwenden
if(!empty($blogs)) { /* do something */ }
Dies ist das Äquivalent zum Schreiben von !isset($var) || $var == false
wie im Handbuch PHP beschrieben - empty :
Kehrt zurück FALSE Wenn var existiert und eine nicht leere, ungleich Null hat Wert. Ansonsten kehrt zurück WAHR.
Die folgenden Dinge gelten als leer:
""
(eine leere Zeichenfolge)0
(0 als ganze Zahl)0.0
(0 als float)"0"
(0 als Zeichenfolge)NULL
FALSE
array()
(ein leeres Array)$var;
(eine Variable wurde deklariert, aber ohne Wert)
Prüfen, ob eine Sammlung leer ist
Wenn $blogs
eine Collection
ist, reicht es aus, um zu überprüfen, ob sie nicht leer ist, und zwar mit `isNotEmpty () method:
@if($blogs->isNotEmpty()) <!-- Do your stuff --> @endif
EDIT
Ich habe vergessen, die Blade-Syntax hinzuzufügen:
@if(count($blogs)) <!-- Do whatever you like --> @endif
oder
@if(!empty($blogs)) <!-- Do whatever you like --> @endif
EDIT 2
Ich füge dieser Antwort mehr Inhalt hinzu, um einige der in den Kommentaren behandelten Probleme zu lösen. Ich denke, dein Problem ist folgendes:
$blogs
ist eine leere Sammlung, also definiert, aber keine Elemente. Aus diesem Grund wird die if(isset($blogs))
-Anweisung zu true
ausgewertet, wobei die erste if
-Bedingung übergeben wird. In Ihrer Blade-Vorlage führen Sie die Überprüfung {{ $blogs[0]->title or '' }}
durch, die absolut nicht gleich<?php isset($blogs[0]->title) ? $blogs[0]->title : '' ?>
ist, wie in den Kommentaren angegeben. Es handelt sich jedoch um einen Ausdruck, der true
oder false
zurückgibt, sodass der Parameter title
niemals ausgegeben wird, selbst wenn $blogs[0]
existiert. Das Problem hierbei ist, dass Sie bei der Überprüfung der Bedingung $blogs[0]->title
tatsächlich auf das Element 0
der $blogs
-Auflistung zugreifen, das die Ausnahme Undefined offset: 0
auslösen wird, da die Auflistung tatsächlich leer ist. Was ich sagte, ist das zusätzlich zum
if(count($blogs)) { /* do something */ }
(das überprüft, ob $blogs
eingestellt ist und die Länge größer als 0
ist) in Ihrer Vorlage, die Sie ausführen sollten
{{ isset($blogs[0]->title) ? $blogs[0]->title : '' }}
oder prägnanter
{{ $blogs[0]->title ?: '' }}
angenommen, der Kontrollfluss wird nur dort ankommen, wenn der $blogs
die erste if
übergeben hat. Wenn das Problem weiterhin besteht, liegt das Problem IMHO an anderer Stelle in Ihrem Code.
versuche Folgendes:
{{ isset($blogs[0]) ? $blogs[0]->title : '' }}
Wenn Sie ein foreach verwenden, um jeden $ blog-> Titel zu erhalten, verwenden Sie
@foreach ($blogs as $blog)
{{ $blog->title }}
@endforeach
Sie können dies einfach mit dem Helper data_get()
lösen.
Zum Beispiel:
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: "[email protected]",
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"
>>>
Also in diesem Fall:
{{ data_get($blogs[0], 'title', '') }}
data_get()
funktioniert sowohl auf Arrays als auch auf Objekten und gibt den im zweiten Parameter definierten Schlüssel oder das angegebene Attribut zurück (dies kann laravel.dot.notation.style
oder nur ein Array sein). Der dritte Parameter ist der Standardwert für die Rückgabe des Objekts/Arrays oder des Schlüssels/Attributs ist nicht vorhanden, der Standardwert ist null.
Bearbeiten:
Ich sah gerade die Bitte um zusätzliche Erklärung, warum der ursprüngliche Code nicht funktionierte.
Der Index 0 ist für das Array/die Sammlung, das an die Ansicht übergeben wird, einfach nicht vorhanden.
>>> $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"
Es ist egal, ob OP das Blade or default
verwendet hat, es kommt nicht einmal zur ternären Anweisung, da der Index 0 für $blogs
fehlt.
Bearbeiten Sie 2 wie gewünscht:
Der Grund, warum Sie den Undefined offset: x
-Fehler erhalten, liegt in der Reihenfolge, in der PHP den Code auswertet.
Blades or default
ist hinter den Kulissen nichts weiter als eine ternäre Aussage:
return preg_replace('/^(?=\$)(.+?)(?:\s+or\s+)(.+?)$/si', 'isset($1) ? $1 : $2', $value);
Das wird also machen:
isset($blogs[0]->title) ? $blogs[0]->title : ''
isset()
prüft, ob der Titel für das Objekt festgelegt ist, aber dazu muss $blogs[0]
ein gültiges Objekt sein. Dazu versucht es, das Objekt aus dem $blogs
-Array am Index 0 abzurufen. Da dieser Index jedoch nicht vorhanden ist, löst er die Exception mit einem Undefined offset: 0
aus.
Damit dies mit Blades or default
funktioniert, müssen Sie zunächst sicherstellen, dass $blogs[0]
definiert ist (und vorzugsweise auch prüfen, ob es ein Objekt ist. Andernfalls erhalten Sie den Versuch, die Eigenschaft eines Nicht-Objektfehlers bitte.) Zu erhalten Beachten Sie, dass dies nicht in der Verantwortung der Ansicht liegen sollte). Danach können Sie den or default
wie gewohnt verwenden.
@if (isset($blogs[0]) && is_object($blogs[0]))
{{ $blogs[0]->title or '' }}
@else
// some other default placeholder
@endif
Grundsätzlich erhalten Sie bei Verwendung von data_get()
den gleichen Offset-Fehler, da Index 0 noch nicht vorhanden ist.
{{ data_get($blogs[0], 'title', '') }} // Undefined offset: 0
Sie könnten schmutzig spielen und dies tun (dies würde keine Codeüberprüfung nirgendwo passieren und ich hätte dies überhaupt nicht eingeben sollen, dies ist nur zur Veranschaulichung)
{{ data_get($blogs, '0.title', '') }} // Will display '' as it will check if key 0 exists
Mit data_get()
würden Sie sowieso trotzdem etwas tun, da Sie sichergehen müssten, dass $blogs[0]
etwas ist, mit dem Sie arbeiten können:
@if (isset($blogs[0]))
{{ data_get($blogs[0], 'title', '') }}
@else
// some other default placeholder
@endif
Unterm Strich wäre die beste Option nicht, um sich in Ihrer Ansicht auf solche Indizes zu verlassen. Dies liegt einfach nicht in der Verantwortung Ihrer Ansicht.
or default
von Blade funktioniert perfekt mit einzelnen Variablen. Beim Umgang mit Objektattributen müssen Sie lediglich sicherstellen, dass das (übergeordnete) Objekt vorhanden ist.
Wenn Sie ein Objekt haben, das an die Ansicht übergeben wird, und sagen Sie, Ihre Daten sind "Posts", die in einem Objekt wie dem folgenden gehalten werden: $ Obj-> posts.
Wenn Sie dann eine foreach-Schleife ausführen, durch die jeder Beitrag durchlaufen würde, und seine Parameter wie im folgenden Beispiel ausgedruckt werden, funktioniert er perfekt, wenn Sie tatsächlich Beiträge haben.
@foreach($obj->posts as $post)
<h1>$post->title</h1>
<p>$post->content</p>
@endforeach
Bevor Sie die Schleife ausführen, sollten Sie überprüfen, ob das Attribut mit Werten festgelegt wurde. Sie können dazu isset () verwenden, und da es sich um eine spezielle Form handelt, kann es als isset ($ obj-> posts) oder isset ($ obj-> posts [0]) verwendet werden. Der Unterschied besteht darin, dass der letztere nur überprüft, ob der Array-Schlüssel einen Wert hat. Wenn Ihr Indexschlüssel nicht 0 ist, wird der Wert false zurückgegeben. Zum Beispiel haben Sie:
$foo = ['first' => somevalue1, 'second' => somevalue2];
isset($foo[0]); //returns false
isset($foo['first']); //returns true
isset($foo); //returns true
Die Art, wie ich den Check machen würde, ist folgende:
@if(isset($obj->posts))
@foreach($obj->posts as $post)
...
@endoforeach
@endif
Ich mache diesen Weg im Controller:
if (empty($allFares) || count($allFares)==0){
return back()->withError('No Fare Found For The City!');
}
ODER in der Klinge:
@if (!empty($allFares) || count($allFares)>0)
@foreach(allFares as $key=>$value)
@endforeach
@endif