【问题标题】:PHP array_push() doesn't work but array[] does, only without SQL where clausePHP array_push() 不起作用,但 array[] 起作用,只是没有 SQL where 子句
【发布时间】:2016-05-11 14:39:07
【问题描述】:

所以我在使用 SQL 子句和 PHP 命令时遇到了一个非常奇怪的问题。出于某种原因,我的代码在使用命令时工作正常 "SELECT * FROM tableName WHERE columnName=text"; 但是使用时不起作用 "SELECT * FROM tableName"; 我已将 SQL 命令直接放入 MySQL,它会返回结果。如果我内爆行数组,我会得到结果,如果我从使用切换 array_push($result...)$result= [] 正如预期的那样,我得到了 JSON 格式的最后一个条目。我不确定为什么会出现这种行为,我相信这段代码在以前版本的 PHP 或旧版本的 MySQL 中有效。我最近做了一些更新,现在一切都是最新版本。搜索发现那些同时使用 array_push 和 array[] 的人都不起作用,或者该命令不适用于 WHERE 子句,但我有相反的问题。不知道是什么问题,我启用了 PHP 错误报告和 SQL 错误报告,当问题发生时我只是得到 PHP 白屏死机。

<?php
error_reporting(-1);
define('HOST','localhost');
define('USER','dbuser');
define('PASS','dbpassword');
define('DB','dbname');

$eventYear = isset($_GET["year"]) ? $_GET["year"] : '';
$eventYear = addslashes($eventYear);
if (empty($_GET["year"])){
$eventYear = 2016;
}

$con = mysqli_connect(HOST,USER,PASS,DB) or die ("Database Connection Failed");

$sql = "SELECT * FROM tableName";

$res = mysqli_query($con,$sql);

if (!$res) {
printf("Error: %s\n", mysqli_error($con));
exit();
}

$result = array();

while($row = mysqli_fetch_array($res)){
array_push($result,
array('teamNumberLabel'=>'Team Number',
'teamNumber'=>$row["teamNumber"],
'teamEventLabel'=>'Team Event Name',
'teamEvent'=>$row["teamEvent"],
'teamDistrictCodeLabel'=>'District Code: ',
'teamDistrictCode'=>$row["teamDistrictCode"],
'teamCityLabel'=>'City: ',
'teamCity'=>$row["teamCity"],
'teamStateProvLabel'=>'State/Province: ',
'teamStateProv'=>$row["teamStateProv"],
'teamCountryLabel'=>'Country: ',
'teamCountry'=>$row["teamCountry"],
'teamNameFullLabel'=>'Sponsors: ',
'teamNameFull'=>$row["teamNameFull"],
'teamNameShortLabel'=>'Nickname: ',
'teamNameShort'=>$row["teamNameShort"],
'teamRobotNameLabel'=>'Name: ',
'teamRobotName'=>$row["teamName"],
'teamRookieYearLabel'=>'Rookie Year: ',
'teamRookieYear'=>$row["teamRookieYear"],
'teamWebsiteLabel'=>'Website: ',
'teamWebsite'=>$row["teamWebsite"]
));
}
header('Content-Type: application/json');
echo json_encode(array("result" => $result));

mysqli_close($con);

?> 

我有很多其他文件具有类似的代码,但它们都包含 SQL 命令上的 WHERE 子句,因此它们都按预期工作。只是有没有包含 WHERE 子句的情况下没有任何工作的问题。我尝试在表名周围加上引号,但它显示的 SQL 语法不正确,所以不是这样。还阅读了 SQL 命令和 array_push,我似乎无法弄清楚。

更新: 正如 Marshall 所说,我认为现在的问题是不是 UTF-8 格式的数据,这会导致 JSON 编码失败并且不显示任何数据。该表有数百个条目,因此我将在编码之前过滤掉非 UTF-8 字符,看看它是否有效。

更新 2: 发现问题。我有另一个脚本贯穿单个事件的团队列表(这个类似,但返回全年的所有团队),我浏览了列表,直到它与这个类似失败。具有非 UTF-8 字符的加拿大事件是导致脚本失败的原因。蒙特利尔在数据库中显示为蒙特利尔,魁北克显示为魁北克。代码更早的工作只是因为在最初测试代码时此事件不存在,并且 é 是不受支持的字符。这也解释了为什么代码与 WHERE 子句和 array[] 函数一起使用,因为在任何一种情况下它都不会命中格式错误的数据。像我应该的那样正确过滤进来的数据不会导致这种情况,但至少现在我知道原因了,我真的被困在这个问题上,因为代码看起来正确并且 SQL 命令也是正确的。感谢大家的帮助。

更新 3: 好的,这是完整的修复。我将 PHPMyAdmin 中的所有内容都修改为 utf8mb4_unicode_ci 排序规则和 utf8mb4 字符集。然后修改了从 API 获取数据并将其输入数据库的脚本。我正在使用 PDO 连接到数据库,所以我将字符集添加到 PDO 条目中。

$dbh = new PDO("mysql:host=localhost;dbname=dbname;charset=utf8mb4", 'username', 'password');

这使数据正确进入数据库,但 JSON 解析器仍然无法正常工作。发现我还需要明确告诉它在 UTF-8MB4 字符集中工作。添加

$con->set_charset("utf8mb4");

SQL 查询修复该问题之前的 PHP 脚本。现在,正确的字符会通过数据进入数据库的位置和请求的时间。所以问题是脚本没有设置为 UTF-8,当数据通过时。希望这可以帮助遇到类似问题的人。

【问题讨论】:

  • 您的错误日志中有什么内容吗?
  • 您的 cmets 和代码不匹配。你说你尝试使用$result=array_push(...),但你的代码只是说array_push($result...。是哪个?
  • 如果你只是打印出它返回的任何东西会发生什么?可能与您的预期略有不同
  • 我不确定您是否清楚地说明了您的问题是什么...但是,如果在选择整个表格而不是仅 1 行时,此脚本末尾没有显示任何内容,则可能会向您显示由于表内容而出现问题。您应该尝试在json_encode 之后致电echo json_last_error_msg() 以查看那里是否有问题。如果问题是由于数据库中的非 UTF8 字符引起的,则应尝试在将数组中的字符串发送到 json_encode 之前对其进行转换。
  • 不,日志中没有,只是再次检查。我的意思是如代码所示,array_push($result, array...) 将更新帖子。如果我内爆 $result 数组,使用 implode(",", $result);在 while 循环之前,它会打印所有请求的内容。所以 SQL 命令确实有效,只是在使用 array_push 时无效。我在想也许表中奇怪的数据会导致这种情况?

标签: php mysql sql arrays


【解决方案1】:

为什么不让 MySQL 处理所有的数据操作..

$sql = "SELECT 
    'Team Number' as teamNumberLabel, 
    teamNumber,
    'Team Event Name' as teamEventLabel,
    teamEvent,
    'District Code: ' as teamDistrictCodeLabel,
    teamDistrictCode,
    'City: ' as teamCityLabel,
    teamCity,
    'State/Province: ' as teamStateProvLabel,
    teamStateProv,
    'Country: ' as teamCountryLabel,
    teamCountry,
    'Sponsors: ' as teamNameFullLabel,
    teamNameFull,
    'Nickname: ' as teamNameFull,
    teamNameShort,
    'Name: ' as teamRobotNameLabel,
    teamName as teamRobotName,
    'Rookie Year: ' as teamRookieYearLabel,
    teamRookieYear,
    'Website: ' as teamWebsiteLabel,
    teamWebsite
FROM tableName";

$res = mysqli_query($con,$sql);
$result = mysqli_fetch_all($res, MYSQLI_ASSOC);

print_r($result);

使用mysqli_fetch_all() 一次获取所有结果并跳过循环。

如果您不能使用mysqli_fetch_all(),请参阅here,然后改为:

// Use the query from above
$res = mysqli_query($con,$sql);
$result = array();
while($r = mysqli_fetch_assoc($res, MYSQLI_ASSOC)) array_push($result, $r);

【讨论】:

  • 这可能更好,但由于某种原因,我得到一个未定义的函数错误。查了一下,该函数应该存在我在 PHP 5.6.21-1 上。又查了一下,说如果PHP不是用mysqlnd编译的,这个函数可能不存在,我不相信是这样。
  • 将 PHP 包从 php5-mysql 更改为 php5-mysqlnd,现在代码运行,但我现在得到一个空的 JSON 回复。比白屏更好,我认为它只是马歇尔所说的表格中某处的非 UTF-8 数据。不过现在代码更好了,谢谢。
  • 哦,好吧,如果我有帮助,请随时给我 +1 :)
  • 我做到了,但我的声望不超过 15,所以公开分数不会改变。不过还是谢谢你。在发布之前尝试过滤掉非 utf8 字符,看看是否可以解决问题。如果是这样,我将修改 API 解析器以在将数据输入数据库之前去除非 utf8 字符。 API 应该已经被过滤了,但我可能不应该相信它。
  • 问题最终是需要将数据库切换到 utf8mb4,并且需要明确告知脚本以 utf8mb4 模式运行。现在一切正常,但您的编辑使代码更简单、更易于阅读,非常感谢。
【解决方案2】:

确保$row 在您的array_push 函数中包含所有必需的索引。您应该验证$row

来自mysqli_fetch_array 手册:

Note: This function sets NULL fields to the PHP NULL value.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-26
    • 1970-01-01
    • 1970-01-01
    • 2014-08-29
    相关资源
    最近更新 更多