AngularJS结合PHP读取数据库报错:TypeError: Cannot read property 'first_name'
咱们先拆解这个错误:TypeError: Cannot read property 'first_name' of undefined 意味着当Angular尝试渲染{{x.first_name}}时,x是未定义的——本质上是你的$scope.names数组要么没被正确赋值,要么初始状态不是数组,导致渲染环节出错。结合你的代码和环境,主要有以下几个问题需要逐一解决:
1. 核心问题:PHP连接SQL Server用错了扩展
你连接的是SQL Server(从主机地址den1.mssql5.gear.host和表前缀dbo.可以明显看出),但你的PHP代码用的是mysqli_*函数——这个扩展只能连接MySQL数据库,完全不支持SQL Server!所以你的查询根本没有成功执行,自然没有返回任何数据,前端的$scope.names一直处于undefined状态,最终触发渲染错误。
修复PHP连接和查询代码
你需要使用sqlsrv扩展(或者PDO_SQLSRV)来连接SQL Server。以下是修正后的select.php代码:
<?php // select.php // 使用sqlsrv扩展连接SQL Server $serverName = "den1.mssql5.gear.host"; $connectionOptions = array( "Database" => "testiranje", "Uid" => "testiranje", "PWD" => "nijebitno@" ); // 建立连接 $conn = sqlsrv_connect($serverName, $connectionOptions); if($conn === false) { die(print_r(sqlsrv_errors(), true)); } $output = array(); $query = "SELECT * FROM dbo.tbl_user"; $result = sqlsrv_query($conn, $query); if($result !== false) { // 只取关联数组,避免返回混合索引/关联格式的数组 while($row = sqlsrv_fetch_array($result, SQLSRV_FETCH_ASSOC)) { $output[] = $row; } // 必须设置正确的JSON响应头,确保Angular能正确解析 header('Content-Type: application/json'); echo json_encode($output); } else { die(print_r(sqlsrv_errors(), true)); } // 释放资源并关闭连接 sqlsrv_free_stmt($result); sqlsrv_close($conn); ?>
注意:确保你的服务器已经安装并启用了
sqlsrv扩展,如果没有的话需要先安装(可参考PHP官方文档的安装指引)。
2. 前端初始化数组,避免异步加载时的渲染错误
由于$http.get是异步操作,页面初始化时$scope.names还没有被赋值,此时ng-repeat会遍历一个undefined的值,直接触发报错。你可以在控制器里先初始化$scope.names为空数组:
app.controller("usercontroller", function($scope, $http){ // 初始化names为空数组,避免初始渲染阶段报错 $scope.names = []; $scope.insertData = function(){ $http.post( "insert.php", {'firstname':$scope.firstname, 'lastname':$scope.lastname} ).then(function(response){ alert(response.data); $scope.firstname = null; $scope.lastname = null; $scope.displayData(); }, function(error){ console.error("插入数据失败:", error); }); } $scope.displayData = function(){ $http.get("select.php") // AngularJS 1.4.x已弃用success/error,推荐用标准then方法处理Promise .then(function(response){ $scope.names = response.data; }, function(error){ // 增加错误处理,方便调试请求问题 console.error("获取数据失败:", error); }); } });
3. 验证PHP接口的输出是否正确
直接在浏览器地址栏访问select.php,检查返回内容:
- 必须是标准的JSON格式,比如:
[{"first_name":"张三","last_name":"李四"},...] - 不能有任何额外输出(比如PHP的警告、错误信息、空格或HTML标签),否则Angular无法正确解析JSON。
如果访问select.php时看到错误信息,根据提示修复即可(比如扩展未安装、用户名密码错误、表名不存在等)。
4. 额外优化:用ng-if避免空数据时的无效渲染
你可以给表格加上ng-if="names.length > 0",这样只有当数据加载完成后才渲染表格,同时添加空状态提示,提升用户体验:
<table class="table table-bordered" ng-if="names.length > 0"> <tr> <th>First Name</th> <th>Last Name</th> </tr> <tr ng-repeat="x in names"> <td>{{x.first_name}}</td> <td>{{x.last_name}}</td> </tr> </table> <!-- 空状态提示 --> <div ng-if="names.length === 0" class="text-center text-muted">暂无用户数据</div>
按照以上步骤逐一排查和修复,应该就能彻底解决你的问题了。
内容的提问来源于stack exchange,提问作者Drason

