Hallo allemaal,

Ik heb een pagina met PHP en HTML code. Deels wordt de html-code gegenereerd door de PHP-code.
Heel veel loopt goed. Maar nu heb ik een bug in mijn pagina zitten die ik niet kan verklaren en waar misschien een hele simpele oplossing voor is.

Ik heb een tabel in mijn database zitten waar ik een id_product heb en een collected.
Als ik op mijn pagina klik op een knopje in een regel van een tabel, dan neemt hij id_product mee naar de volgende code.

		$query_exist = "SELECT * FROM `prstshp_collect_products` WHERE `id_product` = $idproduct;";
		$result_exist = mysqli_query($con,$query_exist);
		$match_found = mysqli_num_rows($result_exist)>0;
		$row_exists = mysqli_fetch_array($result_exists,MYSQLI_ASSOC);
		$collected = $rows_exists["collected"];
		
		if ( $match_found ) 
		{
			// Voor dit product is al een regel aanwezig
			// Als het record er al wel is, dan moet met UPDATE het veld collected van 0 naar 1 worden omgezet of omgekeerd.
			if ( $collected = 1) 
			{
				$query_3 = "UPDATE prstshp_collect_products SET collected = 0 WHERE id_product = $idproduct;";
			}
			else
			{
				$query_3 = "UPDATE prstshp_collect_products SET collected = 1 WHERE id_product = $idproduct;";
			}
		}
		else
		{ 
			// Voor dit product is nog geen regel aanwezig
			// Deze query plaatst een nieuw record omdat er geen recod met dit id_product is.
			$query_3 = "INSERT INTO prstshp_collect_products ( id_product, collected ) VALUES ( $idproduct, 1 );";
		}
		
		mysqli_query($con, $query_3);	
		header("Location: " . $_SERVER['PHP_SELF']);
		mysqli_close($con);
		exit();

De eerste keer gaat goed. Er wordt een record aangemaakt. Nog steeds werkt alles perfect.
De tweede keer doe ik precies het zelfde en wordt er een update gedaan van de bewuste regel. Collected wordt van 1 naar 0 gezet. (Nog steeds goed)
Dan de derde keer. Ik doe weer precies het zelfde, maar gek genoeg wordt collect nu niet terug naar 1 gezet.

Als ik mijn code bekijk zie ik bij de 2 UPDATE regels geen verschil. Natuurlijk wel de 1 en de 0 die omgezet moeten worden.

Wie heeft er een idee wat ik hier niet goed heb gedaan?
if ( $collected = 1)

Je wilt een vergelijking doen, en geen toewijzing.
Dus gebruik ==

Wouw - Ariën - wat ben jij snel. Bedankt voor de tip.
Maar als ik dat doe, kan ik hem wel op 1 zetten maar niet meer terug naar 0.

Collected is van het type tinyint(1) Als dat misschien nog invloed kan hebben.
Aan de hand van de waarde van $collected moet deze op 0 kunnen worden gezet.
Dus kijk eens hoe de query eruit ziet, en of deze uitgevoerd wordt.

Als je een mooie opzet wilt hebben voor het opzetten van queries met de controle en debugging-mogelijkheden. Bekijk dan deze voorbeelden in mijn Github:
https://github.com/arienclaij/sql-boilerplate/tree/master/mysqli
De query die ik laat uitvoeren staan in mijn code die ik hier aangeef.
Bij de INPUT query zet hij collected keurig op 1.
Maar met if ( $collected = 1) zet hij hem op 0 en daarna niet meer op 1
En met if ( $collected == 1) kan ik hem al niet naar 0 zetten.
Kijk eens of je query goed werkt, echo hem eens.
Zie ook mijn vorige reactie en kijk eens naar de tips.
Ik heb gevonden dat ik ook in de SQL een voorwaarde kan stellen.
De code is als volgt: (En werkt goed)

	if ( isset( $_POST['submit_button_administratie']))
	{
		$idproduct = $_POST['submit_button_administratie'];
		
		// Bestaat er een record in prstshp_collect_products met dit id_product?
		$query_exist = "SELECT * FROM `prstshp_collect_products` WHERE `id_product` = $idproduct;";
		$result_exist = mysqli_query($con,$query_exist);
		$match_found = mysqli_num_rows($result_exist)>0;
		$row_exists = mysqli_fetch_array($result_exists,MYSQLI_ASSOC);
		$collected = $rows_exists["collected"];
		
		if ( $match_found ) 
		{
			// Voor dit product is al een regel aanwezig
			// Als het record er al wel is, dan moet met UPDATE het veld collected van 0 naar 1 worden omgezet of omgekeerd.
			$query_3 = "UPDATE prstshp_collect_products 
							SET collected = case 
								when collected=0 then 1 
								else 0 end 
						WHERE id_product = $idproduct";
			
		}
		else
		{ 
			// Voor dit product is nog geen regel aanwezig
			// Deze query plaatst een nieuw record omdat er geen recod met dit id_product is.
			$query_3 = "INSERT INTO prstshp_collect_products ( id_product, collected ) VALUES ( $idproduct, 1 );";
		}
		
		mysqli_query($con, $query_3);
		header("Location: " . $_SERVER['PHP_SELF']);
		exit();


Nogmaals hartelijk dank voor de assistentie.
Een controle of iets verstuurd is via POST, dat doe je op deze manier:

if($_SERVER['REQUEST_METHOD'] == "POST") {


Verder kan je ook de vergelijkings-logica vanuit PHP naar je query verschuiven met een WHEN.
Jouw vorige manier had ook gekund, maar ik denk dat er ergens een bug in je code zat. Als je jouw query had geécho'ed had je misschien daaraan kunnen zien dat het niet lukte. Maar het kan net zo goed ook zo zijn dat je query niet uitgevoerd werd. En dat je waarde nooit aangepast werd. Dus houd altijd je phpMyAdmin, of je MySQL-tool in de gaten.

Enige foutafhandeling hierin ontbreekt bij jouw.
Dus daarom mijn advies om mijn Github-linkje eens aandachtig te bekijken.

Je wilt liever niet gissen en gokken, maar direct zien wat er fout is.
Frits van Leeuwen op 06/03/2023 00:01:38

Ik heb gevonden dat ik ook in de SQL een voorwaarde kan stellen.
De code is als volgt: (En werkt goed)

			$query_3 = "UPDATE prstshp_collect_products 
							SET collected = case 
								when collected=0 then 1 
								else 0 end 
						WHERE id_product = $idproduct";


waarom zo moeilijk doen? gewoon
SET collected = not collected


Jan
Wat je fout doet:
<?php
$idproduct = $_POST['submit_button_administratie'];
// ...
$query_3 = "UPDATE prstshp_collect_products SET collected = 0 WHERE id_product = $idproduct;";
?>

Je code voldoet hiermee aan CWE-89, de #3 van de top 25 meest gemaakte beveiligingsfouten van vorig jaar.
Er zijn genoeg oplossingen voor dit probleem. Een daarvan is deze:
<?php
$idproduct = mysqli_real_escape_string($con, $_POST['submit_button_administratie']);
?>

"Onwetend zondigt men niet."

Reageren