PHP使用$_SESSION存储谷歌Sheets API的JSON数据跨页复用异常求助
问题原因
- 你在第一页的循环中每次都给同一个
$_SESSION键赋值,单个$_SESSION字符串键只能存储一个值,循环结束后最终只会保留最后一次循环的赋值(你看到的第一行是因为代码里赋值顺序错误,提前调用了未定义变量) - 你没有将整个员工列表的数组存入
$_SESSION,只存了单条数据,自然无法在第二页的循环中匹配对应行的数据 - 两处页面代码都没有调用
session_start(),这是PHP使用$_SESSION的前置要求,必须在页面所有输出之前调用 - 第一页代码存在低级语法错误:变量赋值顺序颠倒、未定义变量直接输出
修复方案
步骤1:修改第一页代码
首先在页面最顶部添加session_start(),拉取完员工列表后直接将完整数组存入$_SESSION,不需要在循环内逐行存单个字段:
<?php // 必须放在所有输出之前 session_start(); define("API_KEY", "XXXXXXXXXXXX"); $url = sprintf('https://sheets.googleapis.com/v4/spreadsheets/1R8cETVG5XT08iCgZjWOJXSw-HmC_MDOXkjZntEVys40/values/RECAP!AF4:AI?key=AIzaSyD6Mrl9C700rrEKutzvmZa2_43KLEd1sQE', API_KEY); $json = json_decode(file_get_contents($url)); $rows = $json->values; // 直接存储完整的员工列表数组 $_SESSION['employe_list'] = $rows; ?> <div class="container mt-4"> <div class="row"> <div class="col-12"> <table class="table table-bordered table-hover"> <thead> <tr> <th class="text-center">Nom</th> <th class="text-center">Prénom</th> <th class="text-center">Zone</th> <th class="text-center">RIB</th> </tr> </thead> <tbody> <?php foreach($rows as $row){ echo '<tr>'; $nom_employe = $row[3]; $prenom_employe = $row[3]; $zone_employe = $row[2]; $calc = (($row[3])+($row[3])); echo "<td class='text-center'>" . $nom_employe . '</td>'; echo "<td class='text-center'>" . $prenom_employe . '</td>'; // 修复未定义变量$zone的问题 echo "<td class='text-center'>" . $zone_employe . '</td>'; echo "<td class='text-center'>" . $calc . '</td>'; echo '</tr>'; }?> </tbody> </table> </div> </div> </div>
步骤2:修改第二页代码
同样在顶部加session_start(),循环时通过索引匹配对应行的员工数据(注意:该方式要求两个工作表的行顺序完全一一对应,如果不匹配需要用员工ID等唯一字段做关联匹配):
<?php // 必须放在所有输出之前 session_start(); define("API_KEY", "XXXXXXXXXXXX"); $url = sprintf('https://sheets.googleapis.com/v4/spreadsheets/13I_NndK33-AgnfqELjDn--6pIBLz10dOmH83_KoLqNg/values/SuiviCA!B5:P?key=AIzaSyD6Mrl9C700rrEKutzvmZa2_43KLEd1sQE', API_KEY); $json = json_decode(file_get_contents($url)); $rows = $json->values; // 提前取出员工列表,为空时给默认值避免报错 $employe_list = $_SESSION['employe_list'] ?? []; ?> <div class="container mt-4"> <div class="row"> <div class="col-12"> <table class="table table-bordered table-hover"> <thead> <tr> <th class="text-center">DATE FACRURE</th> <th class="text-center">NOM DE CLIENT</th> <th class="text-center">N° FACTURE</th> <th class="text-center">N° BL</th> <th class="text-center">SEMAINE N°</th> <th class="text-center">MOIS</th> <th class="text-center">SEMAINE</th> <th class="text-center">MT EN EURO</th> <th class="text-center">MT $</th> <th class="text-center">MT MAD</th> <th class="text-center">N° DUM</th> <th class="text-center">AVIS D'EXPORT</th> <th class="text-center">DATE DE PAIE</th> <th class="text-center">MODE DE PAIMENT</th> <th class="text-center">REMARQUE</th> </tr> </thead> <tbody> <?php // 循环增加索引$index,用于匹配员工列表对应行 foreach($rows as $index => $row){ echo '<tr>'; $date_facture_suivi_ca = $row[0]; $nom_client_suivi_ca = $row[1]; $facture = $row[2]; // 取对应索引的员工数据 $current_employe = $employe_list[$index] ?? []; $prenom_employe = $current_employe[3] ?? ''; $num_bl_suivi_ca = $prenom_employe; $sem_num_suivi_ca = $row[4]; $mois_suivi_ca = $row[5]; $sem_suivi_ca = $row[6]; $mt_euro_suivi_ca = $row[7]; $mt_dollar_suivi_ca = $row[8]; $mt_mad_suivi_ca = $row[9]; $num_dum_suivi_ca = $row[10]; $avis_export_suivi_ca = $row[11]; $date_paie_suivi_ca = $row[12]; $mode_paiment_suivi_ca = $row[13]; $remarque_suivi_ca = $row[14]; echo "<td class='text-center'>" . $date_facture_suivi_ca . '</td>'; echo "<td class='text-center'>" . $nom_client_suivi_ca . '</td>'; echo "<td class='text-center'>" . $facture . '</td>'; echo "<td class='text-center'>" . $num_bl_suivi_ca . '</td>'; echo "<td class='text-center'>" . $sem_num_suivi_ca . '</td>'; echo "<td class='text-center'>" . $mois_suivi_ca . '</td>'; echo "<td class='text-center'>" . $sem_suivi_ca . '</td>'; echo "<td class='text-center'>" . $mt_euro_suivi_ca . '</td>'; echo "<td class='text-center'>" . $mt_dollar_suivi_ca . '</td>'; echo "<td class='text-center'>" . $mt_mad_suivi_ca . '</td>'; echo "<td class='text-center'>" . $num_dum_suivi_ca . '</td>'; echo "<td class='text-center'>" . $avis_export_suivi_ca . '</td>'; echo "<td class='text-center'>" . $date_paie_suivi_ca . '</td>'; echo "<td class='text-center'>" . $mode_paiment_suivi_ca . '</td>'; echo "<td class='text-center'>" . $remarque_suivi_ca . '</td>'; echo '</tr>'; }?> </tbody> </table> </div> </div> </div>
其他可选实现方案
- 如果员工数据更新频率不高,可以将拉取到的员工列表存为本地JSON文件做全局缓存,所有用户共用,不需要重复调用谷歌API,也不需要依赖SESSION,性能更高
- 如果数据更新频繁,也可以在需要用到员工数据的页面单独调用一次员工表的谷歌API,避免SESSION过期、数据不同步的问题
内容的提问来源于stack exchange,提问作者Issam Hadid
相关产品推荐
相关产品推荐

