PHP:显示NULL但实际包含数据
PHP: displaying NULL but actually contains data
产品table结构如下
CREATE TABLE `products` (
`id` int(6) unsigned NOT NULL AUTO_INCREMENT,
`category_id` int(6) unsigned NOT NULL,
`name` varchar(30) NOT NULL,
`unit_id` int(6) unsigned NOT NULL,
`brand_id` int(6) unsigned NOT NULL,
`orignalCost` int(30) NOT NULL,
`saleprice` int(30) NOT NULL,
`deleted` tinyint(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
KEY `fk-to-uom` (`unit_id`),
KEY `fk-to-brand` (`brand_id`),
KEY `category_id` (`category_id`),
CONSTRAINT `fk-to-brand` FOREIGN KEY (`brand_id`) REFERENCES `brands` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `products_ibfk_1` FOREIGN KEY (`category_id`) REFERENCES `categories` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=230 DEFAULT CHARSET=utf8mb4
谁能告诉我我犯了什么错误,因为 var_dump() 显示 NULl 值……mysqli_fetch_array 有什么错误吗?它显示为 "array(1) { [0]=> NULL } "
$selected_items_values = $_POST['product_id'];
$prices = [];
foreach($selected_items_values as $prud)
{
if(isset($prud))
{
$priceSql = "SELECT saleprice from products where id = ' $prud ' ";
$price=mysqli_query($db,$priceSql);
$price = mysqli_fetch_array($price);
array_push($prices , $price);
var_dump($prices);
}
}
编辑后的答案
这是我创建的示例 table。 (我删除了外键)
CREATE TABLE `products` (
`id` int(6) unsigned NOT NULL AUTO_INCREMENT,
`category_id` int(6) unsigned NOT NULL,
`name` varchar(30) COLLATE utf8_turkish_ci NOT NULL,
`unit_id` int(6) unsigned NOT NULL,
`brand_id` int(6) unsigned NOT NULL,
`orignalCost` int(30) NOT NULL,
`saleprice` int(30) NOT NULL,
`deleted` tinyint(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`)
)
这是示例插入语句
INSERT INTO `products`VALUES (NULL, '1', 'name1', '1', '1', '100', '200', '0');
INSERT INTO `products`VALUES (NULL, '2', 'name2', '2', '2', '100', '200', '0');
INSERT INTO `products`VALUES (NULL, '3', 'name3', '3', '3', '100', '200', '0');
INSERT INTO `products`VALUES (NULL, '4', 'name4', '4', '4', '100', '200', '0');
INSERT INTO `products`VALUES (NULL, '5', 'name5', '5', '5', '100', '200', '0');
INSERT INTO `products`VALUES (NULL, '6', 'name6', '6', '6', '100', '200', '0');
这是我输入的示例数据。
+----+-------------+-------+---------+----------+-------------+-----------+---------+
| id | category_id | name | unit_id | brand_id | orignalCost | saleprice | deleted |
+----+-------------+-------+---------+----------+-------------+-----------+---------+
| 1 | 1 | name1 | 1 | 1 | 100 | 200 | 0 |
+----+-------------+-------+---------+----------+-------------+-----------+---------+
| 2 | 2 | name2 | 2 | 2 | 100 | 200 | 0 |
+----+-------------+-------+---------+----------+-------------+-----------+---------+
| 3 | 3 | name3 | 3 | 3 | 100 | 200 | 0 |
+----+-------------+-------+---------+----------+-------------+-----------+---------+
| 4 | 4 | name4 | 4 | 4 | 100 | 200 | 0 |
+----+-------------+-------+---------+----------+-------------+-----------+---------+
| 5 | 5 | name5 | 5 | 5 | 100 | 200 | 0 |
+----+-------------+-------+---------+----------+-------------+-----------+---------+
| 6 | 6 | name6 | 6 | 6 | 100 | 200 | 0 |
+----+-------------+-------+---------+----------+-------------+-----------+---------+
这里是 db connect 通过 PHP 获取所有数据。
$conn = mysqli_connect("$db_host","$db_username","$db_pass","$db_name");
$query = $conn->query("SELECT * FROM `products`;");
var_dump($query);
这是上面的结果。你可以看到我有 6 行。
mysqli_result Object
(
[current_field] => 0
[field_count] => 8
[lengths] =>
[num_rows] => 6
[type] => 0
)
为了遍历 php 对象使用 foreach
foreach ($query as $key => $value) {
var_dump($value);
}
Foreach 结果如下
Array
(
[id] => 1
[category_id] => 1
[name] => name1
[unit_id] => 1
[brand_id] => 1
[orignalCost] => 100
[saleprice] => 200
[deleted] => 0
)
Array
(
[id] => 2
[category_id] => 2
[name] => name2
[unit_id] => 2
[brand_id] => 2
[orignalCost] => 100
[saleprice] => 200
[deleted] => 0
)
It continues like that...
为了只得到 saleprice
像下面这样使用它。
foreach ($query as $key => $value) {
var_dump($value['saleprice']);
}
这就是您的获取方式。剩下的就看你怎么用了。
除了特定于您的实施的错误之外,此代码还有两个重要问题:
- 您是 运行 一个循环中的查询,使您正在执行的查询数量成倍增加并产生额外的数据库流量。
- 您正在将不受信任的数据连接到您的查询中,让自己容易受到 SQL 注入
第一个问题的答案是使用SELECT...WHERE...IN...
,从而在一个查询中选择所有需要的数据
第二个问题是通过使用准备好的语句来解决的。对于可变长度数据,它们的设置可能很繁琐,但提高安全性和性能是值得的。
对于您的示例,我们需要获取表单的查询
SELECT `saleprice` FROM `products` WHERE `id` IN (?,?,?); // could be any number of placeholders here.
$mysqli = new mysqli('localhost','user','password','schema');
// create the placeholders
$paramList = str_repeat("?,", count($_POST['product_id']));
$query = "select saleprice from products where id in (".trim($paramList, ',').")";
$stmt = $mysqli->prepare($query);
// create a string of parameter types
$types = str_repeat('s', count($_POST['product_id'])); // All $_POST values are strings.
// Now bind the data to the query
$stmt->bind_param($types, ...$_POST['product_id']); // Use the ... spread operator to unpack the array
$stmt->execute();
$stmt->bind_result($resultData);
while ($row = $stmt->fetch()) {
echo $resultData;
echo "<br>\n";
}
来源:代码取自 this blog
产品table结构如下
CREATE TABLE `products` (
`id` int(6) unsigned NOT NULL AUTO_INCREMENT,
`category_id` int(6) unsigned NOT NULL,
`name` varchar(30) NOT NULL,
`unit_id` int(6) unsigned NOT NULL,
`brand_id` int(6) unsigned NOT NULL,
`orignalCost` int(30) NOT NULL,
`saleprice` int(30) NOT NULL,
`deleted` tinyint(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
KEY `fk-to-uom` (`unit_id`),
KEY `fk-to-brand` (`brand_id`),
KEY `category_id` (`category_id`),
CONSTRAINT `fk-to-brand` FOREIGN KEY (`brand_id`) REFERENCES `brands` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `products_ibfk_1` FOREIGN KEY (`category_id`) REFERENCES `categories` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=230 DEFAULT CHARSET=utf8mb4
谁能告诉我我犯了什么错误,因为 var_dump() 显示 NULl 值……mysqli_fetch_array 有什么错误吗?它显示为 "array(1) { [0]=> NULL } "
$selected_items_values = $_POST['product_id'];
$prices = [];
foreach($selected_items_values as $prud)
{
if(isset($prud))
{
$priceSql = "SELECT saleprice from products where id = ' $prud ' ";
$price=mysqli_query($db,$priceSql);
$price = mysqli_fetch_array($price);
array_push($prices , $price);
var_dump($prices);
}
}
编辑后的答案
这是我创建的示例 table。 (我删除了外键)
CREATE TABLE `products` (
`id` int(6) unsigned NOT NULL AUTO_INCREMENT,
`category_id` int(6) unsigned NOT NULL,
`name` varchar(30) COLLATE utf8_turkish_ci NOT NULL,
`unit_id` int(6) unsigned NOT NULL,
`brand_id` int(6) unsigned NOT NULL,
`orignalCost` int(30) NOT NULL,
`saleprice` int(30) NOT NULL,
`deleted` tinyint(1) NOT NULL DEFAULT 0,
PRIMARY KEY (`id`)
)
这是示例插入语句
INSERT INTO `products`VALUES (NULL, '1', 'name1', '1', '1', '100', '200', '0');
INSERT INTO `products`VALUES (NULL, '2', 'name2', '2', '2', '100', '200', '0');
INSERT INTO `products`VALUES (NULL, '3', 'name3', '3', '3', '100', '200', '0');
INSERT INTO `products`VALUES (NULL, '4', 'name4', '4', '4', '100', '200', '0');
INSERT INTO `products`VALUES (NULL, '5', 'name5', '5', '5', '100', '200', '0');
INSERT INTO `products`VALUES (NULL, '6', 'name6', '6', '6', '100', '200', '0');
这是我输入的示例数据。
+----+-------------+-------+---------+----------+-------------+-----------+---------+
| id | category_id | name | unit_id | brand_id | orignalCost | saleprice | deleted |
+----+-------------+-------+---------+----------+-------------+-----------+---------+
| 1 | 1 | name1 | 1 | 1 | 100 | 200 | 0 |
+----+-------------+-------+---------+----------+-------------+-----------+---------+
| 2 | 2 | name2 | 2 | 2 | 100 | 200 | 0 |
+----+-------------+-------+---------+----------+-------------+-----------+---------+
| 3 | 3 | name3 | 3 | 3 | 100 | 200 | 0 |
+----+-------------+-------+---------+----------+-------------+-----------+---------+
| 4 | 4 | name4 | 4 | 4 | 100 | 200 | 0 |
+----+-------------+-------+---------+----------+-------------+-----------+---------+
| 5 | 5 | name5 | 5 | 5 | 100 | 200 | 0 |
+----+-------------+-------+---------+----------+-------------+-----------+---------+
| 6 | 6 | name6 | 6 | 6 | 100 | 200 | 0 |
+----+-------------+-------+---------+----------+-------------+-----------+---------+
这里是 db connect 通过 PHP 获取所有数据。
$conn = mysqli_connect("$db_host","$db_username","$db_pass","$db_name");
$query = $conn->query("SELECT * FROM `products`;");
var_dump($query);
这是上面的结果。你可以看到我有 6 行。
mysqli_result Object
(
[current_field] => 0
[field_count] => 8
[lengths] =>
[num_rows] => 6
[type] => 0
)
为了遍历 php 对象使用 foreach
foreach ($query as $key => $value) {
var_dump($value);
}
Foreach 结果如下
Array
(
[id] => 1
[category_id] => 1
[name] => name1
[unit_id] => 1
[brand_id] => 1
[orignalCost] => 100
[saleprice] => 200
[deleted] => 0
)
Array
(
[id] => 2
[category_id] => 2
[name] => name2
[unit_id] => 2
[brand_id] => 2
[orignalCost] => 100
[saleprice] => 200
[deleted] => 0
)
It continues like that...
为了只得到 saleprice
像下面这样使用它。
foreach ($query as $key => $value) {
var_dump($value['saleprice']);
}
这就是您的获取方式。剩下的就看你怎么用了。
除了特定于您的实施的错误之外,此代码还有两个重要问题:
- 您是 运行 一个循环中的查询,使您正在执行的查询数量成倍增加并产生额外的数据库流量。
- 您正在将不受信任的数据连接到您的查询中,让自己容易受到 SQL 注入
第一个问题的答案是使用SELECT...WHERE...IN...
,从而在一个查询中选择所有需要的数据
第二个问题是通过使用准备好的语句来解决的。对于可变长度数据,它们的设置可能很繁琐,但提高安全性和性能是值得的。
对于您的示例,我们需要获取表单的查询
SELECT `saleprice` FROM `products` WHERE `id` IN (?,?,?); // could be any number of placeholders here.
$mysqli = new mysqli('localhost','user','password','schema');
// create the placeholders
$paramList = str_repeat("?,", count($_POST['product_id']));
$query = "select saleprice from products where id in (".trim($paramList, ',').")";
$stmt = $mysqli->prepare($query);
// create a string of parameter types
$types = str_repeat('s', count($_POST['product_id'])); // All $_POST values are strings.
// Now bind the data to the query
$stmt->bind_param($types, ...$_POST['product_id']); // Use the ... spread operator to unpack the array
$stmt->execute();
$stmt->bind_result($resultData);
while ($row = $stmt->fetch()) {
echo $resultData;
echo "<br>\n";
}
来源:代码取自 this blog