You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel调用IMDB API后,如何优雅格式化展示响应结果?

如何在Laravel中美观展示IMDB RapidAPI搜索结果

第一步:优化控制器代码

先把返回的JSON字符串解析为PHP数组,同时规范错误处理逻辑,将数据传递给Blade视图:

use Illuminate\Http\Request;

public function search(Request $request) {
    $q = $request->query('movie');
    if (empty($q)) {
        return view('movies.search', ['movies' => [], 'error' => '请输入搜索关键词']);
    }

    $curl = curl_init();
    curl_setopt_array($curl, [
        CURLOPT_URL => "https://imdb8.p.rapidapi.com/auto-complete?q=" . urlencode($q),
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_ENCODING => "",
        CURLOPT_MAXREDIRS => 10,
        CURLOPT_TIMEOUT => 30,
        CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
        CURLOPT_CUSTOMREQUEST => "GET",
        CURLOPT_HTTPHEADER => [
            "X-RapidAPI-Host: imdb8.p.rapidapi.com",
            "X-RapidAPI-Key: xxxxxxxxxxxxxxxxxxxxxxxxx"
        ],
    ]);

    $response = curl_exec($curl);
    $err = curl_error($curl);
    curl_close($curl);

    if ($err) {
        return view('movies.search', ['movies' => [], 'error' => "请求错误: " . $err]);
    }

    $data = json_decode($response, true);
    $movies = $data['d'] ?? [];

    return view('movies.search', ['movies' => $movies, 'searchTerm' => $q]);
}

第二步:创建Blade视图文件

在resources/views/movies/search.blade.php中编写响应式卡片布局的展示模板,自带基础样式:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>电影搜索结果</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
            font-family: Arial, sans-serif;
        }
        .container {
            max-width: 1200px;
            margin: 2rem auto;
            padding: 0 1rem;
        }
        .search-bar {
            margin-bottom: 2rem;
            display: flex;
            gap: 0.5rem;
        }
        .search-bar input {
            flex: 1;
            padding: 0.75rem;
            border: 1px solid #ddd;
            border-radius: 4px;
            font-size: 1rem;
        }
        .search-bar button {
            padding: 0.75rem 1.5rem;
            background: #007bff;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
        }
        .movies-grid {
            display: grid;
            grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
            gap: 1.5rem;
        }
        .movie-card {
            border: 1px solid #eee;
            border-radius: 8px;
            overflow: hidden;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
            transition: transform 0.2s;
        }
        .movie-card:hover {
            transform: translateY(-5px);
        }
        .movie-poster {
            width: 100%;
            height: 420px;
            object-fit: cover;
            background: #f5f5f5;
            display: flex;
            align-items: center;
            justify-content: center;
            color: #999;
        }
        .movie-info {
            padding: 1rem;
        }
        .movie-title {
            font-size: 1.1rem;
            font-weight: bold;
            margin-bottom: 0.5rem;
            color: #333;
        }
        .movie-year {
            color: #666;
            margin-bottom: 0.5rem;
        }
        .movie-cast {
            font-size: 0.9rem;
            color: #555;
            line-height: 1.4;
        }
        .error-message {
            padding: 1rem;
            background: #f8d7da;
            color: #721c24;
            border-radius: 4px;
            margin-bottom: 1rem;
        }
        .no-results {
            text-align: center;
            padding: 2rem;
            color: #666;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="search-bar">
            <input type="text" name="movie" placeholder="输入电影名称搜索..." value="{{ $searchTerm ?? '' }}">
            <button type="submit" onclick="document.querySelector('.search-bar').parentElement.submit()">搜索</button>
        </div>

        @if(isset($error))
            <div class="error-message">{{ $error }}</div>
        @endif

        @if(count($movies) === 0)
            <div class="no-results">没有找到相关电影,请尝试其他关键词</div>
        @else
            <div class="movies-grid">
                @foreach($movies as $movie)
                    <div class="movie-card">
                        @if(isset($movie['i']['imageUrl']))
                            <img src="{{ $movie['i']['imageUrl'] }}" alt="{{ $movie['l'] }}" class="movie-poster">
                        @else
                            <div class="movie-poster">无海报</div>
                        @endif
                        <div class="movie-info">
                            <div class="movie-title">{{ $movie['l'] }}</div>
                            <div class="movie-year">{{ $movie['y'] ?? '未知年份' }}</div>
                            <div class="movie-cast">{{ $movie['s'] ?? '暂无演员信息' }}</div>
                        </div>
                    </div>
                @endforeach
            </div>
        @endif
    </div>
    <form method="GET" action="/search" style="display: none;">
        <input type="text" name="movie" id="search-input">
    </form>
    <script>
        document.querySelector('.search-bar input').addEventListener('keypress', function(e) {
            if (e.key === 'Enter') {
                document.getElementById('search-input').value = this.value;
                document.querySelector('form').submit();
            }
        });
    </script>
</body>
</html>

第三步:路由确认

当前路由配置已经满足需求,无需修改:

Route::get('/search', [HomeController::class,'search']);

这套实现会生成一个响应式的搜索页面,卡片带悬停动效,自动适配不同屏幕,同时处理了无海报、无结果、请求错误等边界情况。

内容的提问来源于stack exchange,提问作者Bashar Dali

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 15:40:28