[PHP] Variabelen in string replacen

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

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Kaastosti
  • Registratie: Juni 2000
  • Laatst online: 20-09 21:39

Kaastosti

Vrolijkheid alom!

Topicstarter
Ik heb een lap tekst uit m'n database. In die tekst komen variabelen voor tussen de tekst.
Blahdiblah $variabele meerblahblah
Eerst include ik een bestand waarin alle mogelijke variabelen staan. Iets als:
PHP:
1
2
3
$kaas        = 'tosti';
$tosti      = 'worst';
$variabele  = 'kaas';

Dan wordt de tekst uit de database gehaald, waarna ik de variabelen daarin wil vervangen door de waarden uit het aparte bestand.
PHP:
1
2
3
$query    = "SELECT content FROM tabel WHERE id='".$this->id."'";
$result   = mysql_query($query);
$row      = mysql_fetch_assoc($result);
In $row zit dan de inhoud van de database in stringvorm "Blahdiblah $variabele meerblahblah"

Door wat zoekwerk kwam ik uit op de functie eval(), maar deze geeft geen restulaat. Of er komt een syntax error uit, of er staat de letter 'A' als enige output, of gewoon helemaal niets. Toch heb ik de indruk dat ik niet de eerste ben die zoiets wil doen en dat er dus ongetwijfeld een functie in php zal zitten waarmee ik dit effect snel kan bereiken. Help! :P

Een vergissing is menselijk, maar om er echt een puinhoop van te maken heb je een computer nodig.


Acties:
  • 0 Henk 'm!

  • killercow
  • Registratie: Maart 2000
  • Laatst online: 18-09 12:47

killercow

eth0

Ik denk dat je het beste je text uit de je database kunt replacen met de volgende setup:

PHP:
1
2
3
4
$text='Jouw text, met [variabelen] en nog meer [test] tags.';
$vars['variabelen']='een';
$vars['test']='twee';
$text=preg_replace("/\\[(\S+)\]/Ue","\$vars\\['\\1'\]",$text);

Zal geven: Jouw text, met een en nog meer twee tags

Eval is een vrij enge functie, aangezien je ook gevaarlijke stukken php code zou kunnen uitvoeren die in de database staan, of gezet zijn door derden. (daarnaast is alles zonder eval veiliger op te lossen)

openkat.nl al gezien?


Acties:
  • 0 Henk 'm!

  • Kaastosti
  • Registratie: Juni 2000
  • Laatst online: 20-09 21:39

Kaastosti

Vrolijkheid alom!

Topicstarter
Ik heb inderdaad gelezen dat eval niet echt een populaire functie is, maar deze leek de enige te zijn voor een dergelijke actie. preg_replace zou inderdaad ook moeten werken... eens kijken.

Een vergissing is menselijk, maar om er echt een puinhoop van te maken heb je een computer nodig.


Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
killercow schreef op woensdag 13 april 2005 @ 16:41:
Ik denk dat je het beste je text uit de je database kunt replacen met de volgende setup:

PHP:
1
2
3
4
$text='Jouw text, met [variabelen] en nog meer [test] tags.';
$vars['variabelen']='een';
$vars['test']='twee';
$text=preg_replace("/\\[(\S+)\]/Ue","\$vars\\['\\1'\]",$text);

Zal geven: Jouw text, met een en nog meer twee tags

Eval is een vrij enge functie, aangezien je ook gevaarlijke stukken php code zou kunnen uitvoeren die in de database staan, of gezet zijn door derden. (daarnaast is alles zonder eval veiliger op te lossen)
Volgens mij is het resultaat dan: "Jouw text, met $vars['variabelen'] en nog meer $vars['test'] tags."

Beetje vreemd stukje code imo.

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

  • Sybr_E-N
  • Registratie: December 2001
  • Laatst online: 12:54
eval() is zoals gezet eval, maar waarom sla een een variabele op in een database? Heeft dat een bepaalde reden, want het meestal niet de meest elegante manier van doen.

Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
werkt dit niet:

PHP:
1
2
3
4
5
$string = "abc \$var ghi";
$var = "def";
$code = '$string = "'  . $string . '";';
eval($code);
print $string;

Ik blaat maar wat, het is niet echt netjes oid.

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

Verwijderd

Kijk eens goed naar het volgende voorbeeld:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php

// INIT
$teststring = 'De grote hond was nooit bang.';

// SEARCH
// Vul een array met waarden die je wilt zoeken
$search[] = 'grote';
$search[] = 'hond';

// REPLACEMENTS
// Vul een array met waarden waarmee je wilt vervangen
$replacement[] = 'kleine';
$replacement[] = 'kat';

// EXECUTE
$string = str_replace($search, $replacement, $teststring);

// SHOW
echo $string;

?>


Als je gebruik wilt maken van een meer gecompliceerde manier van zoeken, voor bijvoorbeeld zinsdelen of woorden waarvan je de opbouw niet exact weet (etc.) maak dan gebruik van preg_replace(), een soort zelfde functie. Voor details verwijs ik je graag naar de php manual...

[ Voor 6% gewijzigd door Verwijderd op 13-04-2005 17:00 . Reden: typo ]


Acties:
  • 0 Henk 'm!

  • Kaastosti
  • Registratie: Juni 2000
  • Laatst online: 20-09 21:39

Kaastosti

Vrolijkheid alom!

Topicstarter
Het nadeel van die manier van replacen, is dat de indices moeten kloppen. Dat werkt niet meer op het moment dat je er namen aan gaat geven, wat ik wel zou willen om de leesbaarheid te verhogen.

Ik geef direct toe dat het opslaan van variabelen in de database niet echt netjes is, maar daar ontkom ik niet aan. Niet alleen staat alles al in de database, het is de enige manier om met deze bestanden te werken. Het gaat om het genereren van bestanden waarin die variabelen voor kunnen komen. Elk bestand is weer anders en is dus niet generiek op te bouwen met scripting.. vandaar de variabelen in de database.

Het is me overigens met eval wel al gelukt om de variabelen te converteren...probleem zat in een array-index foutje mijnerzijds. Toch houd ik me aanbevolen voor de preg_replace manier, die ben ik nog aan het proberen :)

[ Voor 16% gewijzigd door Kaastosti op 13-04-2005 17:06 ]

Een vergissing is menselijk, maar om er echt een puinhoop van te maken heb je een computer nodig.


Acties:
  • 0 Henk 'm!

  • The Milkman
  • Registratie: Maart 2004
  • Laatst online: 12-09 20:42

The Milkman

█████░░░░░ 50%

Wel is str_replace sneller dacht ik...

𓆑 𓆑 𓆑 𓆑 𓆑 𓆑


Acties:
  • 0 Henk 'm!

Verwijderd

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php

// INIT
$teststring = 'De $grote $hond was nooit bang.';

// SEARCH
// Vul een array met waarden die je wilt zoeken
$search[] = '$grote';
$search[] = '$hond';

// REPLACEMENTS
// Vul een array met waarden waarmee je wilt vervangen
$replacement[] = 'kleine';
$replacement[] = 'kat';

// EXECUTE
$string = str_replace($search, $replacement, $teststring);

// SHOW
echo $string;

?>

?

Als dit niet is wat je zoekt, dan snap ik er helemaal niets van. Eet smakelijk, ga er vandoor.

[ Voor 9% gewijzigd door Verwijderd op 13-04-2005 17:29 ]


Acties:
  • 0 Henk 'm!

  • Kaastosti
  • Registratie: Juni 2000
  • Laatst online: 20-09 21:39

Kaastosti

Vrolijkheid alom!

Topicstarter
Het kan inderdaad met bovenstaande code, maar wat waarmee replaced wordt is dat niet erg duidelijk bedoel ik. Als ik een lijst heb van 30 variabelen is niet snel te zien wat de waardes gaan worden.

Een vergissing is menselijk, maar om er echt een puinhoop van te maken heb je een computer nodig.


Acties:
  • 0 Henk 'm!

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06 13:31

drm

f0pc0dert

't grootste nadeel van eval is dat als iemand zo leuk is om malicious code in de content te zetten (op wat voor manier dan ook) dat je de pineut bent.

Je kunt het beste gebruik maken van preg_replace_callback. En een mooie class eromheen doet 't altijd goed.

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
52
<?
class Environment {
   function Environment ( &$env ) {
      $this->env =& $env;
   }

   function lookup ( $varName ) {
      if ( $varName [0] {0} == '\\' ) {
         return substr ( $varName[0], 1 );
      }
      if ( array_key_exists ( $varName[1], $this->env ) ) {
         return $this->env [ $varName[1] ];
      }
      return null;
   }

   function replaceAll ( $str ) {
      return preg_replace_callback ( '/\\\?\$(\w+)/', array ( &$this, 'lookup' ), $str );
   }
}

function localreplace ( $str ) {
   $var = 'some local var contents';
   
   // environment op basis van de lokale variabelen
   $localEnv = new Environment ( get_defined_vars () );
   return $localEnv->replaceAll ( $str );
}


// environment op basis van de globale variabelen
$globalEnv = new Environment ( $GLOBALS );

// environment op basis van een array (evt later te vullen)
$myMap = array ();
$myEnv = new Environment ( $myMap );

$str = '\$var needs to be replaced with &quot;$var&quot;';

$myMap [ 'var' ] = 'other environment var contents';
$var = 'global var contents';

printf ( 
   '<p>With an array environment: <strong>%s</strong></p>
   <p>With a local environment: <strong>%s</strong></p>
   <p>And with the global environmentt: <strong>%s</strong></p>
   ', 
   $myEnv->replaceAll ( $str ),
   localreplace ($str),
   $globalEnv->replaceAll ( $str )
);
?>


Ik raad je wel af gebruik te maken van die globals array, i.v.m. mogelijke security holes.

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
Kaastosti schreef op woensdag 13 april 2005 @ 17:40:
Het kan inderdaad met bovenstaande code, maar wat waarmee replaced wordt is dat niet erg duidelijk bedoel ik. Als ik een lijst heb van 30 variabelen is niet snel te zien wat de waardes gaan worden.
Dat is toch vrij simpel te omzeilen door er zelf een functie om heen te bouwen?
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php

function replaceKeysWithValues($keyValueArray, $target)
{
    return str_replace(
        array_keys($keyValueArray),
        array_values($keyValueArray),
        $target
    );
}

$variablesToReplace = array(
    '$var1' => 'value1',
    '$var2' => 'value2',
    '$var3' => 'value3'
);

$string = '$var1, $var2, $var3';

print replaceKeysWithValues($variablesToReplace, $string);

?>

Noushka's Magnificent Dream | Unity


Acties:
  • 0 Henk 'm!

Verwijderd

Michali schreef op woensdag 13 april 2005 @ 19:17:
[...]


Dat is toch vrij simpel te omzeilen door er zelf een functie om heen te bouwen?
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php

function replaceKeysWithValues($keyValueArray, $target)
{
    return str_replace(
        array_keys($keyValueArray),
        array_values($keyValueArray),
        $target
    );
}

$variablesToReplace = array(
    '$var1' => 'value1',
    '$var2' => 'value2',
    '$var3' => 'value3'
);

$string = '$var1, $var2, $var3';

print replaceKeysWithValues($variablesToReplace, $string);

?>
Exact. Ofwel, @TS, wees zelf ook creatief ;-) NOFI

[ Voor 10% gewijzigd door Verwijderd op 14-04-2005 09:54 ]


Acties:
  • 0 Henk 'm!

  • Kaastosti
  • Registratie: Juni 2000
  • Laatst online: 20-09 21:39

Kaastosti

Vrolijkheid alom!

Topicstarter
Ik wil ook best creatief zijn, tuurlijk, leuk, maar ik was er van overtuigd dat er voor zoiets een oersimpele functie moest zijn :) Nu is het wel zo dat alle informatie in de database er wordt neergezet door mijzelf of een collega, dus malafide code zal niet voorkomen. Ik heb het er over gehad en ik laat nu heel even eval() staan, om me niet stuk te staren op dit probleem.

Als ik aan het einde van m'n stage tijd over houd ga ik dit soort schoonheidsfoutjes er uit filteren, want er zitten nog een aantal puntjes in waar ik nog niet helemaal tevreden over ben. Bovenstaande suggesties zijn in ieder geval zeer welkom, die ga ik dan ook proberen. Bedankt!

Een vergissing is menselijk, maar om er echt een puinhoop van te maken heb je een computer nodig.


Acties:
  • 0 Henk 'm!

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 29-05 22:54
Kaastosti schreef op donderdag 14 april 2005 @ 11:36:
Ik wil ook best creatief zijn, tuurlijk, leuk, maar ik was er van overtuigd dat er voor zoiets een oersimpele functie moest zijn :) Nu is het wel zo dat alle informatie in de database er wordt neergezet door mijzelf of een collega, dus malafide code zal niet voorkomen. Ik heb het er over gehad en ik laat nu heel even eval() staan, om me niet stuk te staren op dit probleem.

Als ik aan het einde van m'n stage tijd over houd ga ik dit soort schoonheidsfoutjes er uit filteren, want er zitten nog een aantal puntjes in waar ik nog niet helemaal tevreden over ben. Bovenstaande suggesties zijn in ieder geval zeer welkom, die ga ik dan ook proberen. Bedankt!
Waarom niet gelijk goed doen? Smerige dingen voor later bewaren is gewoon verkeerd. Bovendien is dit een potentieel veiligheids probleem (waarvan ik overigens niet zo snel kan bedenken wat er fout kan gaan, maar een voorgevoel zegt bijn altijd wel wat). Probeer eval iig zo veel mogelijk te vermijden.

Noushka's Magnificent Dream | Unity

Pagina: 1