web-dev-qa-db-ja.com

laravelで未定義オフセットを処理する方法は?

ログイン後にページにアクセスすると、このエラーが発生します。

Compile.php行11573のErrorException:未定義のオフセット:0(表示:C:\ xampp\htdocs\campusguru\resources\views\home.blade.php)

このエラーの原因は、ビューに渡した空の変数であることを知っています。

私はすでに試しました:

if(isset($blog)) { do something }

ブレードビューでは次のようになります。

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

とにかく私はこのエラーを処理できましたか?またはそれを行うより良い方法はありますか?

15
vs_lala

以下を試してください:

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

Foreachを使用してすべての$ blog-> titleを取得する場合

@foreach ($blogs as $blog)
  {{ $blog->title }}
@endforeach
8
iisurge

問題は_$blogs_が実際に定義され、その値が_[]_(つまり空のarray)であるため、isset($blogs)ステートメントがtrueに評価されることを意味します。コレクションにも同じことが当てはまります。コレクションが空の場合(つまり、要素はないが定義されている場合)isset($blogs)は引き続きtrueに評価されますが、_$blogs[0]_にアクセスすると_Undefined offset: 0_エラーが発生します。

次の解決策を試すことができます。

countを使用

_if(count($blogs)) { /* do something */ }
_

_$blogs = []_または_$blogs = null_の場合、関数countはゼロを返すため、_$blogs_は空です。

emptyを使用

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

これは、 PHP Manual-empty で説明されている!isset($var) || $var == falseと書くのと同等です。

戻り値 FALSE varが存在し、空でもゼロでもない値がある場合。それ以外の場合は戻ります TRUE

次のものは空と見なされます。

  • _""_(空の文字列)
  • _0_(整数として0)
  • _0.0_(フロートとして0)
  • _"0"_(文字列として0)
  • NULL
  • FALSE
  • array()(空の配列)
  • _$var;_(宣言された変数、ただし値なし)

コレクションが空かどうかを確認する

_$blogs_がCollectionである場合、 `isNotEmpty() メソッドを使用して空でないかどうかを確認するには十分です:

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

[〜#〜] edit [〜#〜]

ブレードの構文を追加するのを忘れました:

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

または

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

編集2

コメントに示されている問題のいくつかに対処するために、この回答にさらにコンテンツを追加しています。あなたの問題は次のように思う:

_$blogs_は空のコレクションなので、定義されていますが、要素はありません。このため、if(isset($blogs))ステートメントはtrueに評価され、最初のif条件を渡します。ブレードテンプレートで、コメントで指摘されているように、絶対に等しくない<?php isset($blogs[0]->title) ? $blogs[0]->title : '' ?>であるチェック_{{ $blogs[0]->title or '' }}_を行っていますが、それはtrueを返す式ですまたはfalse。したがって、_$blogs[0]_が存在する場合でも、titleパラメーターは出力されません。ここでの問題は、条件_$blogs[0]->title_をチェックするとき、コレクションが実際に空であるため、例外_0_をトリガーする_$blogs_コレクションの要素_Undefined offset: 0_に実際にアクセスしていることです。私が言っていたことは、それに加えて

_if(count($blogs)) { /* do something */ }
_

(_$blogs_が設定されていること、およびその長さが_0_より大きいことを確認します)

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

またはより簡潔に

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

_$blogs_が最初のifを渡した場合にのみ制御フローがそこに到着すると想定しています。それでも問題が解決しない場合は、コードのどこかに問題があります。

8
Desh901

data_get()ヘルパーでこれを簡単に解決できます。

例えば:

_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"
>>> 
_

したがって、この場合:

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

data_get()は配列とオブジェクトの両方で機能し、2番目のパラメーター(これは_laravel.dot.notation.style_、または単なる配列)で定義されたキーまたは属性を返し、3番目のパラメーターはデフォルトの戻り値になりますオブジェクト/配列またはキー/属性が存在しない場合、デフォルトはnullです。


編集:

元のコードが機能しなかった理由に関する追加説明のリクエストを見たところです。

インデックス0は、単にビューに渡される配列/コレクションに存在しません。

_>>> $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"
_

OPがブレード_or default_を使用したかどうかは関係ありません。_$blogs_の0インデックスが欠落しているため、3項ステートメントにはなりません。


要求に応じて2を編集します。

したがって、_Undefined offset: x_エラーが発生する理由は、PHPがコードを評価する順序のためです。

Bladeの_or default_は、3つのステートメントにすぎません。

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

したがって、これは次のようになります:

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

isset()は、オブジェクトのタイトルが設定されているかどうかを確認しますが、設定するには、_$blogs[0]_が有効なオブジェクトである必要があります。そのためには、インデックス0の_$blogs_配列からオブジェクトを取得しようとします。ただし、このインデックスが存在しないため、_Undefined offset: 0_で例外をトリガーします。

これをBladeの_or default_で機能させるには、最初に_$blogs[0]_が定義されていることを確認する必要があります(また、できればそれがオブジェクトであることを確認する必要があります。そうでない場合は、non -オブジェクトエラー、これはビューの責任ではないことに注意してください)、その後_or default_を使用できるようになります他の時と同じように。

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

インデックス0がまだ存在しないため、基本的にdata_get()を使用すると同じオフセットエラーが発生します。

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

あなたは汚れて遊ぶことができます(これはどこにもコードレビューを渡さず、これをまったく入力するべきではありません、これは単に説明するためです

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

とにかく、data_get()を使用すると、_$blogs[0]_を使用できることを確認する必要があるため、やはりこのようなことを行うことになります。

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

結論として、最適なオプションは、ビューでこのようなインデックスに依存するnotです。これは単にビューの責任ではありません。

Bladeの_or default_は単一の変数で完全に機能しますが、オブジェクトの属性を扱う場合は、その際に(親)オブジェクトが存在することを確認する必要があります。

3
Robert

私はコントローラーでこのようにしています:

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

またはブレード内:

   @if (!empty($allFares) || count($allFares)>0)
               @foreach(allFares as $key=>$value)

                @endforeach
   @endif
1
John

ビューに渡されるオブジェクトがあり、データが「ポスト」であり、このオブジェクトが$ obj-> postsのように保持されているとします。

その後、foreachループを実行してすべての投稿を繰り返し処理し、下の例のようにそのパラメーターを出力すると、実際に投稿があるときに完全に機能します。

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

ループを実行する前に、属性に値が設定されているかどうかを確認する必要があります。これにはisset()を使用できます。これは特殊な形式であるため、isset($ obj-> posts)またはisset($ obj-> posts [0])として使用できます。違いは、後者は配列キーに値があるかどうかのみをチェックするため、インデックスキーが0以外の場合はfalseを返すことです。たとえば、あなたが持っている:

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

私がチェックする方法は次のとおりです。

@if(isset($obj->posts))
   @foreach($obj->posts as $post)
      ...
   @endoforeach
@endif
1
Nino Korent