[php] String replacen naar variabele

Pagina: 1
Acties:
  • 277 views sinds 30-01-2008
  • Reageer

Onderwerpen


Acties:
  • 0 Henk 'm!

  • RickyHeijnen
  • Registratie: Maart 2005
  • Laatst online: 30-04 09:02
Goedendag... ik ben bezig om een language systeem te maken. Nu schrijf ik alle teksten als {{MENU_RESERVERING}} etc.. Nu moet ik alleen een script hebben die het hele document afzoekt naar {{...}} en vervolgens dat replaced door $lang['MENU']['RESERVERING'].

Wat ik kan doen is het document exploden op {{ en vervolgens alles wat eruit komt nog eens op }} en dan wat erin staat in $lang plaatsen, maar mijn vraag is nu of er een makkelijkere manier is die zoekt naar een combinatie van {{ en }}. Iets met preg_match had ik al gekeken, maar ik kom niet helemaal achter de logica van die functie.

Kan iemand me helpen?

Acties:
  • 0 Henk 'm!

  • Kaasplank
  • Registratie: Februari 2001
  • Niet online
str_replace

array maken en daar doorheen lopen

offtopic:
of ik denk ik te simpel of ik snap de vraag niet helemaal?

[ Voor 51% gewijzigd door Kaasplank op 10-02-2006 09:52 ]


Acties:
  • 0 Henk 'm!

  • Skaah
  • Registratie: Juni 2001
  • Laatst online: 16-09 18:38
Regurliere expressies. Zoek eens op preg_replace_callback in de manual.

Eigenlijk heeft Juggernaut een heel goed idee:
PHP:
1
2
3
4
5
foreach ($lang as $la_cat => $la_cat_val) {
 foreach ($la_cat_val as $la_search => $la_replace) {
  str_replace($string,'{{'.$la_cat.'_'.$la_search.'}}',$la_replace);
 }
}

[ Voor 86% gewijzigd door Skaah op 10-02-2006 09:50 ]


Acties:
  • 0 Henk 'm!

  • sorted.bits
  • Registratie: Januari 2000
  • Laatst online: 21:03
Met hele vieze eval code zou je het kunnen oplossen, maar dat zou ik je niet aanraden :D

Acties:
  • 0 Henk 'm!

  • RickyHeijnen
  • Registratie: Maart 2005
  • Laatst online: 30-04 09:02
Ja, het omzetten van MENU_RESERVERING naar $lang['MENU']['RESERVERING'] lukt me nog wel, maar het gaat mij meer om het zoeken naar de combinatie van {{ en }} in een lap HTML code. Zie: http://www.brixion.com/mhho/

Acties:
  • 0 Henk 'm!

  • Peter
  • Registratie: Januari 2005
  • Laatst online: 13-09 17:10
is iets als;

PHP:
1
$tekst = preg_replace( '/\{\{(\w+)_(\w+)\}\}/sie', '$lang[\\1][\\2]', $tekst );


niets? (niet getest)

Acties:
  • 0 Henk 'm!

  • BCC
  • Registratie: Juli 2000
  • Nu online

BCC

Ehm, hier heb je toch juist al die practige template libraries voor?1

Na betaling van een licentievergoeding van €1.000 verkrijgen bedrijven het recht om deze post te gebruiken voor het trainen van artificiële intelligentiesystemen.


Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 00:44

crisp

Devver

Pixelated

Persoonlijk zou ik een callback gebruiken, temeer daar je dan ook kan testen of de betreffende index wel bestaat:
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
<?php

$content = 'blabla {{MENU_RESERVERING}} blabla';

$lang = array();
$lang['MENU'] = array();
$lang['MENU']['RESERVERING'] = 'Uw Reservering';

$content = preg_replace_callback('/{{(\w+)_(\w+)}}/', 'myFunc', $content);

echo $content;

function myFunc($match)
{
    global $lang;

    if (isset($lang[$match[1]][$match[2]]))
    {
        return $lang[$match[1]][$match[2]];
    }
    else
    {
        return $match[0];
    }
}

?>

.Peter's optie kan ook, maar dan moet je het zo doen:
PHP:
1
$content = preg_replace('/{{(\w+)_(\w+)}}/e', '\$lang[\'$1\'][\'$2\']', $content);

;)

Intentionally left blank


Acties:
  • 0 Henk 'm!

  • RickyHeijnen
  • Registratie: Maart 2005
  • Laatst online: 30-04 09:02
Ik denk dat ik hier allemaal voorlopig wel even mee verder kan. Alle tips zijn nog welkom, ik ga dit allemaal even proberen ;). Bedankt voor de hulp...

Acties:
  • 0 Henk 'm!

  • Peter
  • Registratie: Januari 2005
  • Laatst online: 13-09 17:10
Ik gebruik enkele quotes, dan is de slash voor het dollarteken niet nodig (ondanks dat het wel netter is), want variablen worden sowieso niet geparsed. Verder worden { en } in preg gebruikt als min/max quantifiers, een slash daarvoor is dus wel zo netjes. Over de quotes van de array-keys ben ik het wel met je eens :)

Acties:
  • 0 Henk 'm!

  • stekkel
  • Registratie: Augustus 2001
  • Laatst online: 17-09 08:05
De methode voor de ondersteuning van meerdere talen is gettext. Zie ook:
http://nl.php.net/manual/en/ref.gettext.php

Je kan dan gewoon _("MENU_RESERVERING") in je php code prakken en gettext zorgt er dan voor dat afhankelijk van de gekozen language de juiste string gepresenteerd wordt.

Acties:
  • 0 Henk 'm!

Verwijderd

Als je geen gebruik wilt maken van de extra gettext-package, dan kun je ook je eigen language-systeempje maken natuurlijk; bepaal in een sessie-variabele welke taal momenteel de voertaal is op je pagina, schrijf een functie die variabelen - afhankelijk van de taal - ophaalt uit je database (waar je waarden taal-gerelateerd in opgeslagen staan). Haal de data vervolgens uit je database op met behulp van die functie op de juiste plaatsen en krijgt iets als:

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
/* 
# database table named `waarden`
CREATE TABLE `waarden` (
`id` INT NOT NULL AUTO_INCREMENT ,
`naam` VARCHAR( 255 ) NOT NULL ,
`waarde` LONGTEXT NOT NULL ,
`taal` VARCHAR( 3 ) NOT NULL ,
PRIMARY KEY ( `id` ) 
);*/

// init
$language = 'nl'; // (laten bepalen door sessie)

// select textpart function
function x($name) { 
    global $language;   
    $q =    "
        SELECT waarde
        FROM waarden
        WHERE naam = '".$name."'
        AND taal = '".$language."'
        LIMIT 1
        ";
    $r = mysql_query($q) or die(mysql_error()); 
    mysql_num_rows($r) == 1 ?
        $result = mysql_result($r,0,'waarde') :
        $result = 'Error; data for `'.$name.'` not found.';
    
    return $result;
}

?>

<html><!-- etc. -->

<h3><?=x('titel')?></h3>
<p><?=x('inleiding')?></p>


Als je de functie vaker dan x-maal gebruikt op je pagina, kan het in extreme gevallen wat overload genereren. In dat geval zul je een class- of andere functies moeten schrijven die er voor zorgen dat er uiteindelijk maar één query wordt uitgevoerd en zul je de data misschien op een iets andere manier in je html tevoorschijn moeten toveren, maar het concept lijkt me duidelijk.

Tevens kun je, als je e.e.a. uitbreidt, er net als bijvoorbeeld op de MS pagina's voor zorgen dat er een melding komt als de tekst niet in de huidige voertaal beschikbaar is (lees: niet gevonden is in de database) en daar een alternatieve tekst of verwijzing voor in de plaast tonen.

De methode die ik hierboven aanvoer verkies ik persoonlijk boven een replacesysteem, alhoewel die - zeker in combinatie met caching - een goed alternatief kunnen zijn. Bij een replacesysteem krijg ik het gevoel dat zich het beste laat omschrijven als `waarom data neerzetten op de plaats waar je je uiteindelijke data wilt hebben en vervolgens je hele document (wat erg groot kan zijn maar niet in verband moet staan met je content, vindt ik) laten doorzoeken om de eerstgenoemde data te laten vervangen door iets anders?`. Kortom; je moet altijd wat code neerzetten op de plaats waar je je uiteindelijke data wilt hebben staan, dus waarom niet direct (al dan niet met behulp van een functie, zoals ik aandraag) het goede daar neerzetten?

[ Voor 39% gewijzigd door Verwijderd op 10-02-2006 12:32 ]


Acties:
  • 0 Henk 'm!

  • RickyHeijnen
  • Registratie: Maart 2005
  • Laatst online: 30-04 09:02
@Frankie: Goede oplossing, vind het zelf een beetje omslachtig als je dan straks voor 9 talen ongeveer 1000 teksten hebt, dan zit je al snel met traagheid bij het uitlezen van de database. Daar komt nog bij dat de klant zelf heeft aangegeven het in een file te willen en niet in een database.

Wat betreft die errormelding. Ik denk dat ik daar in mijn functie wel uitkom door gewoon een melding te geven en vervolgens de engelse tekst te parsen, waarbij meteen een mailtje gaat naar de admin dat de betreffende tekst nog niet vertaald is.

Maar toch bedankt voor het meedenken ;).

Acties:
  • 0 Henk 'm!

  • SchizoDuckie
  • Registratie: April 2001
  • Laatst online: 18-02 23:12

SchizoDuckie

Kwaak

Als je PHP5 gebruikt zou je zoiets kunnen doen:

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
47
48
49
50
51
class templateengine
{
    var $template, $templateValues, $availableValues;
    function __construct($template='')
    {   
        $this->template = $template;
        $this->availableValues = array();
        $this->templateValues = array();

    }
    
    function __set($key, $value)
    {
        $this->availableValues[$key] = $value;
    }

    function feedValues($input)
    {
        foreach ($input as $key=>$val)
        {
            $this->availableValues[$key] = $val;
        }
    }

    function grabValues($input)
    {
        preg_match_all('!\{\{(.*)\}\}!U', $input, $output);
        return($output);
    }

    function run()
    {
        $tpl = file_get_contents($this->template);
        $this->templateValues = $this->grabValues($tpl);
        for ($i=0; $i<sizeof($this->templateValues[1]); $i++)
        {
            $tpl = str_replace($this->templateValues[0][$i], stripslashes($this->availableValues[$this->templateValues[1][$i]]), $tpl);
        }

        return ($tpl);  

    }

}


$tpl = new templateEngine('template.inc.php');
$tpl->MENU_RESERVERING = $lang['nl_NL']['MENU_RESERVERING'];
$tpl->MENU_HOME = $lang['nl_NL']['MENU_HOME'];
// of: $tpl->feedValues($lang['nl_NL'];
echo ($tpl->run);

Stop uploading passwords to Github!


Acties:
  • 0 Henk 'm!

  • RickyHeijnen
  • Registratie: Maart 2005
  • Laatst online: 30-04 09:02
Ik gebuik inderdaad PHP, maar wat is hier het voordeel van t.o.v. de code die crisp geeft?!?

Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Verwijderd schreef op vrijdag 10 februari 2006 @ 12:26:
PHP:
1
//lap code

Kortom; je moet altijd wat code neerzetten op de plaats waar je je uiteindelijke data wilt hebben staan, dus waarom niet direct (al dan niet met behulp van een functie, zoals ik aandraag) het goede daar neerzetten?
In dit geval: omdat je een query voor elke taalafhankelijke uitdrukking uitvoert. :X Dit is wel de meest resourcevretende oplossing die ik ooit heb gezien om meerdere talen te kunnen ondersteunen op een website. :X
zoetericky schreef op zaterdag 11 februari 2006 @ 18:50:
Ik gebuik inderdaad PHP, maar wat is hier het voordeel van t.o.v. de code die crisp geeft?!?
Vrij weinig tot niets voor zover ik zo zie. Dit is alleen een stuk lastiger omdat je nou midden in je code nog indexen moet gaan linken aan hun daadwerkelijke values.

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

Verwijderd

-NMe- schreef op zaterdag 11 februari 2006 @ 19:11:
[...]

In dit geval: omdat je een query voor elke taalafhankelijke uitdrukking uitvoert. :X Dit is wel de meest resourcevretende oplossing die ik ooit heb gezien om meerdere talen te kunnen ondersteunen op een website. :X
Ik hoop en neem aan dat je de eerste alinea, die er al stond toen je deze reactie plaatste, ook goed gelezen hebt? Ik ben niet de minste die vergeet dat als voor elke, zoals jij het noemt `taalafhankelijke uitdrukking` een query uitgevoerd moet worden, je er wel rekening mee moet houden dat dit bij een x-aantal inderdaad recources gaat `vreten` en dat je dan een alternatieve - schrijf er een class voor, zoals ik opperde - werkwijze moet laten uitvoeren.

Kortom, niet te snel blaten ;) NOFI

Echter, als je louter twee queries moet uitvoeren voor één pagina (bijv. een titel en een stuk tekst) dan is er i.m.o. niets mis met mijn aangevoerde idee - en ik neem toch een klein beetje aan dat ook jij dat vindt.
Pagina: 1