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
相关产品推荐
相关产品推荐

