T-file

一歩踏み出す勇気を全力で応援するブログ

【Laravel】コンポーネントとスロットで渡した変数はオブジェクトに変わっている話

こんにちは、webエンジニア歴4年のtakaです。

今回は、Laravelのプロジェクトでコンポーネントとスロットを利用し変数を渡し、if文を利用した時に下記のエラーが出たのでその解決方法を記載していきます。

エラーメッセージ

Object of class Illuminate\Support\HtmlString could not be converted to int

自分の場合はLaravelでしたが、Laravel以外のCakePHPなのでPHPフレームワークでも根本的に問題は同じなので、参考にしてください。

状況

管理画面の実装・コーディングをしています。

やりたいことは、管理画面のサイドバーであるデータがあると「new」という文言をつけるという実装です。
※ミドルウェア使うべき箇所ですが、エラーとは関係ないのでそっとしておいてください。

Resources/views/admin/index.blade.php
コントローラーから渡された$postsをlayoutに送ります。

@extends('admin.layouts.app')

@section('has_posts', count($posts))

@section('content')
・・・

Resources/views/admin/layouts/app.blade.php
index.blade.phpから渡された has_posts をコンポーネントのsidebarに渡します。

@component('admin.components.header')
@endcomponent

@component('admin.components.sidebar')
  @slot('hasPosts')
    @yield('has_posts')
  @endslot
@endcomponent

@yield('content')
・・・

Resources/views/admin/components/sidebar.blade.php
コンポーネントのサイドバーでは、$hasPostsが1以上の場合「new」という文言を付けたいです。

<li>
 <a href="">
  投稿 @if($hasPosts) new @endif
 </a>
</li>


if文がうまく機能しない

$postsが1以上ある場合は、コンポーネントのサイドバーでnewがつきます。
->正しい挙動

#postsがnullの場合も、コンポーネントのサイドバーでnewがつきます。
->正しくない挙動

おかしいなと思い、コンポーネントのサイドバーで$hasPostsをそのまま表示してみました。
Resources/views/admin/components/sidebar.blade.php

<li>
 <a href="">
  投稿 {{ $hasPosts }}
 </a>
</li>

フロントの出力結果

投稿 0

あれ、$hasPostsは0が入っているではないか。

次にif文を少しいじってみました。

<li>
 <a href="">
  投稿 @if($hasPosts == 0) new @endif
 </a>
</li>

そうすると冒頭で記載をした以下のエラーメッセージがでました。

Object of class Illuminate\Support\HtmlString could not be converted to int

なんか$hasPostsはオブジェクトっぽいですね。

今度はdump()で$hasPostsを確認してみます。
Resources/views/admin/components/sidebar.blade.php

<li>
 <a href="">
  投稿 {{ dump($hasPosts) }}
 </a>
</li>

フロントでの表示

Illuminate\Support\HtmlString {#1443 ▼
#html: "0"
}

というわけでHtmlStringオブジェクトに変換されていました。

解決方法

解決方法
HtmlStringオブジェクトはいくつかのメソッドが用意されています。

公式の情報はこちら

用意されたメソッドの中で今回はtoHTML()メソッドを利用し、オブジェクトではなくhtml文字列として出力させます。

<li>
  <a href="">
    投稿 @if($hasPosts->toHtml()) new @endif
  </a>
</li>

tips!

こんな風にも書けるよ

{{ $hasPosts->toHtml() ? 'new' : '' }}

まとめ

今回の記事では、Laravelにおいてコンポーネントとスロットで渡した変数はオブジェクト[HtmlStringオブジェクト]に変わってしまったので、HtmlStringオブジェクトで利用できるtoHTMLメソッドを利用し、文字列に変換しエラーを解決する方法を記載しました。

とりあえず、dump()やdd()などで変数に何が入っているかを確認することが重要ですね。

この記事が参考になれば幸いです。

著書のプロフィールはこちら