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

求助:PHP getenv无法读取.env变量及AJAX GET请求传值失败

天气网站API密钥与城市参数获取失败问题

开发个人天气网站时,采用PHP后端调用weatherapi.com的API方案:通过AJAX GET请求传递城市名称到PHP文件,同时用getenv读取.env中的API_KEY组合请求URL,再返回结果给前端展示。但目前无法获取.env的API密钥和前端传递的城市值,返回undefined或空字符串,本地用php -S 127.0.0.1:8000测试,期望获取JSON格式的API响应但失败。


相关代码

HTML文件

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <script src="https://kit.fontawesome.com/a076d05399.js" crossorigin="anonymous"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.3/jquery.min.js"></script>
    <link rel="stylesheet" href="./assets/css/style.css">
    <link rel="stylesheet" href="./assets/css/responsive.css">
    <script src="./main.js" defer></script>
    <title>weather site</title>
</head>

<body>
    <div class="weather-app">
        <div class="container">
            <h3 class="brand">the weather</h3>
            <div>
                <h1 class="temp">16&#176;</h1>
                <div class="city-time">
                    <h1 class="name">London</h1>
                    <small>
                        <span class="time">06:10</span>
                        <span class="date">
                            mondey sep 19
                        </span>
                    </small>
                </div>
                <div class="weather">
                    <img src="./assets/img/icon/day/113.png" class="icon" alt="icon" width="50" height="50">
                    <span class="condition">cloudy</span>
                </div>
            </div>
        </div>
        <div class="panel">
            <form action="" id="locationInput">
                <input type="text" placeholder="search location..." class="search">
                <button type="submit" class="submit">
                    <i class="fas fa-search"></i>
                </button>
            </form>
            <ul class="cities">
                <li class="city">New York</li>
                <li class="city">California</li>
                <li class="city">Paris</li>
                <li class="city">Tokyo</li>
            </ul>
            <ul class="details">
                <h4>Weather Details</h4>
                <li>
                    <span>Cloudy</span>
                    <span class="cloud">89%</span>
                </li>
                <li>
                    <span>Humidity</span>
                    <span class="Humidity">64%</span>
                </li>
                <li>
                    <span>Wind</span>
                    <span class="Wind">8Km/h</span>
                </li>
            </ul>
        </div>
    </div>
</body>

</html>

JS文件

//Get every necessary elements from the DOM
const app = document.querySelector('.weather-app');
const temp = document.querySelector('.temp');
const dateOutput = document.querySelector('.date');
const timeOutput = document.querySelector('.time');
const conditionOutput = document.querySelector('.condition');
const nameOutput = document.querySelector('.name');
const icon = document.querySelector('.icon');
const cloudOutput = document.querySelector('.cloud');
const HumidityOutput = document.querySelector('.Humidity');
const windOutput = document.querySelector('.wind');
const form = document.getElementById('locationInput');
const search = document.querySelector('.search');
const btn = document.querySelector('.submit');
const cities = document.querySelectorAll('.city');

//Default city when page loads
let cityInput = "London";

//Add click event to each city in the panel
for (let i = 0; i < cities.length; i++) {
    cities[i].addEventListener('click', (e) => {
        cityInput = e.target.innerHTML;
        // Get data from API
        fetchweatherdata();
        app.style.opacity = "0";
    })
}

//Add submit event to the form
form.addEventListener("submit", (e) => {
    if (search.value.length == 0) {
        alert("please type in a city name")
    } else {
        cityInput = search.value;
        // Get data from API
        //fetchweatherdata();
        search.value = "";
        app.style.opacity = "0";
    }
    e.preventDefault();
})

function dayOfTheWeek(day, month, year) {
    const weekday = [
        "Sunday",
        "Monday",
        "Tuesday",
        "Wednesday",
        "Thursday",
        "Friday",
        "Saturday"
    ];
    return weekday[new Date(`${day}/${month}/${year}`).getDay()];
}

function fetchweatherdata() {
    $.ajax({
        type: "GET",
        url: "./backend.php",
        data: { city: cityInput },
        success: function (response) {
            console.log(response);
        },
        error: function (error) {
            console.log(error);
        }
    });
}

PHP文件

<?php
header('Content-Type: application/json');

require __DIR__ . '/vendor/autoload.php'; // Path to Composer autoloader

$dotenv = Dotenv\Dotenv::createUnsafeImmutable(__DIR__);
$dotenv->load();

$apiKey = getenv('API_KEY');
$city = $_GET['city'];

$url = "https://api.weatherapi.com/v1/current.json?key=".$apiKey."&q=".$city."&aqi=no";

$data = file_get_contents($url);

echo $data;
?>

解决方案

1. 修复.env文件加载问题

  • 确保.env文件和PHP文件在同一目录,内容格式为API_KEY=你的实际密钥,不要加引号、不要留多余空格。
  • 替换Dotenv初始化代码,增加错误捕获,改用$_ENV读取变量(部分环境下getenv无法读取Dotenv注入的变量):
    $dotenv = Dotenv\Dotenv::createImmutable(__DIR__);
    try {
        $dotenv->load();
        $dotenv->required('API_KEY')->notEmpty();
    } catch (Exception $e) {
        echo json_encode(['error' => '环境变量加载失败: ' . $e->getMessage()]);
        exit;
    }
    $apiKey = $_ENV['API_KEY'] ?? '';
    

2. 确保前端城市参数正确传递

  • 取消JS表单提交事件中//fetchweatherdata();的注释,否则提交表单后不会发起AJAX请求。
  • 在PHP中增加参数校验,避免未获取到city时出错:
    $city = $_GET['city'] ?? '';
    if (empty($city)) {
        echo json_encode(['error' => '缺少城市参数']);
        exit;
    }
    

3. 替换file_get_contents为cURL(避免函数禁用)

部分环境下file_get_contents会被禁用,改用cURL发起请求:

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$data = curl_exec($ch);
curl_close($ch);

if (!$data) {
    echo json_encode(['error' => '获取天气数据失败']);
    exit;
}

4. 调试与路径检查

  • 在PHP中临时添加调试输出,确认变量值(上线前删除):
    echo json_encode(['api_key' => $apiKey, 'city' => $city]);
    exit;
    
  • 确认composer require vlucas/phpdotenv已执行,vendor/autoload.php文件存在。
  • 启动本地服务器时确保工作目录是项目根目录,浏览器开发者工具网络面板可查看AJAX请求是否发送到正确路径。

内容的提问来源于stack exchange,提问作者sajed sadeghi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 14:13:09