Waarde buiten de foreach opvragen
Ik gebruik onderstaande voorbeeld array op meerdere locaties in mijn script.
Op 1 locatie wil ik iets toevoegen en wil daarvoor een foreach gebruiken.
Code (php)
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
$array = array(
"form_name" => "Naam",
"form_email" => "E-mail",
"form_subject"=> "Onderwerp"
);
foreach($array as $key => $value) {
$output = 'Label: ' . $value;
};
echo $output;
"form_name" => "Naam",
"form_email" => "E-mail",
"form_subject"=> "Onderwerp"
);
foreach($array as $key => $value) {
$output = 'Label: ' . $value;
};
echo $output;
Dit echoot alleen de laatste waarde "Label: Onderwerp" uit.
Hoe echo ik overige waarden?
Ik dacht zelf:
Maar helaas werkt dit niet.
Guido
Bedankt voor je reactie.
Maar bedoel je dus dat ik de overige waarden niet buiten de foreach kan aanroepen?
Kun je me uitleggen hoe ik de $output naar een array kan "omzetten"?
Guido
Code (php)
Maar het komt een beetje dubbel over wat je precies wilt bereiken.
Wat wil je precies met die array in $output dan doen?
Gewijzigd op 20/08/2018 15:03:26 door - Ariën -
Het was een voorbeeld array, in werkelijkheid betreft het een contact formulier:
Code (php)
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
$array = array(
'form_name' => $_POST['name'],
'form_email' => $_POST['email'],
'form_subject' => $_POST['subject']
);
$output = array();
foreach($array as $key => $value) {
$output[] = preg_replace( '/\\\\/', '', $value );
};
'form_name' => $_POST['name'],
'form_email' => $_POST['email'],
'form_subject' => $_POST['subject']
);
$output = array();
foreach($array as $key => $value) {
$output[] = preg_replace( '/\\\\/', '', $value );
};
Wil alle backslashes dus strippen middels de foreach en de $output gebruiken voor de value van mijn input velden. Hoopte het bv zo te kunnen doen:
Guido
Gewijzigd op 20/08/2018 16:00:21 door Guido -
Quote:
Kun je me uitleggen hoe ik de $output naar een array kan "omzetten"?
Maar je oorspronkelijke $array is toch al een array? :/
Waarom zou je een nieuw array bakken?
Quote:
Wil alle backslashes dus strippen middels de foreach en de $output gebruiken voor de value van mijn input velden. Hoopte het bv zo te kunnen doen
Wat wil je hier uiteindelijk mee bereiken? Het aanpassen van input is zelden tot nooit de oplossing.
Als iets aan een bepaalde vorm dient te voldoen controleer je dit in de validatie van het formulier, maar je past de
invoer bij voorkeur niet aan. Voldoet de invoer niet aan je eisen geef je deze terug aan de gebruiker (zoals ie die aanleverde) met de mededeling dat de invoer gefixt moet worden.
Als je wilt voorkomen dat er HTML ingevoerd kan worden / het formulier wordt gebroken door speciale karakters dan kun je je beter bedienen van output escaping met functies zoals htmlspecialchars().
Maar eerst is het handig als je vertelt wat je nu eigenlijk probeert te bereiken :p.
Onderneem je met die bovenstaande preg_replace() een poging om invoer veilig(er) te maken? Dan zijn er andere en waarschijnlijk betere manieren om dit te doen.
In de mail die ik krijg staat een backslash achter (dubbele) aanhalingstekens en die wil ik eruit halen. Dus als iemand "Guido's" heeft ingetypt wordt het in het formulier als "Guido\'s" afgedrukt. Hetzelfde gebeurt in het formulier op mijn website, na drukken op submit. Mijn ervaring was dat stripslashes() niet altijd alle backslashes weghaalt dus vandaar deze poging. Misschien wat te veel vh goede?
Guido
Gewijzigd op 20/08/2018 16:50:30 door Guido -
Er schieten mij twee dingen te binnen die aan de hand kunnen zijn, en beide zijn onwenselijk:
- de PHP versie waar deze functionaliteit op draait is ouder dan versie 5.4, voor deze versie bestond er namelijk iets dat magic_quotes heette, dit voegde automagisch backslashes toe aan quotes. Dit werd vaak verkeerd gebruikt voor security redenen en was daar eigenlijk ook nooit voor bedoeld
- er is een of andere functie actief die in eerste instantie de backslashes toevoegt, waarschijnlijk met gebruikmaking van addslashes() of wellicht een real_escape_string() functie? De eerste is niet echt nodig voor een e-mail en de tweede is de verkeerde plek (context) om die functie te gebruiken
- EDIT: en mogelijk nog een derde: mogelijk kwamen deze tekstpassages met teveel slashes uit de database, waar ze in eerste instantie met extra slashes waren opgeslagen? ook dit principe (het op voorhand escapen, of ook wel escape-on-input) is vrijwel nooit een goed idee
Je moet het zo zien: in bepaalde contexten (HTML, SQL et cetera) zijn er bepaalde karakters die een bepaalde betekenis hebben. Zo heb je in HTML bijvoorbeeld de < punthaken >, de ampersand (&) en " dubbele quotes ". Om deze karakters onschadelijk te maken zijn er functies die deze karakters ontdoet van hun speciale betekenis binnen die context. Dit wordt ook wel output escaping genoemd.
Het klinkt alsof je deze methodiek aan moet wenden om je probleem op te lossen en ook loont het waarschijnlijk de moeite om de verschillende verkeerde manieren om output te escapen (zoals het sec toevoegen van backslashes) uit je applicatie te verwijderen.
stripslashes() bestrijdt alleen maar het symptoon van "teveel backslashes", het is beter om de achterliggende oorzaak die voor de overvloed aan backslashes zorgt te identificeren en weg te nemen. Waarschijnlijk komen er tijdens het identificatieproces nog wel wat andere skeletten uit de kast vallen :).
Gewijzigd op 20/08/2018 17:23:49 door Thomas van den Heuvel
De achterliggende oorzaak is helaas simpel.. dit doet WordPress bij $_POST.. blijkbaar zelfs anno 2018 nog. Escapen doe ik al. Maar omdat mijn vraag daar niet over ging, heb ik dat achterwege gelaten in mijn voorbeeld ;-)
Weet je, ik laat de hele foreach anders maar achterwege en gebruik striplashes() na escapen.
Of andersom, eerst striplashes() en dan pas escapen?
Guido
Ook al is het volgende een gedrocht en borduurt het voort op een achterhaald principe, wellicht is dit iets?
https://codex.wordpress.org/Function_Reference/stripslashes_deep (< 2 minuten Googlen)
EDIT: escapen doe je altijd aan het einde, vlak voor verwerking / weergave.
Gewijzigd op 20/08/2018 19:56:10 door Thomas van den Heuvel
Bedankt voor jullie reacties.
Guido
Ik heb de discussie niet gevolgd en misschien heeft iemand dit al uitgelegd, maar in je for-each loop overschrijf je keer op keer de waarde van $output. Uiteindelijk zie je om die reden alleen de laatst overschreven waarde.
Probeer voor de grap in plaats van deze regel in jouw code:
$output = 'Label: ' . $value;
maar eens deze regel ...
$output .= 'Label: ' . $value . '<br>';
Let op de . voor het = teken. In plaats van dat je de waarde nu overschrijft, vul je hem aan.
Je kunt alles wel aan elkaar rijgen in een nieuwe variabele, maar waarom zou je dit doen, je kunt ook meteen de value weergeven, hier hoef je niet eens een nieuwe variabele voor te introduceren. En de vraag is ook waarom dit gedaan wordt, mogelijk voor debugging?
Los daarvan, wat hierboven allemaal gebeurt is waarschijnlijk al een verkeerde insteek voor dat specifieke probleem. En dan doet WordPress nog allerlei vage dingen :/.
Gewijzigd op 21/08/2018 01:23:12 door Thomas van den Heuvel
Zoals ik al zei heb ik de discussie niet gelezen. Wilde alleen even uitleggen wat er gebeurt ... en hoe hij wel alle output in een variabele kan stoppen. Puur ter lering ende vermaak :-) ... en dus niet met de insteek om te bepalen of dat een goede oplossing is.
Soms is het ook leuk om mensen te motiveren en ze (wellicht) een Eureka-momentje te bezorgen :)
Zo is het inderdaad wel. Ook al werk ik al jaren met PHP, ik krijg het maar niet goed onder de knie. Dus een simpele uitleg is meestal gewenst. Die heb ik nu. Natuurlijk ben ik vóór mijn bericht hier eerst zelf al op zoek gegaan naar een antwoord op mijn vraag, maar die nergens gevonden. En soms denk je het op een bepaalde manier goed te doen en moet je er door een ander op gewezen worden dat je juist niet goed bezig bent ;-) Zoals in dit geval.
Bedankt weer!
Guido
Code (php)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
<?php
ob_start(); // start output buffering
foreach ($array as $value) {
// misschien hier ook nog wat output escaping op $value toepassen als je dit in een HTML context gebruikt
?>Label: <?php echo $value; ?><br><?php
echo "\n"; // voor leesbaarheid
}
$output = ob_get_clean();
?>
ob_start(); // start output buffering
foreach ($array as $value) {
// misschien hier ook nog wat output escaping op $value toepassen als je dit in een HTML context gebruikt
?>Label: <?php echo $value; ?><br><?php
echo "\n"; // voor leesbaarheid
}
$output = ob_get_clean();
?>
Uiteraard is de meerwaarde bij zo'n klein snippet nou niet bepaald groot.
En omdat dit waarschijnlijk debugging betrof, is het misschien beter om hier wat functies voor te introduceren zodat dit herbruikbaar is, in plaats van elke keer dezelfde code te kloppen om een array te dumpen.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
// shorhand voor escaping in HTML-context
function escape($in) {
return htmlspecialchars($in, ENT_QUOTES, 'UTF-8');
}
// voor veilige dump van data (arrays, strings, whatever) in de HTML-context
function dump($in) {
if (is_array($in)) {
$in = print_r($in, true);
}
echo '<pre>'.escape($in).'</pre>';
}
?>
// shorhand voor escaping in HTML-context
function escape($in) {
return htmlspecialchars($in, ENT_QUOTES, 'UTF-8');
}
// voor veilige dump van data (arrays, strings, whatever) in de HTML-context
function dump($in) {
if (is_array($in)) {
$in = print_r($in, true);
}
echo '<pre>'.escape($in).'</pre>';
}
?>
Dan kun je simpelweg volstaan met: