Met onderstaande code is het me als beginneling (na veel tips van anderen) toch gelukt om via de adresbalk het aantal zichtbare foto's op mijn webpagina te variëren.

<?php

$aantal = 2;
$photos = glob('img/*.jpg');

if (isset($_GET['aantal']))
{
$aantal = (int) $_GET['aantal'];
}

if (!is_int($aantal) || $aantal < 1 || $aantal > count($photos))
{
$aantal = count($photos);
}

for($getal = 1; $getal <= $aantal; $getal++)
{
echo '[ul]';
echo '[li][img src="img/photo' . $getal . '.jpg"][/li]';
echo '[/ul]';
}

?>

De code wordt middels een 'include('photos.php');' binnen een divje van de [main][/main] geplaatst.

In de adesbalk staat nu bijvoorbeeld:
localhost/album.php?aantal=5

En als ik in plaats van ?aantal=5 invul ?aantal=14, dan zie je niet 5 foto's, maar 14 foto's netjes geordend.

Nu wil ik mijn webpagina zowel Nederlandstalig als Franstalig hebben. Dus heb ik dit PHP-bestand bedacht.

<?php

$drapeaux = array
(
array
(
'href' => 'album.php?lang=fr',
'content' => '[img src="images_2/fr.png" title="fran&ccedil;ais"]',
'target' => '_self',
'seq' => 1,
),
array
(
'href' => 'album.php?lang=nl',
'content' => '[img src="images_2/nl.png" title="Nederlands"]',
'target' => '_self',
'seq' => 2,
),
);

echo '<ul>';
foreach ($drapeaux as $key => $value)
{
$class = '';
if ($value['href'] == basename($_SERVER['REQUEST_URI']))
{
$class = 'visited';
}
echo '[li][a class="' .$class. '" href="' .$value['href']. '" target="' .$value['target']. '"]' .$value['content']. '[/a][/li]';
}
echo '[/ul]';

?>

Deze code wordt via 'require_once('drapeaux.php');' binnen de header opgeroepen.

Als ik op een vlaggetje klik, dan komt er in de adresbalk bijvoorbeeld te staan:
localhost/album.php?lang=nl

In de adresbalk rechtstreeks of via het andere vlaggetje kan ik er van maken:
localhost/album.php?lang=fr

In de CSS heb ik volledige opacity gegeven aan het actieve vlaggetje en beduidend verminderde opacity aan het vlaggetje dat even niet meedoet.

Ik weet nog niet hoe ik in mijn code ook kan aangeven dat je effectief naar bijvoorbeeld het volgende adres gaat:
localhost/album/fr.php?lang=fr

Een bestand met de naam 'album/fr.php' wordt als ongeldig gezien wegens het slash-teken.
Dus als iemand een tip heeft om de taalparameter ?lang=... ook echt te koppelen aan een anderstalige pagina... ???

Beide $_GET parameters functioneren apart gebruikt zoals verwacht. Maar als ik ze in de adresbalk combineer, worden de vlaggetjes allebei transparant, terwijl de taal-parameter nog wel in de adresbalk staat:
localhost/album.php?lang=fr&aantal=4
of
localhost/album.php?aantal=4&lang=fr

De volgorde maakt dus niet uit. Alleen de parameter voor het aantal foto's blijft correct het gekozen aantal foto's tonen.

Mijn vraag is nu: hoe kan ik de codes zo aanpassen, dat er geen conflict meer tussen de $_GET parameters blijft bestaan? En dat dus ook bij het actieve vlaggetje de transparantie wegblijft.
• Waar lees je $_GET['lang'] uit?
• Hoe sla je de gekozen taal op?
• Hoe bepaal je de taal als de gebruiker nog niets heeft gekozen?

Probeer in je code een antwoord te formuleren op die drie vragen en je hebt een goed werkend geheel.
Heb je misschien meerdere foto's in de map img zitten?
Een bestand met de naam 'album/fr.php' wordt als ongeldig gezien wegens het slash-teken.

Als je een script "fr.php" hebt in de subdirectory "album" van je webdirectory dan zou dit gewoon moeten werken.

Maar als ik ze in de adresbalk combineer, worden de vlaggetjes allebei transparant, terwijl de taal-parameter nog wel in de adresbalk staat:
localhost/album.php?lang=fr&aantal=4
of
localhost/album.php?aantal=4&lang=fr

Ook hier is geen speciale reden dat dit niet zou werken, omdat je in principe niets vreemds doet.

Ik vermoed dat in beide gevallen iets misgaat in code bij het matchen van gegevens. Volg de tips van @Ward om na te gaan waar het schip precies strandt.
Neen, in de map img zitten alleen de foto's die voor deze plek van de webpagina zijn bedoeld.
Ik denk dat ik $_GET['lang'] moet uitlezen in het bestand album.php:

<?php
	$taal = 'nl';

	if(isset($_GET['lang']))
	{
		$taal == $_GET['lang'];
	}
	else
	{
		$taal == 'nl';
	}

?>

Er verandert overigens niets in de uitwerking. Bovendien wordt hier wel een variable $taal gedefinieerd, maar vervolgens komt die variable nergens in de code terug. Dus heeft deze toevoeging niet echt veel betekenis.

Bij het aanroepen van de pagina: localhost/album.php wordt de $_GET['lang'] parameter niet in de adresbalk geafficheerd en blijven beide vlaggetjes dus transparant. Pas door toevoeging van ?lang=fr wordt het Franse vlaggetje volledig zichbaar, maar blijf ik nog steeds op dezelfde pagina.

Ik vermoed dat hetgeen ik beoog te bereiken met de webpagina voor PHP-ingewijden in het geheel niet ingewikkeld is. Maar voor een beginner geeft het standaard cursusmateriaal waarin losse PHP-elementen worden gepresenteerd geen handvatten om verder te bouwen. Waarom bestaat er geen boek of handleiding waarin de manier van coderen die hier nodig is aan de hand van voorbeelden duidelijk wordt uitgelegd. Binnen een formulier met een submit-knop lukt het me wel om meertaligheid te krijgen. Maar de $_GET parameter hoort toch ook te werken buiten een formulier om?

<?php
    if(isset($_GET['lang'])) {
		$taal = $_GET['lang'];
	} else {
		$taal = 'nl';
	}

    if(isset($_GET['nomen'])) {
		$nomen = $_GET['nomen'];
	}
?>

<!DOCTYPE html>
<html lang="<?php echo $taal; ?>-NL">
	<head>
		<title>Meertaligheid - 02</title>
		<meta charset="UTF-8">
	</head>
	<body>
		<div id="container">

			<a href="talen.php?lang=nl"><img src="nl.png"></a>
			<a href="talen.php?lang=en"><img src="gb.png"></a>
			<a href="talen.php?lang=de"><img src="de.png"></a>
			<a href="talen.php?lang=fr"><img src="fr.png"></a>
			
			<form action="talen.php" method="GET">
				<label for="naam">Vul een willekeurige naam in</label>
				<input type="text" name="nomen" id="naam">
				<input type="hidden" name="lang" value="<?php echo $taal; ?>">
				<input type="submit" name="activeer" value="genereer">
			</form>
<?php

	if(isset($_GET['activeer'])) {
		if (!empty($_GET['nomen'])) {
			if($taal == 'nl') {
				echo '<h1>Welkom, '.$nomen.' !</h1>';					
			} elseif ($taal == 'en') {
				echo '<h1>Welcome, '.$nomen.' !</h1>';
			} elseif ($taal == 'de') {
				echo '<h1>Willkommen, '.$nomen.' !</h1>';
			} elseif ($taal == 'fr') {
				echo '<h1>Bienvenue, '.$nomen.' !</h1>';
			}
		} else {			
			if($taal == 'nl') {
				echo '<h1>U heeft nog geen naam gekozen</h1>';					
			} elseif ($taal == 'en') {
				echo '<h1>You have not chosen a name yet</h1>';
			} elseif ($taal == 'de') {
				echo '<h1>Sie haben noch keinen Namen gewählt</h1>';
			} elseif ($taal == 'fr') {
				echo '<h1>N\'oubliez pas de choisir un pr&eacute;nom</h1>';
			}
		}
	}
	
?>
		</div>
	</body>
</html>

De vragen die Ward van der Put vanuit didactisch oogpunt aan mij retourneert, leiden bij mij althans niet tot evidente en concrete antwoorden. In het Frans zeggen wij dan: "Je nage et je tourne en rond!" Als complete neofiet zie ik geen enkel aanknopingspunt om in de code verder te komen.

Er blijven nogal wat vragen over:
1 Hoe ga ik effectief naar een anderstalige pagina via ?lang=... ? Is daar op enige plek een begrijpelijke uitleg voor te vinden?
2 Waarom wordt de default-taal niet herkend door de startpagina? Hoe zorg ik trouwens dat bijvoorbeeld het Nederlands effectief de default-taal is?
3 Wat is er nodig om de onverzoenbaarheid tussen ?lang=... en ?aantal=... te doen ophouden?

Voor alle duidelijkheid: ik vraag niet om een compleet uitgetekende code. Maar een aanwijzing als "Gebruik dit of dat PHP-element eens in een apart PHP-bestand met zus of zo naam en laat dan eens zien hoe je dat hebt opgeschreven" kunnen mij misschien een stapje verder helpen?


1. zoals iedere ander link (of begrijp ik je vraag niet goed?)

2. De defaulttaal is een instelling. Het punt is dat je je programma al flink aan het uitbouwen bent terwijl je nog een goede structuur mist. 1 onderdeel van een goede structuur is een config bestand waarin je alle instellingen bewaard. Dit is makkelijk als je later iets wilt wijzigen en veel overzichtelijker.

<?php
// config/config.php

$config = array(
'defaultLanguage' => 'nl',
'acceptedLanguages' => array('nl', 'fr'),
/* en zo nog veel meer variabelen*/
);

?>

De volgende logische stap is checken of $_GET['lang'] bestaat en of deze een GELDIGE WAARDE heeft. Zo niet dan schakel je over op $defaultLanguage. Deze check doe je op iedere pagina, inclusief je index pagina en dus ga je deze code niet apart op elke pagina zetten. Je zult hiervoor een functie moeten gaan maken.

<?php
// libraries/LanguageFunctions.php

function getCurrentLanguage($defaultLanguage, $acceptedLanguages)
{
if(isset($_GET['lang']))
{
$lang = strtolower($_GET['lang']);

if(in_array($lang, $acceptedLanguages))
{
// indien de taal in de url een geldige waarde heeft verlaat de functie en geef deze taal terug
return $lang;
}
}

// anders verlaat de functie en geef de defaulttaal terug
return $defaultLanguage;
}

?>

Dan zou ik voor iedere taal een een translation.xx.php aanmaken:
<?php
// config/translation.nl.php

$trans = array(
'homepage' => array(
'title' => 'Welkom',
'noname' => 'U heeft nog geen naam gekozen',
/* en zo nog veel meer variabelen*/
),
'about' => array(
'title' => 'Over ons',
/* en zo nog veel meer variabelen*/
),
);

?>


Op iedere landingspagina (bijv. index.php) krijg je nu:

<?php
require_once 'config/config.php';
require_once 'libraries/LanguageFunctions.php';

$language = getCurrentLanguage($config['defaultLanguage'], $config['acceptedLanguages']);

require_once 'config/translation.'.$language.'.php';

?>
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title><?php echo $trans['homepage']['title']; ?></title>
    </head>
    <body>
        ...
    </body>
</html>



[size=xsmall]Toevoeging op 25/10/2017 23:29:22:[/size]

Je mappen structuur:

  |
  |-- [config]
  |      |
  |      |-- config.php
  |      |-- translation.fr.php
  |      |-- translation.nl.php
  |
  |-- [libraries]
  |      |
  |      |-- LanguageFunctions.php
  |
  |
  |-- index.php
  |
  |-- about.php


Punt 3:
>> 3 Wat is er nodig om de onverzoenbaarheid tussen ?lang=... en ?aantal=... te doen ophouden?

Het antwoord is goede structuur en vaste variabelen. Je zult de variabele $language nodig hebben voor ieder URL die je maakt en $aantal ook voor de pagina met de plaatjes.
voorbeeld:

<a href="index.php?lang=<?php echo $language; ?>&aantal=<?php echo $aantal; ?>">homepage</a>


[size=xsmall]Toevoeging op 25/10/2017 23:51:10:[/size]

p.s. Dit alles is nog zeer BASIC, bedoeld om je op weg te helpen. Hopelijk brengt het je op nieuwe ideeën en of meer inzicht. Perfect is het nog niet

[size=xsmall]Toevoeging op 26/10/2017 00:22:47:[/size]

[edit]

Ik denk dat ik vraag 1 ook begrijp: Veranderen van taal zonder dat mijn GET variabelen verloren gaan.

zoiets?
<?php
// toevoegen aan LanguageFunctions.php
function getLanguageLinks($acceptedLanguages)
{
$get = $_GET; // kopieer de hele $_GET array
$links = array(); // netjes initialiseren.

foreach ($acceptedLanguages as $lang)
{
$get['lang'] = $lang; // overschrijf het 'lang' element met de taal waar we mee bezig zijn
$links[$lang] = '<a href="'.$_SERVER['PHP_SELF'].'?'.http_build_query($get).'"><img src="/images/vlag_'.$lang.'.png"></a>';
}

// geef een array met links voor elke taal terug
return $links;
}

?>

en dan in je html:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title><?php echo $trans['homepage']['title']; ?></title>
    </head>
    <body>
        <ul class="language-flags">
            <?php foreach(getLanguageLinks($config['acceptedLanguages']) as $link): ?>
                <li><?php echo $link; ?></li>
            <?php endforeach; ?>
        </ul>
    </body>
</html>


Met http_build_query() zal het hele querystring gedeelte opnieuw opgebouwd worden waarin alle oude waardes uit $_GET overgenomen worden behalve de taal. Die wijst naar een andere taal.
een querystring is bijvoorbeeld: lang=nl&aantal=12
<?php
$taal = 'nl';

if(isset($_GET['lang']))
{
    $taal == $_GET['lang'];
}
else
{
    $taal == 'nl';
}
?>

Let op: met == vergelijk je twee waarden, met = ken je een waarde aan een variabele toe. Bovenstaande snippet levert dus altijd 'nl' op als waarde van $taal, ongeacht wat in $_GET['lang'] staat.

[color=#ff0000]EDIT: Dit had je in zekere zin al zelf vast kunnen stellen als je hierna $taal had weergegeven op je scherm. Dan had je meteen gezien dat $_GET['lang'] niet altijd correct wordt overgenomen.[/color]

Daarnaast is het inderdaad handig om een soort van whitelisting te gebruiken. Oftewel, je stelt een lijst van toegestane waarden -in dit geval talen- op, en je kijkt of $_GET['lang'] een geldige waarde bevat en anders schakel je terug naar een (geldige) default.

Ook is het handig om een soort van taal-mapping te hebben (of wellicht zou je kunnen denken aan afzonderlijke templates of HTML-snippets per taal) zodat je niet voor elk taalspecifiek stuk tekst een if-elseif-elseif-else statement hoeft te introduceren.

Sidenote aan @Frank: zorg dat je in je HTML je entiteiten escaped --> &amp; in plaats van & in je hyperlinks. Makkelijkste manier is meestal om de hele URL te escapen middels htmlspecialchars(), waarbij je querystringparameterwaarden eigenlijk ook zou moeten urlencoden.
Sidenote #2: het is handiger om eerst je meta-tag in je head te zetten, en dan pas je title-tag, omdat laatstgenoemde UTF-8 kan bevatten. Beter is wellicht nog om in de plaats hiervan, of hiernaast, een header mee te sturen met de gebruikte character encoding.
@thomas,

Sidenote #1: Ik heb hier mijn twijfels of ik jou goed begrijp? Zou je misschien een voorbeeldje kunnen oplepelen?
Sidenote #2: Hier heb je helemaal gelijk, een gevalletje van copy & paste. Ik pas dat even aan in bovenstaande post(s).
Hm, heb nog even zitten zoeken, maar misschien is het niet echt meer nodig (lees: verplicht), maar het wordt nog steeds aangeraden om (i.h.a.) ampersands (en andere speciale karakters) te escapen. Ook in URL's. Daarbij verdienen querystringparameterwaarden nog wat meer aandacht omdat je daar binnen een URL-context werkt binnen de HTML-context. Net zoals er tekens zijn die een speciale betekenis hebben binnen HTML zijn er (nog andere) tekens die een speciale betekenis hebben in een URL. Nu is het niet handig om deze te gaan gebruiken als je de keuze hebt, maar deze keuze heb je niet altijd.

Dus goed:
<a href="lala.php?a=1&b=2">hoi</a>

Beter:
<a href="lala.php?a=1&amp;b=2">hoi</a>

(plus als je XML of derivaat gebruikt is het nog steeds verplicht :p)

Vergelijk escaping met het dragen van een autogordel. Jij mag dan misschien geen ongelukken maken in het verkeer, maar dat wil niet zeggen dat het verkeer daarmee veilig(er) is (of wordt). Ook wil je niet elke keer de afweging maken. Gebruik gewoon altijd een autogordel.

Plus, het is gewoon een goede gewoonte om output te escapen. Het probleem wanneer je een gevalsonderscheid gaat maken (wat escape ik wel, wat escape ik niet) is dat hier tijd in gaat zitten en het soms niet duidelijk is of het bewust niet wordt gedaan of dat het per ongeluk vergeten is. Het is gewoon veel makkelijker om alles consequent te escapen. Eigenlijk zou dit dus altijd moeten gebeuren met *alle* dynamische output (ook al komen deze dynamische delen uit een taalbestand - het is gewoon vele malen simpeler om alle output hetzelfde te behandelen), tenzij je een expliciete reden hebt om niet te escapen, bijvoorbeeld omdat je HTML-snippets invoegt ofzo (maar dan is je aanpak wellicht niet echt handig).

meer
nog meer
etc.
>> <a href="lala.php?a=1&amp;b=2">hoi</a>

Volgens mij gebruik je &amp; alleen als onderdeel van een string en niet als scheidingsteken van parameters?
Het is alweer even geleden dat ik een validatieservice van W3C heb gebruikt, maar op elke plek waar je binnen HTML & niet laat volgen door amp; begint de validator te melken over "unescaped entities" of wat dan ook. Bij mijn weten is het dan ook overal verplicht (of i.i.g. verdient de sterke voorkeur), ook (en eigenlijk in het bijzonder) binnen hyperlinks.

EDIT: mogelijke uitzondering: hyperlinks in javascript, maar: andere context, andere spelregels :p

Reageren