Kan dit misschien beter???
Ik neem alle adviezen zeker ten harte en ik leer er ook van en pas ze zeker toe (of later)
Maar ik ben even bezig geweest met het kijken of dit misschien goed is of beter kan.
wat het script doet, is kijken of de user een bepaalde service aan heeft of niet.
Ik heb het op deze manier gedaan en het werkt, maar ik vraag me af, kon/kan het het beter?
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
/* Services & Options page */
/* In this table are all the user_id`s with the corrensponding services_id */
$sql = 'SELECT * FROM Services ORDER BY ID';
$result = mysqli_query($connect, $sql);
$Options = mysqli_fetch_all($result, MYSQLI_ASSOC);
foreach($Options as $option) {
$MySql = 'Select UserServices.Services_ID, Services.Services FROM UserServices INNER JOIN Services ON Services.ID WHERE Services.ID = UserServices.Services_ID AND User_ID ='.$_SESSION['ID'].';';
$myresult = mysqli_query($connect, $MySql);
$uoptions = mysqli_fetch_all($myresult, MYSQLI_ASSOC);
echo $option['Services'];
foreach($uoptions as $services) {
if(!empty($services['Services_ID'] == $option['ID'])){
echo " this is checked";
}
}
echo "<br>";
}
?>
/* Services & Options page */
/* In this table are all the user_id`s with the corrensponding services_id */
$sql = 'SELECT * FROM Services ORDER BY ID';
$result = mysqli_query($connect, $sql);
$Options = mysqli_fetch_all($result, MYSQLI_ASSOC);
foreach($Options as $option) {
$MySql = 'Select UserServices.Services_ID, Services.Services FROM UserServices INNER JOIN Services ON Services.ID WHERE Services.ID = UserServices.Services_ID AND User_ID ='.$_SESSION['ID'].';';
$myresult = mysqli_query($connect, $MySql);
$uoptions = mysqli_fetch_all($myresult, MYSQLI_ASSOC);
echo $option['Services'];
foreach($uoptions as $services) {
if(!empty($services['Services_ID'] == $option['ID'])){
echo " this is checked";
}
}
echo "<br>";
}
?>
Ik ben geneigd je gemakzuchtige vraag op slot te zetten, maar ik gun je graag nog een laatste kans.
Leg bijvoorbeeld uit waarom je voor deze oplossing hebt gekozen. Of waarom je vermoedt dat het beter kan.
Zie je zelf waar het fout kan gaan? En waarom?
- de eerste tab op elke regel voegt niets toe
- de PHP-sluit tag (?>) kan je beter vermijden
- variabelen die maar 1x gebruikt worden kunnen weg
- gemengd hoofdlettergebruik in variabele namen is verwarrend
- je code is onveilig op het gebied van SQL-injectie
- variabele definitie binnen for(each)-lus is onnodig traag
- SQL kan je beter in heredoc- of nowdow formaat in de code opnemen
- deze constructie is onduidelijk: if(!empty($services['Services_ID'] == $option['ID']))
Deze code heb ik niet kunnen testen, maar zo iets zou het kunnen zijn:
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?php
$stmt = $connect->prepare( <<<'EOQ'
SELECT
UserServices.Services_ID,
Services.Services
FROM UserServices
INNER JOIN Services
ON Services.ID = UserServices.Services_ID
WHERE UserServices.User_ID = ?
EOQ );
$stmt->bind_param('s', $_SESSION['ID']);
$stmt->execute();
$res = $stmt->get_result();
header('Content-type: text/plain'); // geen HTML nodig
$res = $connect->query($connect, 'SELECT * FROM Services ORDER BY ID');
foreach (mysqli_fetch_all($res, MYSQLI_ASSOC) as $option) {
echo $option['Services'];
foreach($res->fetch_array() as $services) {
if(!empty($services['Services_ID'] == $option['ID'])){
echo " this is checked";
}
}
echo PHP_EOL;
}
$stmt->free();
?>
$stmt = $connect->prepare( <<<'EOQ'
SELECT
UserServices.Services_ID,
Services.Services
FROM UserServices
INNER JOIN Services
ON Services.ID = UserServices.Services_ID
WHERE UserServices.User_ID = ?
EOQ );
$stmt->bind_param('s', $_SESSION['ID']);
$stmt->execute();
$res = $stmt->get_result();
header('Content-type: text/plain'); // geen HTML nodig
$res = $connect->query($connect, 'SELECT * FROM Services ORDER BY ID');
foreach (mysqli_fetch_all($res, MYSQLI_ASSOC) as $option) {
echo $option['Services'];
foreach($res->fetch_array() as $services) {
if(!empty($services['Services_ID'] == $option['ID'])){
echo " this is checked";
}
}
echo PHP_EOL;
}
$stmt->free();
?>
Vervolgens vergelijk je in PHP de uitkomsten van 2 SQL queries, terwijl de database daar veel beter in is. Dat kan ook in 1 query en scheelt de helft van de PHP-code.
Code (php)
1
2
3
4
5
6
2
3
4
5
6
SELECT * FROM Services ORDER BY ID
Select UserServices.Services_ID, Services.Services
FROM UserServices
INNER JOIN Services ON Services.ID
WHERE Services.ID = UserServices.Services_ID AND User_ID ='.$_SESSION['ID'].
Select UserServices.Services_ID, Services.Services
FROM UserServices
INNER JOIN Services ON Services.ID
WHERE Services.ID = UserServices.Services_ID AND User_ID ='.$_SESSION['ID'].
die 2e query is raar.
Dat zou ik schrijven als
Code (php)
1
2
3
4
2
3
4
Select UserServices.Services_ID, Services.Services
FROM UserServices
INNER JOIN Services ON Services.ID = UserServices.Services_ID
WHERE User_ID ='.$_SESSION['ID'].
FROM UserServices
INNER JOIN Services ON Services.ID = UserServices.Services_ID
WHERE User_ID ='.$_SESSION['ID'].
Maar is er een verband tussen die 2 query's?
Je voert eerst de eerste uit. Zeg dat daar 20 resultaten uitkomen.
Dan ga je in een loop 20x de 2e query uitvoeren?
En vervolgens test je de resultaten van de 2e query om alles te negeren dat niet de ID van de eerste query heeft.
Dat doe je dus liever in 1 query:
- is het onnodig om 2x met dezelfde tabel te joinen
- is de join conditie van de inner join onvolledig, die staat in de where als eerste
- moet er nog wel iets gedaan worden tegen SQL-injectie
- de logica in PHP voor weergave kan ook meteen in de SQL query
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
SELECT
CONCAT(Services.Services,
CASE WHEN UserServices.User_ID IS NOT NULL
THEN ' this is checked'
ELSE ''
END
) AS optie
FROM UserServices
LEFT JOIN Services
ON Services.ID = UserServices.Services_ID
AND UserServices.User_ID = ?
ORDER BY Services.ID
CONCAT(Services.Services,
CASE WHEN UserServices.User_ID IS NOT NULL
THEN ' this is checked'
ELSE ''
END
) AS optie
FROM UserServices
LEFT JOIN Services
ON Services.ID = UserServices.Services_ID
AND UserServices.User_ID = ?
ORDER BY Services.ID
Opmerking Ward gelezen?
Ward van der Put op 19/04/2023 19:03:48:
Het is hier geen afhaalbalie.
Ik ben geneigd je gemakzuchtige vraag op slot te zetten, maar ik gun je graag nog een laatste kans.
Leg bijvoorbeeld uit waarom je voor deze oplossing hebt gekozen. Of waarom je vermoedt dat het beter kan.
Zie je zelf waar het fout kan gaan? En waarom?
Ik ben geneigd je gemakzuchtige vraag op slot te zetten, maar ik gun je graag nog een laatste kans.
Leg bijvoorbeeld uit waarom je voor deze oplossing hebt gekozen. Of waarom je vermoedt dat het beter kan.
Zie je zelf waar het fout kan gaan? En waarom?
Ik snap dat jullie het goed bedoelen, maar laten we eerst even het antwoord van de TS (Arno) op de vragen van Ward afwachten.
Maar als je gewoon een goede tutorial volgt, dan weet je dat:
- escaping van je query belangrijk is
- het filteren van schadelijke tekens met htmlspecialchars() in je uitvoer belangrijk is.
- dat je beter met mysqli_fetch_assoc een result kan halen uit je database, en als je expliciet meerdere records hebt gebruik je while. De combinatie van mysqli_fetch_all en foreach() heb ik nooit eerder gezien.
- foutafhandeling zeer handig is.
- En verder zijn er nog meer tips gegeven. Doe er wat mee!!!!!!
Dus ik hoop dat de volgende topics van beter niveau zijn dan dit topic is. Ik laat deze open, maar ook ik zou bijna de neiging gekregen hebben om dit topic te sluiten.
Gewijzigd op 19/04/2023 23:33:09 door - Ariën -
Ward van der Put op 19/04/2023 19:03:48:
Het is hier geen afhaalbalie.
Ik ben geneigd je gemakzuchtige vraag op slot te zetten, maar ik gun je graag nog een laatste kans.
Leg bijvoorbeeld uit waarom je voor deze oplossing hebt gekozen. Of waarom je vermoedt dat het beter kan.
Zie je zelf waar het fout kan gaan? En waarom?
Ik ben geneigd je gemakzuchtige vraag op slot te zetten, maar ik gun je graag nog een laatste kans.
Leg bijvoorbeeld uit waarom je voor deze oplossing hebt gekozen. Of waarom je vermoedt dat het beter kan.
Zie je zelf waar het fout kan gaan? En waarom?
De code moet als volgt te werk gaan.
Kijk welke services is aangevinkt bij de des betreffende User, zet daar checked bij, is dit niet het geval, zet er dan niks achter.
In principe werkt het, echter bij een andere gebruiker is maar 1 services aangevinkt, maar zet bij 2 services een checked achter.
Dus dat ben ik aan het uitzoeken hoe dat kan, maar kan ook zijn dat hij de ID`s met User_ID en Services_ID verdraaid of vergelijkt.
Bij de andere gebruiker werkt het wel en staat alles gewoon goed.Vreemd genoeg snap ik even niet hoe dat weer kan.
En alles moet in een form terecht komen met checkboxen.
Klein voorbeeld hoe ik het nu heb.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<?php
/* Services & Options page */
if($_GET['menu'] == 'services' && $_GET['action'] == 'postservices') {
if(isset($_POST['submit'])) {
$test = $_POST['services'];
foreach($test as $mytest) {
$mysql = 'SELECT * FROM Services WHERE Services ="'.$mytest.'" ';
$result = mysqli_query($connect, $mysql);
while($cool = mysqli_fetch_object($result)) {
echo $cool->ID." - ".$mytest."<br />";
}
}
}
} else {
/* In this table are all the user_id`s with the corrensponding services_id */
$sql = 'SELECT * FROM Services ORDER BY ID';
$result = mysqli_query($connect, $sql);
$Options = mysqli_fetch_all($result, MYSQLI_ASSOC);
$checkbox = ">";
echo "<form action='index.php?menu=services&action=postservices' method='POST'>
<div class='services-grid'>";
foreach($Options as $option) {
$MySql = 'Select UserServices.Services_ID, Services.Services FROM UserServices INNER JOIN Services ON Services.ID WHERE Services.ID = UserServices.Services_ID AND User_ID ='.$_SESSION['ID'].';';
$myresult = mysqli_query($connect, $MySql);
$uoptions = mysqli_fetch_all($myresult, MYSQLI_ASSOC);
echo "<div class='services-item'><input type='checkbox' name='services[]' value='".$option['Services']."'".$checkbox, $option['Services']."</div>";
foreach($uoptions as $services) {
if(empty($services['Services_ID'] == $option['ID'])){
$checkbox = " checked>";
} else {
$checkbox = ">";
}
}
}
echo" </div>
<div class='button'><input type='submit' name='submit' value='Preview'></div>
</form>";
}
?>
/* Services & Options page */
if($_GET['menu'] == 'services' && $_GET['action'] == 'postservices') {
if(isset($_POST['submit'])) {
$test = $_POST['services'];
foreach($test as $mytest) {
$mysql = 'SELECT * FROM Services WHERE Services ="'.$mytest.'" ';
$result = mysqli_query($connect, $mysql);
while($cool = mysqli_fetch_object($result)) {
echo $cool->ID." - ".$mytest."<br />";
}
}
}
} else {
/* In this table are all the user_id`s with the corrensponding services_id */
$sql = 'SELECT * FROM Services ORDER BY ID';
$result = mysqli_query($connect, $sql);
$Options = mysqli_fetch_all($result, MYSQLI_ASSOC);
$checkbox = ">";
echo "<form action='index.php?menu=services&action=postservices' method='POST'>
<div class='services-grid'>";
foreach($Options as $option) {
$MySql = 'Select UserServices.Services_ID, Services.Services FROM UserServices INNER JOIN Services ON Services.ID WHERE Services.ID = UserServices.Services_ID AND User_ID ='.$_SESSION['ID'].';';
$myresult = mysqli_query($connect, $MySql);
$uoptions = mysqli_fetch_all($myresult, MYSQLI_ASSOC);
echo "<div class='services-item'><input type='checkbox' name='services[]' value='".$option['Services']."'".$checkbox, $option['Services']."</div>";
foreach($uoptions as $services) {
if(empty($services['Services_ID'] == $option['ID'])){
$checkbox = " checked>";
} else {
$checkbox = ">";
}
}
}
echo" </div>
<div class='button'><input type='submit' name='submit' value='Preview'></div>
</form>";
}
?>
Deels werkt het, maar bij de andere gebruiker waar maar 1 optie aangevinkt staat, zet hij bij 2 en 4 een checked achter, terwijl het alleen bij 2 moet zijn.
De andere gebruiker heeft 2 en 3 en daar staat wel alles goed met checked.
Dus er is iets in de code wat ik fout heb staan, maar ik zie het niet.
Gewijzigd op 20/04/2023 00:29:33 door - Ariën -
Probeer die stap in het vervolg eens te volgen. Zo weet je wat er gebeurt en komt dit niet over als een afhaalbalie opdracht. Ik hoor je nu alleen over aannames, en daar heb je niks aan.
We willen je hier echt niet weg hebben, maar ik denk dat je zo wel een gros van je topics kan besparen. Het begint namelijk wel op te vallen als je per week een grote hoeveelheid topics opent, en vaak opeens na korte tijd al het probleem opeens opgelost hebt.
Zie het forum niet als eerste redmiddel. Ga eerst debuggen, en in je hoofd of op papier redeneren wat er aan de hand is. Check ook php.net, benut var_dump, print_r en de echo's, en kijk wat er gebeurt. Vaak zul je zien dat een topic dan overbodig is.
Gewijzigd op 20/04/2023 00:37:59 door - Ariën -
Dat moet dus niet, ik heb alles met een echo nagekeken en daar zag ik dat de Services_ID gelijk is aan de $_SESSION['ID']. Hoe kan ik zorgen dat hij die niet vergelijkt?
Post even de code mee, die ik deels aangepast heb.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<?php
echo "<form action='index.php?menu=services&action=postservices' method='POST'>
<div class='services-grid'>";
$MySql = 'SELECT * FROM UserServices WHERE User_ID = '.$_SESSION['ID'].'';
$Myresult = mysqli_query($connect, $MySql);
$uoptions = mysqli_fetch_all($Myresult, MYSQLI_ASSOC);
$checkbox = ">";
foreach($uoptions as $services) {
$IDA = $services['ID'];
$USID = $services['User_ID'];
$SEID = $services['Services_ID'];
$sql = 'SELECT * FROM Services';
$result = mysqli_query($connect, $sql);
$Options = mysqli_fetch_all($result, MYSQLI_ASSOC);
foreach($Options as $option) {
$ID = $option['ID'];
$Serv = $option['Services'];
$SID = $option['Serv_ID'];
echo "<div class='services-item'><input type='checkbox' name='services[]' value='".$option['Services']."'".$checkbox, $option['Services']."</div>";
if($SID != $SEID) {
$checkbox = " checked>";
} else {
$checkbox = ">";
}
}
}
echo" </div>
<div class='button'><input type='submit' name='submit' value='Preview'></div>
</form>";
?>
echo "<form action='index.php?menu=services&action=postservices' method='POST'>
<div class='services-grid'>";
$MySql = 'SELECT * FROM UserServices WHERE User_ID = '.$_SESSION['ID'].'';
$Myresult = mysqli_query($connect, $MySql);
$uoptions = mysqli_fetch_all($Myresult, MYSQLI_ASSOC);
$checkbox = ">";
foreach($uoptions as $services) {
$IDA = $services['ID'];
$USID = $services['User_ID'];
$SEID = $services['Services_ID'];
$sql = 'SELECT * FROM Services';
$result = mysqli_query($connect, $sql);
$Options = mysqli_fetch_all($result, MYSQLI_ASSOC);
foreach($Options as $option) {
$ID = $option['ID'];
$Serv = $option['Services'];
$SID = $option['Serv_ID'];
echo "<div class='services-item'><input type='checkbox' name='services[]' value='".$option['Services']."'".$checkbox, $option['Services']."</div>";
if($SID != $SEID) {
$checkbox = " checked>";
} else {
$checkbox = ">";
}
}
}
echo" </div>
<div class='button'><input type='submit' name='submit' value='Preview'></div>
</form>";
?>
Eerlijk gezegd wordt dit gewoon vermoeiend. Zwaar vermoeiend!
Gewijzigd op 20/04/2023 09:17:38 door - Ariën -
Gewoon los van je php-script.
Die query kun je gewoon in een database-tool draaien. Bijvoorbeeld PhpMyadmin.
Ik was hierboven te slordig met de copy/paste, maar bottom line is dat deze info met 1 query opgehaald kan worden.
Zorg dat je dat eerst werkend hebt.
Je draait nu 2 query's, deels over dezelfde tabel, waarbij de 2e query vaak herhaald wordt. Naast dat dat extra werk voor php is, is dat ook onoverzichtelijk. (en zoals ook in een eerder topic al aangehaald en hierboven ook opgemerkt: je ON clause bevat normaal een vergelijking tussen 2 velden uit 2 tabellen. Niet 1 veld.
--
en voor je opmerking "het werkt voor 1 testcase, maar niet voor een andere"
los op: 2x2 = 4.
Mijn script klopt, want $antwoord = 2 + 2; geeft 4.
En het klopt ook voor 0.
Maar waarom werkt het niet voor 1 en 3??
Probeer niet blind te staren op dat het soms werkt. Dat kan een uitzondering zijn.
Heb er een hele nacht over geslapen en goed nagedacht, dit werkt deels.
Nu wil ik alles van de database in een array wegzetten en deze vergelijken met wat de user geselecteerd heeft.
Deels werkt, maar ik zit met een klein probleem.
output :
Yes => 2
Warning: Undefined array key "Schep" in /data/sites/web/[cut]/www/Users/inc/services.php on line 24
Yes => 3
Warning: Undefined array key "Paraplu" in /data/sites/web/[cut]/www/Users/inc/services.php on line 24
de code :
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?php
$Serving = array("1"=>"Emmer", "2"=>"Schep", "3"=>"Paraplu", "4"=>"Bril");
$Selection1 = $Serving['1'];
$Selection2 = $Serving['2'];
$Selection3 = $Serving['3'];
$Selection4 = $Serving['4'];
/*
echo $Selection1." => ".$Selection2." => ".$Selection3." => ".$Selection4;
*/
// Database where users has their selected services //
$MySql = 'SELECT * FROM UserServices WHERE User_ID = '.$_SESSION['ID'].'';
$Myresult = mysqli_query($connect, $MySql);
$uoptions = mysqli_fetch_all($Myresult, MYSQLI_ASSOC);
foreach($uoptions as $data => $value) {
$val = $value['Services_ID'];
$Uselct = array($data);
if($Uselct = $Serving) {
echo "Yes => ".$val."<br />";
}
if($val = $Serving[$val]) {
$gotcha = $Serving[$val]; // <= hier zit het probleem in, hoe los ik dat op?
echo $gotcha."<br />";
}
/* echo"<pre>";
print_r($Uselct);
echo"</pre>";
*/
}
?>
$Serving = array("1"=>"Emmer", "2"=>"Schep", "3"=>"Paraplu", "4"=>"Bril");
$Selection1 = $Serving['1'];
$Selection2 = $Serving['2'];
$Selection3 = $Serving['3'];
$Selection4 = $Serving['4'];
/*
echo $Selection1." => ".$Selection2." => ".$Selection3." => ".$Selection4;
*/
// Database where users has their selected services //
$MySql = 'SELECT * FROM UserServices WHERE User_ID = '.$_SESSION['ID'].'';
$Myresult = mysqli_query($connect, $MySql);
$uoptions = mysqli_fetch_all($Myresult, MYSQLI_ASSOC);
foreach($uoptions as $data => $value) {
$val = $value['Services_ID'];
$Uselct = array($data);
if($Uselct = $Serving) {
echo "Yes => ".$val."<br />";
}
if($val = $Serving[$val]) {
$gotcha = $Serving[$val]; // <= hier zit het probleem in, hoe los ik dat op?
echo $gotcha."<br />";
}
/* echo"<pre>";
print_r($Uselct);
echo"</pre>";
*/
}
?>
Gewijzigd op 20/04/2023 17:11:07 door Arno van Zanten
Verder word ik moe van de afhaalbalie-vragen die je zo kan googlen. Lees de tips eens!
Dit topic gaat dicht.