我试图在我的购物车阵列中获得超过1个项目,但我遇到了一个问题
使用post方法
插入1个项目后,这是我的数据库尝试插入第二个产品后,项目结果将被覆盖。
点击添加到购物车后我的开发者工具输出
添加
我正在使用我的模态> https://pastebin.com/HKSRTG4L中的添加到购物车按钮,该按钮通过ajax提交并解析为add-cart.php
我添加到购物车功能的位置:https://pastebin.com/guv0rB6x
这是我的cart.php代码:
<?php
include_once $_SERVER['DOCUMENT_ROOT']."/EcomApp/konfiguracija.php";
require_once $_SERVER['DOCUMENT_ROOT'].'/EcomApp/config.php';
include 'include/head.php';
include 'include/izbornik.php';
if($cart_id != ''){
$cartQ = $veza->prepare("SELECT * FROM cart WHERE id = '$cart_id';");
$cartQ->execute();
$result= $cartQ->fetch(PDO::FETCH_ASSOC);
$items = json_decode($result['items'],true);var_dump($items) ;
$i = 1;
$sub_total = 0;
$item_count = 0;
}
?>
<div class="col-md-12">
<div class="row">
<h2 class ="text-center">Your Shopping Cart </h2><hr>
<?php if($cart_id =='') :?>
<div class="bg-danger">
<p class="text-center text-danger">
Your shopping cart is empty!
</p>
</div>
<?php else: ?>
<table class="table" >
<thead><th>#</th><th>Item</th><th>Price</th><th>Quantity</th><th>Size</th><th>Sub Total</th></thead>
<tbody>
<?php
foreach ($items as $item){
$product_id =$item['id'];
$productQ = $veza ->prepare("SELECT * FROM products WHERE id = '$product_id'");
$productQ ->execute();
$product= $productQ->fetch(PDO::FETCH_ASSOC);
$sArray = explode (',',$product['sizes']);
foreach($sArray as $sizeString){
$s = explode(':',$sizeString);
if($s[0] ==$item['size']){
$available = $s[1];
}
}
?>
<tr>
<td><?=$i;?></td>
<td><?=$product['title'];?></td>
<td><?=$product['price'];?></td>
<td><?=$item['quantity'];?></td>
<td><?=$item['size'];?></td>
<td><?=$item['quantity'] * $product['price'];?></td>
</t>
<?php } ?>
</tbody>
</table>
<?php endif; ?>
</div>
<?php include 'include/footer.php';?>
我肯定93%确定问题出在数组合并,因为目前插件会用新结果覆盖行而不添加到数组。
<?php
require_once $_SERVER['DOCUMENT_ROOT'].'/EcomApp/konfiguracija.php';
require_once $_SERVER['DOCUMENT_ROOT'].'/EcomApp/config.php';
$product_id = sanitize($_POST['product_id']);
$size = sanitize($_POST['size']);
$available = sanitize($_POST['available']);
$quantity = sanitize($_POST['quantity']);
$item = array();
$item[]= array(
'id' => $product_id,
'size' => $size,
'quantity' => $quantity,
);
$domain = ($_SERVER['HTTP_HOST'] != 'localhost')?'.'.$_SERVER['HTTP_HOST']:false;
$query = $veza->prepare("SELECT * FROM products WHERE id = '$product_id'");
$query ->execute();
$product = $query->fetch(PDO::FETCH_ASSOC);
$_SESSION['success_launch'] = $product['title']. 'was added to your cart.';
//check does cookie cart exist
if($cart_id != ''){
$cartQ= $veza->prepare("SELECT * FROM cart WHERE id = '$cart_id'");
$cart = $cartQ->fetch(PDO::FETCH_ASSOC);
$previous_items = json_decode($cart['items'],true);
$item_match = 0;
$new_items = array();
foreach ($prevous_items as $pitem){
if($item[0]['id']==$pitem['id'] && $item[0]['size'] == $pitem['size']){
$pitem ['quantity']= $pitem['quantity']+$item[0]['quantity'];
if ($pitem['quantity']>$available){
$pitem['quantity'] = $available;
}
$item_match = 1;
}
$new_items[] = $pitem;
}
if($item_match != 1){
$new_items = array_merge($item,(array)$previous_items);
}
$items_json = json_encode($new_items);
$cart_expire = date("Y-m-d H:i:s", strtotime("+30 days"));
$something=$veza->prepare("UPDATE cart SET items = '$items_json',expire_date= '$cart_expire'WHERE id ='$cart_id'");
$something ->execute();
setcookie(CART_COOKIE,'',1,'/',$domain,false);
setcookie(CART_COOKIE,$cart_id,CART_COOKIE_EXPIRE,'/',$domain,false);
}else {
插入
//add cart inside database
$items_json = json_encode($item);
$cart_expire = date("Y-m-d H:i:s",strtotime("+30 days"));
$smth=$veza->prepare("INSERT INTO cart (items,expire_date) VALUES ('$items_json','$cart_expire')");
$smth->execute();
$cart_id = $veza->lastInsertId();
setcookie(CART_COOKIE,$cart_id,CART_COOKIE_EXPIRE,'/',$domain,false);
}
var_dump($cart_id);
?>
添加到购物车功能:https://pastebin.com/guv0rB6x
function add_to_cart(){
jQuery('#modal_errors').html("");
var size = jQuery('#size').val();
var quantity = jQuery('#quantity').val();
var available = jQuery('#available').val();
var error = '';
var data = jQuery("#add_product_form").serialize();
if(size == '' || quantity == '' || quantity == 0){
error += '<p class= "bg-danger text-center">You must choose a size and quantity</p>';
jQuery('#modal_errors').html(error);
return;
}else if (quantity>available){
error += '<p class= "bg-danger text-center">There are only '+available+' available.</p>';
jQuery('#modal_errors').html(error);
return;
}else{
jQuery.ajax({
url: '/EcomApp/admin/parsers/add_cart.php',
method : 'post',
data : data,
success : function(){
location.reload();
},
error : function(){alert("Something went wrong");}
});
}
}
konfiguracija.php 第65行有一个(未定义的偏移量:1)
$ user_data ['last'] = $ fn 1;
但我认为它没有直接连接到功能
try{
$veza = new PDO("mysql:host=" . $host . ";dbname=" . $dbname,$dbuser,$dbpass);
$veza->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$veza->setAttribute(PDO::MYSQL_ATTR_INIT_COMMAND, "SET NAMES 'utf8';");
$veza->exec("SET NAMES 'utf8';");
}catch(PDOException $e){
switch($e->getCode()){
case 1049:
header("location: " . $eone . "error/wrongDBname.html");
exit;
break;
default:
header("location: " . $eone . "error/error.php?code=" . $e->getCode());
exit;
break;
}
}
require_once $_SERVER['DOCUMENT_ROOT'].'/EcomApp/config.php';
require_once BASEURL.'helpers/helpers.php';
session_start();
//
$cart_id = '';
if(isset($_COOKIE[CART_COOKIE])){
$cart_id = sanitize($_COOKIE[CART_COOKIE]);
}
if(isset($_SESSION['SDUser'])){
$user_id =$_SESSION['SDUser'];
$query = $veza->prepare("SELECT* FROM korisnik WHERE id ='$user_id'");
$query->execute();
$user_data = $query->fetch(PDO::FETCH_ASSOC);
$fn = explode(' ', $user_data['full_name']);
$user_data['first'] = $fn[0];
$user_data['last'] = $fn[1];
// print_r($user_data);
}
if(isset($_SESSION['success_launch'])){
echo '<h1><p class="text-success">'.$_SESSION['success_launch'].'</p></h1>';
unset($_SESSION['success_launch']);
}
if(isset($_SESSION['error_launch'])){
echo '<div class="success"><p class="text-success">'.$_SESSION['error_launch'].'</p></div>';
unset($_SESSION['error_launch']);
}
答案 0 :(得分:0)
在add_cart.php中:
$previous_items = json_decode($cart['items'],true);
$item_match = 0;
$new_items = array();
foreach ($prevous_items as $pitem){
请注意,$previous_items
和$prevous_items
不同。
这就是你获得原因的原因:
注意:未定义的变量:prevous_items in 第29行/opt/lampp/htdocs/EcomApp/admin/parsers/add_cart.php
你没有采纳我以前的建议,让你的生活更轻松。
显然工作代码还不够。始终验证并快速失败(http://www.practical-programming.org/ppl/docs/articles/fail_fast_principle/fail_fast_principle.html):
if(!$cart_id){
$cartQ = $veza->prepare("SELECT * FROM cart WHERE id = ?");
$cartQ->execute([(int)$cart_id]);
$result= $cartQ->fetch(PDO::FETCH_ASSOC);
if (!isset($result['items'])) {
throw new \RuntimeException("The items were not found.");
}
$items = json_decode($result['items'],true);
if (!$items) {
throw new \RuntimeException("Invalid items format.");
}
$i = 1;
$sub_total = 0;
$item_count = 0;
}
如上所述,做这样的事情:
<?php
$validKeys = ['product_id', 'size', 'available', 'quantity'];
foreach ($validKeys as $key) {
if (!isset($_POST[$key])) {
throw new RuntimeException("Parameter $key is missing.");
}
}
require_once $_SERVER['DOCUMENT_ROOT'].'/EcomApp/konfiguracija.php';
require_once $_SERVER['DOCUMENT_ROOT'].'/EcomApp/config.php';
$product_id = sanitize($_POST['product_id']);
$size = sanitize($_POST['size']);
$available = sanitize($_POST['available']);
$quantity = sanitize($_POST['quantity']);
很可能你在客户端错过了某些东西(javascript或HTML表单),例如,你可能拼写错误&#34; product_id&#34;。
<强>增加:强>
function add_to_cart(){
jQuery('#modal_errors').html("");
var size = jQuery('#size').val();
var quantity = jQuery('#quantity').val();
var available = jQuery('#available').val();
var error = '';
var data = jQuery("#add_product_form").serialize();
if(size == '' || quantity == '' || quantity == 0){
error += '<p class= "bg-danger text-center">You must choose a size and quantity</p>';
jQuery('#modal_errors').html(error);
return;
}else if (quantity>available){
error += '<p class= "bg-danger text-center">There are only '+available+' available.</p>';
jQuery('#modal_errors').html(error);
return;
}else{
jQuery.ajax({
url: '/EcomApp/admin/parsers/add_cart.php',
method : 'post',
data : data,
success : function(){
location.reload();
},
error : function(){alert("Something went wrong");}
});
}
}
您没有检查&#34; product_id&#34;字段是空的。
<强>增加:强>
替换:
$previous_items = json_decode($cart['items'],true);
$item_match = 0;
$new_items = array();
foreach ($prevous_items as $pitem){
if($item[0]['id']==$pitem['id'] && $item[0]['size'] == $pitem['size']){
$pitem ['quantity']= $pitem['quantity']+$item[0]['quantity'];
if ($pitem['quantity']>$available){
$pitem['quantity'] = $available;
}
$item_match = 1;
}
$new_items[] = $pitem;
}
if($item_match != 1){
$new_items = array_merge($item,(array)$previous_items);
}
有这样的事情:
$previous_items = json_decode($cart['items'], true);
if (!$previous_items) {
$previous_items = array();
}
$items_by_unique = array();
foreach (array_merge($item, $previous_items) as $item) {
if (!isset($item['id'], $item['size'], $item['quantity'])) {
throw new RuntimeException('Found a invalid invalid data: ' . json_encode($item));
}
$unique = $item['id'] . '-' . $item['size'];
if (isset($items_by_unique[$unique])) {
$old_item = $items_by_unique[$unique];
$item['quantity'] = $old_item['quantity'];
}
if ($item['quantity'] > $available) {
$item['quantity'] = $available;
}
$items_by_unique[$unique] = $item;
}
$items_json = json_encode(array_values($items_by_unique));
答案 1 :(得分:0)
代码有很多问题很难找到错误,而且很难回答一个问题,这个问题总是在增加几个问题,好像我们正在免费提供调试服务......我们可能会在这里讨论几个小时和几天,就像工作一样,直到一切都得到纠正。在这种情况下,帮助和照顾我们的个人生活和工作将非常困难。
无论如何,我将列举一些使代码很难调试的问题。
大多数返回的值都没有经过验证,假设它们是预期的,而是在出现错误时立即失败。这意味着你可能只会注意到很多错误并寻找其来源,这可能是在另一个文件中。
例如,当你做这样的事情时:
$query = $veza->prepare("SELECT * FROM products WHERE id = '$product_id'");
$query->execute();
$product = $query->fetch(PDO::FETCH_ASSOC);
您应该始终检查$product
是否至少不为空:
if (!$product) {
throw new RuntimeException("The product #$product_id" was not found.");
}
此外,将变量放在SQL语句中可能非常危险。如果你正在使用准备好的陈述,你应该这样做:
$query = $veza->prepare("SELECT * FROM products WHERE id = ? LIMIT 1");
$query->execute([$product_id]);
代码没有利用可重用性。您可以实现类或函数并单独测试它们。
例如,你可以做这样的事情:
<?php
/**
* Add a new item ...
*
* If it's being requested more items then available ...
*
* @param array $newItem The new item that should be added.
* @param array $items The list of items where the item should be added.
* @param integer $available Available items.
* @return void
*/
function add_item(array $newItem, array &$items, int $available=MAX_INT_MAX)
{
throw_error_if_invalid_item($newItem);
$unique = $newItem['id'] . '-' . $newItem['size'];
if (isset($items_by_unique[$unique])) {
add_item_quantity(
$items_by_unique[$unique],
$item['quantity'],
$available
);
} else {
$items[] = $newItem;
}
}
/**
* Add quantity ...
*
* @param array $item ...
* @param integer $moreQuantity ...
* @param integer $available ...
* @return void
*/
function add_item_quantity(array &$item, int $moreQuantity, int $available=MAX_INT_MAX)
{
$item['quantity'] += $moreQuantity;
if ($item['quantity'] > $available) {
$item['quantity'] = $available;
}
}
/**
* ...
*
* @param array $item ...
* @return void
*/
function throw_error_if_invalid_item(array $item)
{
if (!isset($item['id'], $item['size'], $item['quantity'])) {
throw new RuntimeException(
'Found a invalid invalid item data: ' . json_encode($item)
);
}
}
然后,您可以在隔离文件中进行单独测试:
<?php
$item = array(
'id' => 10,
'size' => 'm',
'quantity' => 2,
);
add_item_quantity($item, 3, 10);
if ($item['quantity'] != 5) {
echo "wrong! quantity = {$item['quantity']}\n";
} else {
echo "correct!\n";
}
如果您将类或函数放在专用文件中,则可以将它们重用为库,使代码易于阅读,测试和安全:
<?php
throw_error_if_invalid_item($_POST);
$newItem = create_item($_POST);
$items = fetch_cart_items($cart_id);
add_item($newItem, $items, 10);
save_cart_items($items);
show_json_items($json);
使用类会更容易(例如:您不必担心丢失数组键)并且可以使用PHPUnit自动测试所有函数和方法。检查我是如何为一个简单的项目做的那样:
https://github.com/pedroac/nonce4php
您还可以使脚本出现任何错误或警告:
<?php
set_error_handler(
function (int $errno , string $errstr, string $errfile, int $errline) {
http_response_code(500);
echo "ERROR #$errono:$errfile:$errline: $errstr";
die();
}
);
set_exception_handler(
function (Throwable $exception) {
http_response_code(500);
echo $exception->getMessage();
die();
}
);
如果您按照good practices进行操作,发现错误会更容易,并让其他人帮助您。
答案 2 :(得分:0)
我通过将array_merge
的第二个参数强制转换为数组来修复此问题:
$new_items = array_merge($item, (array)$previous_items);