通过添加1更新PHP MYSQL行

通过添加1更新PHP MYSQL行,php,mysql,database,Php,Mysql,Database,你好,我想做一个像投票一样的人 因此,行bitwa_glosy设置为0 当我按下按钮后,方法应该将值从0增加到1。每次我按下按钮都会长大 从DB读取值 $Query="SELECT * FROM tentego_img WHERE id='$aid'"; $QueryResult=mysql_query($Query); while($Kol_a=mysql_fetch_array($QueryResult)){ $a_glos =$Kol_a['bitwa_glosy']; // Values

你好,我想做一个像投票一样的人

因此,行bitwa_glosy设置为0

当我按下按钮后,方法应该将值从0增加到1。每次我按下按钮都会长大

从DB读取值

$Query="SELECT * FROM tentego_img WHERE id='$aid'";
$QueryResult=mysql_query($Query);
while($Kol_a=mysql_fetch_array($QueryResult)){
$a_glos =$Kol_a['bitwa_glosy']; // Values= 0 
现在我知道bitwa_glosy的值是0

并试图增加

if(isset($_POST['glos_a']))

    {
        $plus = 1;
        $a_glos = $a_glos+$plus;
    $dodaj_glos_a = "UPDATE `tentego_img` SET `bitwa_glosy` = $plus WHERE `id`=$aid"; 
    $idzapytania = mysql_query($dodaj_glos_a);
    }
但它不起作用,我不知道为什么

这是邮寄表格

<form method="post"><input type="submit" name="glos_a" value="Głosuj +"/></form>

***根据你的建议和答案编辑了最后的代码,但仍然不起作用,我放弃了,谢谢所有试图帮助我的人

奶酪

感谢大家的关注,我放弃了他们,代码有时有效,有时无效,并尝试了所有答案

顺便说一句,有些代码根据您的建议进行了修改,但仍然不起作用

干杯

<!-- Begin Block -->
<?php
$ilosc= 1;
$typ= 'img';




#Lewa
$Query="SELECT * FROM tentego_img WHERE type='img' ORDER BY RAND() LIMIT ".$ilosc;
$QueryResult=mysql_query($Query);
while($Kol=mysql_fetch_array($QueryResult)){
$atytul =$Kol['title'];
$asrc =$Kol['src'];
$aid =$Kol['id'];
}


#Prawa
$QueryResult=mysql_query($Query);
while($Kol1=mysql_fetch_array($QueryResult)){
$btytul =$Kol1['title'];
$bsrc =$Kol1['src'];
$bid =$Kol1['id'];
}



echo '<table border="0"><tr>';
echo '<td><span style="color:green">#1#</span> '.$atytul.'</td><td></td><td><span style="color:red">#2#</span> '.$btytul.'</td><tr>';
echo '<td><a href="/img/'.$aid.'/'.$atytul.'/"><img src="/upload/'.$asrc.'" alt="'.$atytul.'" title="'.$atytul.'" width="370px" height="370px" /></a>Liczba głósów:0<form method="post"><input type="submit" name="glos_a" value="Głosuj +"/></form></td><td><img src="./_themes/fajna/bitwa/vs.png" /></td>';
echo '<td><a href="/img/'.$bid.'/'.$btytul.'/"><img src="/upload/'.$bsrc.'" alt="'.$btytul.'" title="'.$btytul.'" width="370px" height="370px" /></a>Liczba głosów:0<form method="post"><input type="submit" name="glos_b" value="Głosuj +"/></form></td>';
echo '</tr></table>';
$plus = 1;
if(isset($_POST['glos_a']))
{
$a_glos = $a_glos+$plus;
     $dodaj_glos_a = "UPDATE `tentego_img` SET `bitwa_glosy` = `bitwa_glosy` + $plus WHERE `id`=$aid"; 
$idzapytania = mysql_query($dodaj_glos_a);
}
if(isset($_POST['glos_b']))
{

     $dodaj_glos_b = "UPDATE `tentego_img` SET `bitwa_glosy` = `bitwa_glosy` + $plus WHERE `id`=$bid"; 
$idzapytania2 = mysql_query($dodaj_glos_b);
}

?>
   </div>   
<!-- End Block --> 

与其查询然后更新,为什么不试试这个

 UPDATE `tentego_img` SET `bitwa_glosy` = `bitwa_glosy` + 1  WHERE `id`=$aid
(还有,请注意SQL注入。如果您的用户设法给您$aid值“7;DROP TABLE TENTEGO_IMG;”,系统会发生什么情况?)

将查询更改为

更新
tentegou img
SET
bitwa_glosy
='bitwa_glosy'+1,其中
id
=$aid

它“不起作用”,因为您将
$plus
的值分配给列,而不是将
$plus
的值添加到列中存储的当前值

要解决此问题,请从以下位置更改更新查询:

"UPDATE `tentego_img` SET `bitwa_glosy` = $plus WHERE `id`=$aid";
为此:

"UPDATE `tentego_img` SET `bitwa_glosy` = `bitwa_glosy` + $plus WHERE `id`=$aid";
                                           ^^^^^^^^^^^^^^
您的问题提到的值为0。如果当前值为零,则不清楚是否只希望增加此行。您还提到,该值应该随着每个按钮的按下而递增,这听起来好像您希望它递增,不仅仅是从零递增,而是从当前值递增

不要这样做:

"UPDATE `tentego_img` SET `bitwa_glosy` = $a_glos WHERE `id`=$aid";
                                          ^^^^^^^  
看起来您正在计算$a_glos,并打算将其分配给列。但不要这样做,因为这会带来并发问题,“最后更新获胜”反模式

考虑两个(或多个)副本同时运行时会发生什么情况。该计数器的递增次数可能比它应该增加的次数少,最终得到的值可能比预期值低

假设流程的每个副本都可以运行SELECT,并且如果时机合适,恰好可以检索相同的值。然后,每个进程都将更新表。稍后的更新将覆盖第一个更新。最终的结果是计数器增加1,而不是我们预期的2

而且,如果在其中一个进程中,SELECT和更新之间发生了较大的延迟,那么在更新运行时,计数器实际上可能被设置为低于其当前值

要避免这种情况,请使用原子操作。使用一条语句检索当前值,向其添加
$plus
,然后在一次操作中设置列

(此方法在此处的其他好答案中得到了演示。)

作为并发问题的演示,当四个进程同时运行时,考虑这一点:

process 1    : select gets 0
process  2   : select gets 0
process   3  : select gets 0
process 1    : update set to 1
process    4 : select gets 1
process   3  : update set to 1
process    4 : update set to 2
process  2   : update set to 1
在完成四次执行时,我们希望将值设置为4

但我们保证得到的唯一方法是,流程之间没有重叠。在多用户、多线程环境中,如果不引入对资源的“序列化”访问,这是不可能保证的,而且这不必要地增加了复杂性并影响了可伸缩性

在单用户开发测试中,如果不在SELECT和更新之间的代码中添加某种明显的延迟,并且运行两个或多个进程,则很难发现这个问题。但即使是在“低容量、低概率”的情况下,您也确实希望避免“最后一次更新获胜”的反模式


因此,不需要检索列的当前值的代码段,当然,除非您正在检索要显示在页面上的值,显示当前投票总数。

bitwa_glosy
=
bitwa_glosy
+1是一种更简单的方法。您当前正在设置
$plus=1
,然后更新记录并将bitwa_glossy值设置为
$plus
的值,即1。相反,您应该使用当前代码将其设置为
$a_glos
。这远远超出了您的需要。它过度混淆了目的,并且受到(一个更麻烦的)并发问题的影响。当两个(或更多)同时运行时,计数器只能递增1。每个进程都可以运行select,并获得相同的值,然后每个进程更新表。稍后的更新将覆盖第一个更新。因此计数器的增量为1,而不是2(或更多)。(如果在选择和更新之间有很大的延迟,计数器实际上可以设置得更低。如答案中所示,通过原子操作避免这种情况。@Mike:事实上,不是。将列的值设置为
$a_glos
是一种反模式,如果目的是“将当前值增加一个”,则应该避免这种情况发生。)。不需要在单独的语句中检索列值。最好在更新列的同一语句中引用列中的当前值。为了进一步说明@phpisuber01所说的,不仅有“更简单”这样做的方法,但这样做也更好。@spencer7593这就是为什么我将其作为注释而不是答案添加。我的目的是显示当前代码中的错误。事实上-本应使用PDO/Mysqli为安全性准备的语句添加代码段,以防出现此类错误