如何在PHP CLI中运行含cURL逻辑的代码?运行时出现数据库相关报错
问题原因分析
你遇到的报错由两类问题共同导致:
1. 数据库连接失败
你在浏览器访问这个脚本的时候不会出现连接错误,是因为Web请求是由XAMPP虚拟机内的Apache服务处理的,运行的PHP进程在虚拟机内部,可以直接访问虚拟机内的3306端口的MySQL服务。但CLI模式下你是在物理机终端执行命令,调用的是物理机安装的PHP,默认连接物理机的3306端口,该端口没有运行MySQL服务,所以出现Connection refused错误。
连接失败后$conn变量没有被初始化,所以后续调用$conn->prepare()会直接报变量未定义、调用null成员方法的错误。
2. 代码逻辑错误
你的index.php存在两处明显的逻辑问题:
- 重复调用prepare方法,第二次调用时传入的
$query变量根本没有定义 - 数据清洗、参数绑定的代码写在了遍历数据的循环外,此时
$county等变量还未赋值,逻辑完全错误
修复步骤
第一步:修复数据库连接问题
二选一即可:
- 方案1:直接在XAMPP虚拟机的终端中执行
php index.php命令,不要在物理机终端执行,就能直接访问虚拟机内的MySQL服务 - 方案2:查询Bitnami XAMPP映射到物理机的MySQL端口(默认一般为3307,可在XAMPP控制面板的端口映射配置中查看),修改
Database.php中的连接代码,指定映射后的端口:
// 假设映射到物理机的端口为3307 $conn = new PDO("mysql:host=$servername;port=3307;dbname=api-call", $username, $password);
第二步:修复index.php代码逻辑
修改后的完整代码如下:
<?php include_once './config/Database.php'; // 连接失败直接终止程序 if (!isset($conn)) { die("数据库连接失败,终止执行"); } $url = "http://exampledomain.com/api/properties"; $ch = curl_init($url); $headers = array( 'Content-type: application/json', 'API_KEY: 2S7rhsaq9X1cnfkMCPHX64YsWYyfe1he', ); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); $resp = curl_exec($ch); if ($e = curl_error($ch)) { echo $e; curl_close($ch); die(); } $decoded = json_decode($resp, true); // 校验接口返回格式 if (!isset($decoded['data']) || !is_array($decoded['data'])) { die("接口返回数据格式异常"); } // 仅执行一次预处理 $stmt = $conn->prepare("INSERT INTO details (county, country, town, description, type) VALUES (:county, :country, :town, :description, :type)"); foreach ($decoded["data"] as $decode) { // 拿到单条数据后再做清洗和绑定 $county = htmlspecialchars(strip_tags($decode['county'])); $country = htmlspecialchars(strip_tags($decode['country'])); $town = htmlspecialchars(strip_tags($decode['town'])); $description = htmlspecialchars(strip_tags($decode['description'])); $type = htmlspecialchars(strip_tags($decode['type'])); $stmt->bindParam(':county', $county); $stmt->bindParam(':country', $country); $stmt->bindParam(':town', $town); $stmt->bindParam(':description', $description); $stmt->bindParam(':type', $type); $stmt->execute(); } curl_close($ch); echo "所有数据插入完成";
内容的提问来源于stack exchange,提问作者Monsta Jams
相关产品推荐
相关产品推荐

