Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/289.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何处理laravel中未定义的偏移?_Php_Laravel_Undefined_Offset - Fatal编程技术网

Php 如何处理laravel中未定义的偏移?

Php 如何处理laravel中未定义的偏移?,php,laravel,undefined,offset,Php,Laravel,Undefined,Offset,我在登录后登录页面时遇到此错误: compiled.php行11573中的ErrorException:未定义的偏移量:0(视图: C:\xampp\htdocs\campusguru\resources\views\home.blade.php) 我知道这个错误的原因是我传递给视图的空变量 >>> $a = [1 => App\Models\User::find(1)]; => [ 1 => App\Models\User {#890

我在登录后登录页面时遇到此错误:

compiled.php行11573中的ErrorException:未定义的偏移量:0(视图: C:\xampp\htdocs\campusguru\resources\views\home.blade.php)

我知道这个错误的原因是我传递给视图的空变量

>>> $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"
我已经试过:

if(isset($blog)) { do something }
在刀片视图中显示为:

{{ $blogs[0]->title or '' }}
不管怎样,我都可以处理这个错误。或者有更好的方法吗?

尝试以下方法:

{{ isset($blogs[0]) ? $blogs[0]->title : '' }}
@if(isset($obj->posts))
   @foreach($obj->posts as $post)
      ...
   @endoforeach
@endif
如果您使用foreach获取每个$blog->title,请使用

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

如果您有一个传递到视图的对象,假设您的数据是“posts”,它保存在一个对象中,如下所示: $obj->posts

如果你接着去做一个foreach循环,它会在每一篇文章中迭代并打印出它的参数,就像下面的例子一样,当你真的有文章时,它工作得非常好

@foreach($obj->posts as $post)
   <h1>$post->title</h1>
   <p>$post->content</p>
@endforeach
我进行检查的方式如下:

{{ isset($blogs[0]) ? $blogs[0]->title : '' }}
@if(isset($obj->posts))
   @foreach($obj->posts as $post)
      ...
   @endoforeach
@endif

问题是,
$blogs
实际上是定义的,它的值是
[]
(即空的
数组
),因此这意味着
isset($blogs)
语句将计算为
true
。同样的道理也适用于集合。如果集合为空(即没有元素但已定义)
isset($blogs)
仍将计算为
true
,但访问
$blogs[0]
将导致
未定义的偏移量:0
错误

您可以尝试以下解决方案:

使用
计数

if(count($blogs)) { /* do something */ }
if(!empty($blogs)) { /* do something */ }
如果
$blogs=[]
$blogs=null
函数
count
将返回零,这意味着
$blogs
为空

使用

if(count($blogs)) { /* do something */ }
if(!empty($blogs)) { /* do something */ }
这相当于编写
!isset($var)| |$var==false
如中所述:

如果var存在且具有非空、非零的值,则返回FALSE 价值否则返回TRUE

以下内容被认为是空的:
  • (一个 空字符串)
  • 0
    (0作为整数)
  • 0.0
    (0作为整数) 浮动)
  • “0”
    (0作为字符串)
  • NULL
  • FALSE
  • array()
    (空数组)
    (a)
    已声明变量,但没有值)

    检查集合是否为空

    如果
    $blogs
    集合
    足以使用以下方法检查其是否为空:

    (检查模板中是否设置了
    $blogs
    ,并且其长度是否大于
    0

    {{ isset($blogs[0]->title) ? $blogs[0]->title : '' }}
    
    或者更简洁地说

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

    假设只有当
    $blogs
    通过第一个
    if
    时,控制流才会到达那里。如果问题仍然存在,则问题在代码IMHO中的其他地方。

    您只需使用
    data\u 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: "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"
    >>> 
    
    因此,在这种情况下:

    {{ data_get($blogs[0], 'title', '') }}
    
    data_get()
    将同时作用于数组和对象,返回第二个参数中定义的键或属性(可以是
    laravel.dot.notation.style
    ,也可以只是一个数组),如果对象/数组或键/属性不存在,则第三个参数将是默认返回值,默认值为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使用的是blade
    还是default
    ,它都不会进入三元语句,因为
    $blogs
    上缺少0索引


    按要求编辑2:

    因此,出现
    未定义偏移量:x
    错误的原因是PHP计算代码的顺序

    Blade的
    或default
    在幕后不过是一个三元语句:

    return preg_replace('/^(?=\$)(.+?)(?:\s+or\s+)(.+?)$/si', 'isset($1) ? $1 : $2', $value);
    
    因此,这将使:

    isset($blogs[0]->title) ? $blogs[0]->title : ''
    
    isset()
    将检查对象上的标题是否已设置,但要执行此操作,将要求
    $blogs[0]
    为有效对象。为此,它将尝试从索引0处的
    $blogs
    数组中获取对象。但由于该索引不存在,它将触发异常,并带有
    未定义的偏移量:0

    为了使用Blade的
    或默认值
    ,您首先必须确保定义了
    $blogs[0]
    (最好还要检查它是否是一个对象,否则您将得到“尝试获取非对象错误”属性,请注意,这不应该是视图的责任),之后,您可以像其他任何时候一样使用
    或default

    @if (isset($blogs[0]) && is_object($blogs[0]))
        {{ $blogs[0]->title or '' }}
    @else
        // some other default placeholder
    @endif
    
    使用
    data\u get()
    时,基本上会得到相同的偏移错误,因为索引0仍然不存在

    {{ data_get($blogs[0], 'title', '') }} // Undefined offset: 0
    
    你可以玩脏东西,然后这样做(这不会在任何地方通过任何代码审查,我根本不应该键入它,这只是为了举例说明。)

    无论如何,使用
    data\u get()
    您最终还是会做类似的事情,因为您需要确保
    $blogs[0]
    是您可以使用的:

    @if (isset($blogs[0]))
        {{ data_get($blogs[0], 'title', '') }}
    @else
        // some other default placeholder
    @endif
    
    总之,最好的选择是而不是在您的视图中依赖这样的索引,这根本不是您的视图的责任


    Blade的
    或default
    在单个变量上运行良好,但在处理对象属性时,您只需确保(父)对象存在即可。

    我在控制器中这样做:

     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
    

    从PHP7开始,您可以使用空合并运算符
    检查三元条件:

    @if($posts?? '')
     @foreach($posts as $post)
       <h1>$post->title</h1>
       <p>$post->content</p>
     @endforeach
    @endif
    

    这么说,这个解决方案行得通?如果是的话,我觉得没问题,只是你应该用三个括号({{{和}}}}})来防止解释HTML(XSS缺陷)。@christoptd仅在Laravel4.x,Laravel5ESC中使用
    @if($posts?? '')
     @foreach($posts as $post)
       <h1>$post->title</h1>
       <p>$post->content</p>
     @endforeach
    @endif
    
    {{ $blogs && $blogs[0]->title ? $blogs[0]->title : '' }}