$_Cookie voor geselecteerde taal

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Pagina: 1 2 volgende »

Donald Boers

Donald Boers

30/09/2018 10:03:58
Quote Anchor link
Ik loop een beetje vast met op welk moment ik een Cookie moet zetten voor een geselecteerde taal (drie talige website) met het gebruik van AltoRouter. De situatie is momenteel als volgt. In mijn controller file heb ik momenteel het volgende:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
$lang  = filter_input(INPUT_GET, 'lang');
$route = filter_input(INPUT_GET, 'route');

if ( !$lang ) {
    if ( isset($_COOKIE["language"]) ) {
        $lang = $_COOKIE["language"];
    } else {
        $lang = 'nl';
    }
    header("Location: /$lang/$route");
}

Met andere woorden als $_Cookie{"language"] bestaat (nl, en, de) dan dient de uitgangs- taal (bij een tweede bezoek) de waarde van het Cookie te zijn (www.website.com/de/ of een van de andere twee), bestaat het Cookie nog niet zet de taal dan op Nederlands (www.website.com/nl/).

In de navigatie wil ik graag een taal dropdown hebben waar de Cookie taal de link voor de dropdown is:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php if (!isset($_COOKIE["lang"]) || isset($_COOKIE["lang"]) && $_COOKIE["lang"] == 'nl' ): ?>
<li class="nav-item dropdown">
    <a id"languageDropdown" class="nav-link dropdown-toggle" href="#" data-toggle="dropdown">
        <img src="/images/flaggs/nl.png">&nbsp;&nbsp;Nederlands
    </a>
    <div class="dropdown-menu" aria-labelledby="languageDropdown">
        <a href="/en<?php echo $current_route?>" class="dropdown-item">
            <img src="/images/flaggs/uk.png">&nbsp;&nbsp;English
        </a>
        <a href="/de<?php echo $current_route?>" class="dropdown-item">
            <img src="/images/flaggs/de.png">&nbsp;&nbsp;Deutsch
        </a>        
    </div>
</li>
<?php elseif(isset($_COOKIE["lang"]) && $_COOKIE["lang"] == 'en'): ?>    
    // Zelfde als boven met Engels als uitgangs taal    
<?php elseif(isset($_COOKIE["lang"]) && $_COOKIE["lang"] == 'de'): ?>
    // Zelfde als boven met Duits als uitgangs taal
<?php endif; ?>


Ik kom er alleen niet uit op welk moment en waar ik het best het Cookie kan zetten. Zit me nu al een uur of wat rot te tobben. Iedere hulp zou ik zeer op prijs stellen.





Toevoeging op 30/09/2018 18:11:46:

Ik heb dit op de volgende wijze opgelost:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
$lang  = filter_input(INPUT_GET, 'lang');
$route = filter_input(INPUT_GET, 'route');

if ( !$lang ) {
    if ( isset($_COOKIE["language"]) ) {
        $lang = $_COOKIE["language"];
    } else {
        $lang = 'nl';
    }
    header("Location: /$lang/$route");
} else {
    $lang = (string)$lang;
    setcookie( 'language', $lang, time() + 60*60*24*365, '/' );    
}

En dat werkt prima. Het enige probleem dat ik nu nog ondervind is de content voor de dropdown niet wijzigd, althans niet met gebruik van de header("Location") Als iemand bijvoorbeeld Engels kies veranderd de waarde van het Cookie naar en maar de nederlandse vlag met bijbehorende tekst blijven staan.
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
<img src="/images/flaggs/nl.png">&nbsp;&nbsp;Nederlands

Als ik daarna de pagina handmatig ververs veranderd de content wel naar de engelse versie:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
<img src="/images/flaggs/uk.png">&nbsp;&nbsp;English

Hoe zou ik dit kunnen oplossen? Alvast bedankt
Gewijzigd op 30/09/2018 10:11:38 door Donald Boers
 
PHP hulp

PHP hulp

29/03/2024 10:18:33
 
Thomas van den Heuvel

Thomas van den Heuvel

30/09/2018 21:11:02
Quote Anchor link
In je controller, voordat je een header verstuurt?

Achter zo'n header moet trouwens nog steeds een exit-statement, want het instellen van een Location header transporteert je niet direct naar de nieuwe locatie (interne link).

En dan moet je wellicht nog rekening houden met dat geneuzel dat de gebruiker expliciet moet instemmen met het gebruik van cookies om je site fatsoenlijk te laten werken.
 
Donald Boers

Donald Boers

01/10/2018 10:50:48
Quote Anchor link
@Thomas. Hartelijk bedankt voor je reactie

Thomas van den Heuvel op 30/09/2018 21:11:02:
In je controller, voordat je een header verstuurt?

Wat bedoel je precies met het bovenstaande?
Thomas van den Heuvel op 30/09/2018 21:11:02:
Achter zo'n header moet trouwens nog steeds een exit-statement, want het instellen van een Location header transporteert je niet direct naar de nieuwe locatie (interne link).

Bedankt voor je opmerkzaamheid. Ik heb het meteen aangepast!

Thomas van den Heuvel op 30/09/2018 21:11:02:
En dan moet je wellicht nog rekening houden met dat geneuzel dat de gebruiker expliciet moet instemmen met het gebruik van cookies om je site fatsoenlijk te laten werken.

Wanneer dit op een andere/betere manier opgelost zou kunnen worden, sta ik open voor iedere suggestie. Hoe zou jij dit dan aanpaggen
Gewijzigd op 01/10/2018 10:53:45 door Donald Boers
 
- Ariën  -
Beheerder

- Ariën -

01/10/2018 11:26:59
Quote Anchor link
je bent bekend met het MVC-pattern?
 
Donald Boers

Donald Boers

01/10/2018 11:30:08
Quote Anchor link
@- Ariën - Ik ben bekent met het MVC-pattern en weet dus ook wat de Controller is, maar mijn vraag is wat ik in de Controller moet doen voordat ik de header verstuur.
Gewijzigd op 01/10/2018 11:30:49 door Donald Boers
 
Frank Nietbelangrijk

Frank Nietbelangrijk

01/10/2018 13:12:33
Quote Anchor link
Het lijkt me dat je het wat "centraler" zou moeten regelen Donald. Je zou niet in elke functie van je controller jezelf moeten bezighouden met welke taal er nu gebruikt moet worden. Ik heb geen idee welk framework je gebruikt en al zou ik dat hebben dan ben ik er wellicht niet bekend mee dus ik probeer je de goede richting in te duwen.

Stel dat de taal niet bekend is. Je moet dan een taal als standaard taal nemen en deze opslaan in
a) een variabele ergens in je applicatie en op zo een manier dat je er overal gemakkelijk bij kunt komen. (Je gebruikt elders in je applicatie niet meer rechtstreeks je $_COOKIE['language'] maar gebruikt een eigen variabele, bijvoorbeeld $language). en
b) moet je een COOKIE meesturen in de header van je response, dus de "pagina" die je terug gaat sturen naar de browser.

Als de taal wel bekend is (Je hebt een cookie meegestuurd gekregen in de REQUEST) dan stel je eveneens de taal in een variabele ergens in je applicatie. Het verschil is echter dat het nu de voorkeurstaal van de gebruiker is in plaats van de default-taal die jij zelf ingesteld hebt. Er hoeft nu geen nieuw cookie verstuurd te worden want de gebruiker heeft die al. (ga er van uit dat je hem een lange geldigheidsduur geeft).

Vervolgens kun je overal dus bijvoorbeeld in je controller, je menu-builder en in je view de $language variabele raadplegen. Dit betekend dus ook dat je bij voorkeur deze variabele al geïnitialiseerd hebt voordat je controller wordt geraadpleegd of misschien uiterlijk in de constructor van je baseController class.

Indien bovenstaande niet duidelijk is laat dan even weten hoe je controller class er uit ziet en of deze van een base class extended wordt.
Gewijzigd op 01/10/2018 13:15:23 door Frank Nietbelangrijk
 
- Ariën  -
Beheerder

- Ariën -

01/10/2018 13:19:46
Quote Anchor link
Gebruik je een bestaand framework? Vaak hebben deze de beschikking over 'auto loaders', en daar zou dit prima in passen.
 
Donald Boers

Donald Boers

01/10/2018 13:30:01
Quote Anchor link
Frank Nietbelangrijk op 01/10/2018 13:12:33:
Het lijkt me dat je het wat "centraler" zou moeten regelen Donald. Je zou niet in elke functie van je controller jezelf moeten bezighouden met welke taal er nu gebruikt moet worden. Ik heb geen idee welk framework je gebruikt en al zou ik dat hebben dan ben ik er wellicht niet bekend mee dus ik probeer je de goede richting in te duwen.

@Frank Nietbelangrijk. Lang niet gehoord. Het is geen bestaand Framewerk, maar een samengesteld. Het taal gebeuren vind niet echt plaats in elke functie van een Controller. Ik heb een file (Bootstrap.php) wat ik include in index.php. In dit document worden zaken zoals autoloader, PATH en routes gedefinieerd Voor de goede orde. Dit is wat er dit document staat:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
error_reporting(E_ALL);
ini_set('display_errors', 1);

define('APP_PATH', realpath(__DIR__.'/../'));

session_start();

$lang  = filter_input(INPUT_GET, 'lang');
$route = filter_input(INPUT_GET, 'route');

if ( !$lang ) {
    if ( isset($_COOKIE["language"]) ) {
        $lang = $_COOKIE["language"];
    } else {
        $lang = 'nl';
    }
    header("Location: /$lang/$route");
    exit;
} else {
    $lang = (string)$lang;
    setcookie( 'language', $lang, time() + 60*60*24*365, '/' );    
}

require_once 'autoloader.php';
require_once APP_PATH . '/lib/password.php';
require_once APP_PATH . '/lib/i18n.class.php';
require_once APP_PATH . '/lib/AltoRouter.php';

Config::setDirectory(APP_PATH.'/config');
View::setDirectory(APP_PATH.'/templates');

$router = new Router();
$router->dispatch('/'.$route);

Daarnaast heb ik een main Controller waarin zaken zoals de navigatie geregeld worden. Ik heb werkelijk geen idee wat in dit geval de beste aanpak zou kunnen zijn

Toevoeging op 01/10/2018 13:35:22:

@- Ariën - Dit staat niet in elke Controller. Dit staat alleen in het document wat ik in index.php include:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
require_once('../private/includes/bootstrap.php');
Gewijzigd op 01/10/2018 13:32:36 door Donald Boers
 
- Ariën  -
Beheerder

- Ariën -

01/10/2018 13:42:03
Quote Anchor link
Een auto-loader zou dan makkelijker zijn. Dan hoef je eigenlijk niet steeds meer alles zelf te includeren ;-)

http://php.net/manual/en/language.oop5.autoload.php

Je Language-systeem kan je ook dan tot een Language-class verpakken.
Gewijzigd op 01/10/2018 13:43:02 door - Ariën -
 
Donald Boers

Donald Boers

01/10/2018 13:49:09
Quote Anchor link
- Ariën - op 01/10/2018 13:42:03:
Een auto-loader zou dan makkelijker zijn. Dan hoef je eigenlijk niet steeds meer alles zelf te includeren ;-)

http://php.net/manual/en/language.oop5.autoload.php

Je Language-systeem kan je ook dan tot een Language-class verpakken.

@- Ariën - Ik gebruik een auto-loader zoals ik in mijn antwoord aan @Frank reeds aangaf. Dit is mijn auto-loader:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
function auto_loader($file)
{
    $file = APP_PATH . '/includes/classes/' . str_replace('_', '/', $file) . '.php';
    if (file_exists($file)) {
        require_once $file;
    }
}
    
spl_autoload_register('auto_loader');
 
Frank Nietbelangrijk

Frank Nietbelangrijk

01/10/2018 14:00:11
Quote Anchor link
De netste oplossing lijkt mij een class te schrijven die bepaald en bijhoudt welke taal er gebruikt moet worden.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
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
<?php

class LanguageManager
{
    private static $defaultLanguage = 'nl'; // of haal deze uit de configuratie

    private static $language;

    public static function init()
    {

        /* checken of we een cookie hebben ontvangen */
        if ( isset($_COOKIE["language"]) ) {
            self::$language = $_COOKIE["language"];

        /* anders dan maken we een taal nederlands en schrijven we een cookie weg */
        } else {
            self::setLanguage(self::$defaultLanguage);
        }
    }


    public static function getLanguage()
    {

        return self::$language;
    }


    public static function setLanguage($language)
    {

        self::$language = $language;
        setcookie( 'language', self::$language, time() + 60*60*24*365, '/' );
    }

}


/* ergens in je applicatie voordat je met je controllerfuncties aan de gang gaat: */
LanguageManager::init();

/* Een andere taal instellen kan maar moet wel voordat je enige output verstuurd met: */
// LanguageManager::setLanguage('de'); // (bijvoorbeeld als een gebruiker dit kiest in een dropdown)

/* welke taal moeten we hebben? */

echo LanguageManager::getLanguage();
?>
 
Donald Boers

Donald Boers

01/10/2018 14:05:24
Quote Anchor link
Frank Nietbelangrijk op 01/10/2018 14:00:11:
/* Een andere taal instellen kan maar moet wel voordat je enige output verstuurd met: */
// LanguageManager::setLanguage('de'); // (bijvoorbeeld als een gebruiker dit kiest in een dropdown)

@Frank Nietbelangrijk. Ik heb de klas gemaakt en geinitieerd. als ik die echo geeft deze de juiste taal aan maar hoe verwerk ik dit in een dropdown?
Gewijzigd op 01/10/2018 22:38:03 door Donald Boers
 
Thomas van den Heuvel

Thomas van den Heuvel

01/10/2018 14:55:45
Quote Anchor link
Donald Boers op 01/10/2018 13:49:09:
@- Ariën - Ik gebruik een auto-loader zoals ik in mijn antwoord aan @Frank reeds aangaf. Dit is mijn auto-loader:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
function auto_loader($file)
{
    $file = APP_PATH . '/includes/classes/' . str_replace('_', '/', $file) . '.php';
    if (file_exists($file)) {
        require_once $file;
    }
}
    
spl_autoload_register('auto_loader');

Heb je die functie wel eens gebenchmarkerd? Dit lijkt mij een extreem "dure" autoloader variant. De default implementatie van spl_autoload_register() is nagenoeg altijd het snelste en regelt alles eigenlijk al automatisch. Als de directorystructuur van de class-bestanden de naamgeving volgt dan werkt het eigenlijk al out-of-the-box.

Het enige wat je zou moeten doen is ergens een include path instellen waarin de classes staan. Sterker nog, hier kun je zelfs een volgorde in aanbrengen waarbij je bijvoorbeeld eerst een directory include voor alternatieve implementaties van "core" classes, en vervolgens de directory van de standaard implementaties. Dit zodat je af kunt wijken van standaard implementaties zonder de "core" functionaliteit aan te passen.

Dit is ook handig als je met externe libraries werkt waarin je waarschijnlijk beter niet zelf kunt gaan lopen modderen (en dat wordt ook een ramp als je die dingen versioned).
 
Ward van der Put
Moderator

Ward van der Put

01/10/2018 16:39:01
Quote Anchor link
Donald Boers op 01/10/2018 14:05:24:
Maar op welk moment/waar roep ik deze Class aan?

Wanneer heb je de taal nodig?
 
Donald Boers

Donald Boers

01/10/2018 17:29:56
Quote Anchor link
@Ward van der Put. Op het moment dat iemand in de dropdown een andere taal kiest. En op zich werkt het op de manier zoals ik het nu heb alleen wordt de taal dropdown niet geupdate. De huidige(actieve) taal is de link (bootstrap dropdown):
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
<li class="nav-item dropdown">
    <a class="nav-link dropdown-toggle" href="#">
        <img src="/images/flaggs/nl.png">&nbsp;&nbsp;Nederlands
    </a>
</li>

Met in de dropdown de andere talen
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
<div class="dropdown-menu dropdown-menu-right mt-0">
    <a href="/en<?php echo $current_route?>" class="dropdown-item">
        <img src="/images/flaggs/uk.png">&nbsp;&nbsp;English
    </a>
    // andere talen
</div>

Dus op het moment dat iemand op b.v. de engelse link klikt moet de li nav-item van nederlands in engels veranderen. Op zich werkt dit alleen als ik de pagina handmatig ververs
 
Rob Doemaarwat

Rob Doemaarwat

01/10/2018 19:55:39
Quote Anchor link
Is het niet een gevalletje: "Let op: een cookie setten met setcookie() verandert niet de huidige waarde in $_COOKIE"?

In je index.php doe je nu een setcookie(), maar in je template kijk je naar $_COOKIE["lang"] (die dus nog niet is bijgewerkt, dat zie de volgende call pas terug). Als je nu van regel 21 in index.php het volgende maakt:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
   setcookie( 'language', $_COOKIE["lang"] = $lang, time() + 60*60*24*365, '/' );
//                        ^^^^^^^^^^^^^^^^^^^ - dit toevoegen

Werkt het dan wel zoals bedoeld?

Bonus: ipv regel 12 t/m 16 kun je tegenwoordig (PHP 7) ook:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
$lang = $_COOKIE["language"] ?? 'nl'; //kijk mam, geen foutmeldingen!
Gewijzigd op 01/10/2018 19:59:39 door Rob Doemaarwat
 
Donald Boers

Donald Boers

01/10/2018 21:53:19
Quote Anchor link
@Rob Doemaarwat
Rob Doemaarwat op 01/10/2018 19:55:39:
Werkt het dan wel zoals bedoeld?

Nee helaas niet. Ik moet de pagina nog steeds handmatig verversen alvorens de actieve nav-item veranderd naar de nieuwe taal:(
Rob Doemaarwat op 01/10/2018 19:55:39:
Bonus: ipv regel 12 t/m 16 kun je tegenwoordig (PHP 7) ook:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
$lang = $_COOKIE["language"] ?? 'nl'; //kijk mam, geen foutmeldingen!

Leuke bonus. Scheelt toch weer 4 regels code. Hartelijk bedankt.
 
Rob Doemaarwat

Rob Doemaarwat

01/10/2018 22:17:12
Quote Anchor link
Hm, jammer. Nog wel een paar vragen:

- Dit klopt volgens mij niet:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
if (!isset($_COOKIE["lang"]) || isset($_COOKIE["lang"]) && $_COOKIE["lang"] == 'nl' )
Bedoel je niet ("niet gezet; of wel gezet, en dan 'nl'"):
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
if (!isset($_COOKIE["lang"]) || ($_COOKIE["lang"] == 'nl'))

Nu is het deel voor de "&&" altijd waar (cookie is altijd niet of wel gezet)

- Waar komt die $current_route vandaan? Echo anders $_COOKIE["lang"] en $current_route in je template (waar je ook het menu in elkaar zet), en kijk eens of daar wel in zit wat je verwacht.
 
Donald Boers

Donald Boers

01/10/2018 22:36:11
Quote Anchor link
Rob Doemaarwat op 01/10/2018 22:17:12:
- Dit klopt volgens mij niet:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
if (!isset($_COOKIE["lang"]) || isset($_COOKIE["lang"]) && $_COOKIE["lang"] == 'nl' )
Bedoel je niet ("niet gezet; of wel gezet, en dan 'nl'"):
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
if (!isset($_COOKIE["lang"]) || ($_COOKIE["lang"] == 'nl'))

Nu is het deel voor de "&&" altijd waar (cookie is altijd niet of wel gezet)


Heb je helemaal gelijk in. Dat was inderdaad niet juist. Het werkte wel maar was ietwat omslachtig

Rob Doemaarwat op 01/10/2018 22:17:12:
- Waar komt die $current_route vandaan? Echo anders $_COOKIE["lang"] en $current_route in je template (waar je ook het menu in elkaar zet), en kijk eens of daar wel in zit wat je verwacht.


$current_route is gedefinieerd in de Main Controller:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
protected $route;

$this->route = $route;

'current_route'   => $this->route

dat is de huidige pagina/template waarop een bezoeker zich bevindt als deze een ander taal kiest. Als ik bijvoorbeeld op www.website.com/nl/over ben dan is $_COOKIE["lang"] /nl/ en $current_route /over. Waneer ik vervolgens voor engels kies dan wordt $_COOKIE["lang"] /en/ en $current_route /about
Gewijzigd op 01/10/2018 22:41:53 door Donald Boers
 
Rob Doemaarwat

Rob Doemaarwat

01/10/2018 23:21:29
Quote Anchor link
Is $_COOKIE["lang"] dan letterlijk "/nl/" (dus met die twee slashes - voor & na)!? Is dat dan niet je probleem? "/en/" is niet gelijk aan "en". Dus dan werkt het niet. Waarom het dan de tweede keer wel werkt geen idee, maar dit lijkt in ieder geval niet te (kunnen) werken.
 
Donald Boers

Donald Boers

02/10/2018 17:33:07
Quote Anchor link
Rob Doemaarwat op 01/10/2018 23:21:29:
Is $_COOKIE["lang"] dan letterlijk "/nl/" (dus met die twee slashes - voor & na)!? Is dat dan niet je probleem? "/en/" is niet gelijk aan "en". Dus dan werkt het niet. Waarom het dan de tweede keer wel werkt geen idee, maar dit lijkt in ieder geval niet te (kunnen) werken.

@Rob Doemaarwat. Klein foutje van mijn kant. Is een enkele slash
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
/nl

de tweedeslash hoort bij de Route
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
/over
 

Pagina: 1 2 volgende »



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.