PHP Variable in String finden und ersetzen
Hallo zusammen,
da eval() sowohl aus Sicherheitsgründen als auch aus Performancegründen keine Option zu sein scheint, würde ich gern ein Problem wie folgt lösen:
Es gibt einen String, der in der Datenbank samt PHP Variablen gespeichert ist. Wenn ich diesen nun wieder aus der DB auslese und per Echo ausgebe, werden nachvollziehbarer Weise die Variablen als String interpretiert. Lässt sich theoretisch mit eval () lösen, jedoch kostet das eine Menge Zeit.
Als andere Alternative gilt das arbeiten mit str_replace.
Jetzt würde ich das gern von der Logik her wie folgt auflösen:
1. Suche einen String nach einem Text mit dem Muster $Variablenname ab.
2. str_replace ($Variablenname, $Variablenname, $Text)
Allerdings stellt sich mir die Frage, ob es nicht einen besseren Weg gibt, als alle möglichen Variablen die in den Strings vorkommen können als array zu führen, sondern einfach in den jeweiligen Strings danach suchen zu lassen.
Ja, an könnte natürlich auch Platzhalter in die Datenbank schreiben und diese dann mittels "str_replace" durch die dazugehörende Variable ersetzen, ist aus meiner Sicht allerdings einfach mehr Code für das gleiche Ergebnis.
Habt ihr da eine Idee.
PS: Die Variablennamen sind natürlich mit unterschiedliche Länge vorhanden.
Danke und Grüße
René
da eval() sowohl aus Sicherheitsgründen als auch aus Performancegründen keine Option zu sein scheint, würde ich gern ein Problem wie folgt lösen:
Es gibt einen String, der in der Datenbank samt PHP Variablen gespeichert ist. Wenn ich diesen nun wieder aus der DB auslese und per Echo ausgebe, werden nachvollziehbarer Weise die Variablen als String interpretiert. Lässt sich theoretisch mit eval () lösen, jedoch kostet das eine Menge Zeit.
Als andere Alternative gilt das arbeiten mit str_replace.
Jetzt würde ich das gern von der Logik her wie folgt auflösen:
1. Suche einen String nach einem Text mit dem Muster $Variablenname ab.
2. str_replace ($Variablenname, $Variablenname, $Text)
Allerdings stellt sich mir die Frage, ob es nicht einen besseren Weg gibt, als alle möglichen Variablen die in den Strings vorkommen können als array zu führen, sondern einfach in den jeweiligen Strings danach suchen zu lassen.
Ja, an könnte natürlich auch Platzhalter in die Datenbank schreiben und diese dann mittels "str_replace" durch die dazugehörende Variable ersetzen, ist aus meiner Sicht allerdings einfach mehr Code für das gleiche Ergebnis.
Habt ihr da eine Idee.
PS: Die Variablennamen sind natürlich mit unterschiedliche Länge vorhanden.
Danke und Grüße
René
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 374034
Url: https://administrator.de/contentid/374034
Ausgedruckt am: 22.11.2024 um 04:11 Uhr
19 Kommentare
Neuester Kommentar
Hallo.
Wie wäre es mit preg_recplace-callback() - PHP-Manual
Mit einem RegEx nach möglichen Variablen suchen ala "\$[a-zA-Z_-]+" und in der Callback-Funktion überprüfen ob diese gefundene Variable tatsächlich existieret/einenWertHat oder sie in einem Whitelist-Array steht und dann ersetzen oder nicht.
~Arano
Wie wäre es mit preg_recplace-callback() - PHP-Manual
Mit einem RegEx nach möglichen Variablen suchen ala "\$[a-zA-Z_-]+" und in der Callback-Funktion überprüfen ob diese gefundene Variable tatsächlich existieret/einenWertHat oder sie in einem Whitelist-Array steht und dann ersetzen oder nicht.
~Arano
Hallo René,
Gruß Frank
Zitat von @Lorderich:
Es gibt einen String, der in der Datenbank samt PHP Variablen gespeichert ist. Wenn ich diesen nun wieder aus der DB auslese und per Echo ausgebe, werden nachvollziehbarer Weise die Variablen als String interpretiert.
Gib uns bitte mal ein Beispiel wie "String samt Variablen" in der DB aussieht damit das tatsächlich nachvollziehbar wird.Es gibt einen String, der in der Datenbank samt PHP Variablen gespeichert ist. Wenn ich diesen nun wieder aus der DB auslese und per Echo ausgebe, werden nachvollziehbarer Weise die Variablen als String interpretiert.
Gruß Frank
Mahlzeit
Hab ich richtig verstanden? Du hast einen String nach dem Schema var1=inhalt1&var2=inhalt2&var3=inhalt3 und hättest im weiteren Verlauf des Scripts gerne die Variablen so, als wären Sie direkt per GET übergeben worden. Dann sollte parse_str() eigentlich das machen was du willst.
Manuel
Hab ich richtig verstanden? Du hast einen String nach dem Schema var1=inhalt1&var2=inhalt2&var3=inhalt3 und hättest im weiteren Verlauf des Scripts gerne die Variablen so, als wären Sie direkt per GET übergeben worden. Dann sollte parse_str() eigentlich das machen was du willst.
Manuel
Hallo Manuel,
Bei dem von Dir genannten Beispiel wäre ich bisher in dieser Art vorgegangen:
Der Fokus liegt hier auf der Syntax von Zeile 16 (Zuweisung per $$).
Ausgabe
Gruß Frank
parse_str()
kann ich bisher nicht. Danke für den Hinweis und den Link.Bei dem von Dir genannten Beispiel wäre ich bisher in dieser Art vorgegangen:
<?php
// Vorgabe
$zeichenfolge = "var1=inhalt1&var2=inhalt2&var3=inhalt3";
// Am &-Zeichen auftrennen
$paare = explode("&", $zeichenfolge);
foreach($paare AS $paar)
{
// Am =-Zeichen auftrennen
$paarteile = explode("=", $paar);
// optionale Ausgabe zur Kontrolle
// echo $paarteile . " = " . $paarteile[1] . "<br>\n";
// Zuweisung von Wert zu variablem Variablenname
$$paarteile = $paarteile[1];
};
// Ergebnisausgabe zur Kontrolle
echo "Ermittelte Variablen und ihre Werte:<br>\n";
echo "var1: " . $var1 . "<br>\n";
echo "var2: " . $var2 . "<br>\n";
echo "var3: " . $var3 . "<br>\n";
?>
Der Fokus liegt hier auf der Syntax von Zeile 16 (Zuweisung per $$).
Ausgabe
Ermittelte Variablen und ihre Werte:
var1: inhalt1
var2: inhalt2
var3: inhalt3
Gruß Frank
Bei dem von Dir genannten Beispiel wäre ich bisher in dieser Art vorgegangen
Mit parse_str() sieht das dann so aus:
<?php
$zeichenfolge = "var1=inhalt1&var2=inhalt2&var3=inhalt3";
parse_str($zeichenfolge);
if (isset($var1)) {
echo $var1 . "<br>\n";
}
if (isset($var2)) {
echo $var2 . "<br>\n";
}
if (isset($var3)) {
echo $var3 . "<br>\n";
}
?>
Als Ausgabe erhälst du damit
inhalt1
inhalt2
inhalt3
Manuel
Hallo René,
ich sehe keinen Grund nicht
Was Du aber bei 1. mit "Variablen ab" meinst ist unklar.
Hast Du die Anführungszeichen falsch gesetzt?
Was Du damit meinst ist auch unklar:
$Variablennamen, $Variablenname, $string
Die Syntax für
Dein Code könnte dann so aussehen:
Zuvor musst Du die Variable namens ID noch irgendwie mit dem Wert 12 belegen.
Ich gehe davon aus, dass die 12 auch irgendwo in der DB steht und Du mit einer entsprechenden Abfrage dynamisch
Gruß Frank
ich sehe keinen Grund nicht
str_replace
einzusetzen.Was Du aber bei 1. mit "Variablen ab" meinst ist unklar.
Hast Du die Anführungszeichen falsch gesetzt?
Was Du damit meinst ist auch unklar:
$Variablennamen, $Variablenname, $string
- $Variablennamen (Mehrzahl) ?
- $Variablenname (Einzahlzahl) ?
Die Syntax für
str_replace
ist diese hier:str_replace ($suchfolge, $ersatzfolge, $quellfolge)
Dein Code könnte dann so aussehen:
$string = "<div class='panel-heading'><h1>Vielen Dank für deine Registrierung.</h1></div><div class='panel-body'>Deine Mitgliedsnummer ist: <span class='success'>“. $ID.“ </span> und Du wurdest <span class='success'> mit den ausgewählten Rollen</span> registriert!<p><p></div>"
$string = str_replace ("$ID", $ID, $string);
Ich gehe davon aus, dass die 12 auch irgendwo in der DB steht und Du mit einer entsprechenden Abfrage dynamisch
$ID = "12";
setzen kannst.Gruß Frank
Hallo René,
Eine Lösung wäre dann relativ umständlich und/oder eventuell fehleranfällig.
Es müsste dabei eindeutig definierbar sein wo eine Variable anfängt und wo sie auffhört.
Das $-Zeichen dürfte beispielsweise nie Teil des Ausgangstextes sein, ausser wenn es tatsächlich den Beginn einer auszuwertenden Variablen kennzeichnet.
Ebenso darf das $-Zeichen nicht Inhalt einer Variabel sein, damit Du es Dir nicht beim Ersetzen in den Text einfügst.
Hier etwas Pseudocode, der je nach erforderlichen Fallunterscheidungen beliebig komplex werden kann.:
Gruß Frank
Zitat von @Lorderich:
Ich suche einen eher allgemeineren Weg für das ersetzen.
...
Wenn ja, dann bau das str_replace zusammen aus
$string = ("$Variablenname", $Variablenname, $string)
...dann schreib das doch bitte auch gleich.Ich suche einen eher allgemeineren Weg für das ersetzen.
...
Wenn ja, dann bau das str_replace zusammen aus
$string = ("$Variablenname", $Variablenname, $string)
Eine Lösung wäre dann relativ umständlich und/oder eventuell fehleranfällig.
Es müsste dabei eindeutig definierbar sein wo eine Variable anfängt und wo sie auffhört.
Das $-Zeichen dürfte beispielsweise nie Teil des Ausgangstextes sein, ausser wenn es tatsächlich den Beginn einer auszuwertenden Variablen kennzeichnet.
Ebenso darf das $-Zeichen nicht Inhalt einer Variabel sein, damit Du es Dir nicht beim Ersetzen in den Text einfügst.
Hier etwas Pseudocode, der je nach erforderlichen Fallunterscheidungen beliebig komplex werden kann.:
While (pos von "$" >= 0 in $string)
{
$anfang = pos von "$"
$ende = pos von "." oder " " oder ...
$Variabelname = teilstring (von $anfang, bis $ende, aus $string)
$string = ("$Variablenname", $Variablenname, $string)
};
Gruß Frank
Ich suche einen eher allgemeineren Weg für das ersetzen.
Na dann:// variables
$var1 = "Max";
$var2 = "Ball";
$var3 = "blauen";
// replace function
function ReplaceVariablesInString($str){
// search all variables in string
if ($result = preg_match_all('/\$([a-z_\x7f-\xff][a-z0-9_\x7f-\xff]*)/i',$str,$matches,PREG_SET_ORDER)){
// itterate over all vars
foreach($matches as $match){
// replace variables with content
$str = preg_replace('/' . preg_quote($match) .'/',$GLOBALS[$match[1]],$str);
}
}
//return new string
return $str;
}
// original string
$stringFromDB = 'Hallo mein Name ist $var1 und ich habe einen $var3 $var2.';
// replaced string
echo ReplaceVariablesInString($stringFromDB);
Nö .
Es müsste dabei eindeutig definierbar sein wo eine Variable anfängt und wo sie auffhört.
Das ist definiert, einfacher Regex genügt . => http://php.net/manual/de/language.variables.basics.php
Nabend.
Kinners...
Und die Passende Ausgabe dieses:
Die Handbuchseite zu
~Arano
Kinners...
<?php
$gVar1="Hallo";
$gVar2="ich";
$gVarX="UNUSED";
$gVar14="Arano";
$strFromDBOrig='$gVar1, $gVar2 kenne meinen Namen: $gVar14<br>und hier eine falsche: $Bazinga';
$strFromDBManip=preg_replace_callback( '/\$([a-zA-Z0-9-_]+)/', 'cb_replace_if_exist', $strFromDBOrig );
echo $strFromDBOrig;
echo "<br><br>";
echo $strFromDBManip;
function cb_replace_if_exist( $inp )
{
if( isset( $GLOBALS[$inp[1]] ) )
return $GLOBALS[$inp[1]];
// Error handling
return ' ### Unknown Variable: $'.$inp[1].' ### ';
# Ein `trigger_error()` könnte man auch nehmen oder
# return ''; # nichts
}
?>
$gVar1, $gVar2 kenne meinen Namen: $gVar14
und hier eine falsche: $Bazinga
Hallo, ich kenne meinen Namen: Arano
und hier eine falsche: ### Unknown Variable: $Bazinga ###
Die Handbuchseite zu
preg_replace_callback
ist in der ersten Antwort verlinkt ;)~Arano
@Kabelbruch,
Deine Lösung mit
@Arano,
Dein Code funktioniert auch wunderbar.
Den Returnwert hattest Du schon wahlfrei angeboten.
Wie wäre es mit diesem Return?
Die Ein- und Ausgabe wären dann diese hier:
Variablen, die nicht belegt sind erscheinen im Ergebnis unersetzt.
So könnte ich Arano heißen und meinen 1000$anzug tragen.
(... ist etwas konstuiert da es eingentlich Tausenddollaranzug oder 1000-Dollar-Anzug heißen müsste und es ohnehin nur 50-Euro-Hose und T-Shirt sind und ich nicht Arano heiße.)
Gruß Frank
Zitat von @136166:
Der Punkt geht an Dich.Es müsste dabei eindeutig definierbar sein wo eine Variable anfängt und wo sie auffhört.
Das ist definiert, einfacher Regex genügt . => http://php.net/manual/de/language.variables.basics.phpZitat von @136166:
Nö .
...bezogen auf die Lösung basierend auf Nö .
str_replace
Deine Lösung mit
preg_replace
ist hingegen hübsch und hat auch kein Problem, wenn Variablen ein Dollarzeichen im Wert enthalten, was bei str_replace
in While-Schleife zu Problemen führen würde.@Arano,
Dein Code funktioniert auch wunderbar.
Den Returnwert hattest Du schon wahlfrei angeboten.
Wie wäre es mit diesem Return?
// Error handling
return '$'.$inp[1];
$gVar1, $gVar2 kenne meinen Namen: $gVar14
und hier eine falsche: $Bazinga
Hallo, ich kenne meinen Namen: Arano
und hier eine falsche: $Bazinga
So könnte ich Arano heißen und meinen 1000$anzug tragen.
(... ist etwas konstuiert da es eingentlich Tausenddollaranzug oder 1000-Dollar-Anzug heißen müsste und es ohnehin nur 50-Euro-Hose und T-Shirt sind und ich nicht Arano heiße.)
Gruß Frank
Hallo,
joar klar, alles machbar und neben der Geschmackssache seinen Kosten-Nutzungs-Faktor hat.
Und natürlich steht es auch jedem frei die Details zu verfeinern/anzupassen
Darüber hinaus kann es schwer sein einen Tippfehler in der Pseudo-Variable zu finden wenn einem kein Fehler oder Ähnliches angezeigt wird, daher
Allerdings kann man den RegEx auch dahingehend anpassen,
~Arano
joar klar, alles machbar und neben der Geschmackssache seinen Kosten-Nutzungs-Faktor hat.
Und natürlich steht es auch jedem frei die Details zu verfeinern/anzupassen
Variablen, die nicht belegt sind erscheinen im Ergebnis unersetzt.
In PHP gibt das immerhin eine Notice: Undefined variable: Bazinga in /srv/vhosts/test/www/lorderich/index.php on line 25 (darum der Hinweis auf trigger_error() )Darüber hinaus kann es schwer sein einen Tippfehler in der Pseudo-Variable zu finden wenn einem kein Fehler oder Ähnliches angezeigt wird, daher
return '### ERROR ###'
1000$anzug
Ja stimmt, hier wird "$anzug" gefunden aber so schreibt das doch auch keiner...1000$ AnzugAllerdings kann man den RegEx auch dahingehend anpassen,
- das vor dem $-Zeichen kein Buchstabe/Ziffer stehen darf
- oder ein Leerzeichen/Tabulator/Zeilenbeginn/Zeilenumbruch davor zu stehen hat was wiederum Verkettungsprobleme mit sich bringt
- oder kein \-Zeichen davor sein darf Maskierungszeichen
- oder bestimmen das "$" zu verwenden ist um sicher zu gehen das zwischen Variable-$ und Zeichen-$ differenziert wird !
- oder , oder, ...
~Arano
Hi,
wie wäre es denn, Code und Gestaltung sauber von einander zu trennen? Schreibe anstelle der Variablen Platzhalter rein und diese Platzhalter füllst du dann mit den Werten. Die Template Klasse hast du dir in 10 Minuten selbst geschrieben und macht nichts anderes als Platzhalter mit den Variablenwerten zu füllen. Codemäßig sieht das dann etwa so aus (lange kein PHP mehr geschrieben):
Gruß,
Thomas
wie wäre es denn, Code und Gestaltung sauber von einander zu trennen? Schreibe anstelle der Variablen Platzhalter rein und diese Platzhalter füllst du dann mit den Werten. Die Template Klasse hast du dir in 10 Minuten selbst geschrieben und macht nichts anderes als Platzhalter mit den Variablenwerten zu füllen. Codemäßig sieht das dann etwa so aus (lange kein PHP mehr geschrieben):
$Webpage = new Template("index.html");
$Webpage->Parse("MEMBERNAME", $Username);
$Webpage->Parse("LASTLOGIN", $LastLoginDate);
echo $Webpage->Show();
Gruß,
Thomas
Tach
Es gibt einen String, der in der Datenbank samt PHP Variablen gespeichert ist.
Wobei! Eine Templatesystem wirklich praktisch sein kann
Aus der anderen Seite, kommt der Content hier aus der DB und müsste dennoch geparst werden BEVOR er in das Template eingefügt werden kann...
~Arano
wie wäre es denn, Code und Gestaltung sauber von einander zu trennen?
Hat er doch, darum steht der Text doch auch in der Datenbank.Es gibt einen String, der in der Datenbank samt PHP Variablen gespeichert ist.
Schreibe anstelle der Variablen Platzhalter rein und diese Platzhalter füllst du dann mit den Werten.
Ist eine Variable kein Platzhalter !? Oder anders: Warum soll "PLATZHALTER" besser sein als "$PLATZHALTER" oder "#PLATZHALTER#" oder "{PLATZHALTER}" oder "$PLATZHALTER$".Die Template Klasse hast du dir in 10 Minuten selbst geschrieben
Wie du im Verlauf sehen kannst: 09:37-22:29Uhr = 12:52hWobei! Eine Templatesystem wirklich praktisch sein kann
Aus der anderen Seite, kommt der Content hier aus der DB und müsste dennoch geparst werden BEVOR er in das Template eingefügt werden kann...
~Arano
Hallo Arano,
Ich schrieb ja schon dazu, dass es eingentlich Tausenddollaranzug oder 1000-Dollar-Anzug heißen müsste.
Das wirft im Duden eine zweifache Errormeldung aus:
Syntax error: unexpected '
Syntax error: missing '
Handbuch: Da es sich um ein Wort handelt, muss es auch als ein Wort geschrieben werden (1000$anzug), aber wegen der Zahl und des $-Zeichens mit Bindestrichen (1000-$-Anzug).
Dazu sollte sich der TO äußern. Vielleicht trägt er ja gar keine Anzüge und die Aufgabe wäre ohne weitere Fallunterscheidung erledigt.
Gruß Frank
Ich schrieb ja schon dazu, dass es eingentlich Tausenddollaranzug oder 1000-Dollar-Anzug heißen müsste.
Das wirft im Duden eine zweifache Errormeldung aus:
Syntax error: unexpected '
' on line 1Syntax error: missing '
-
' on line 11000-$-Anzug
kompiliert ohne Error.Handbuch: Da es sich um ein Wort handelt, muss es auch als ein Wort geschrieben werden (1000$anzug), aber wegen der Zahl und des $-Zeichens mit Bindestrichen (1000-$-Anzug).
Dazu sollte sich der TO äußern. Vielleicht trägt er ja gar keine Anzüge und die Aufgabe wäre ohne weitere Fallunterscheidung erledigt.
Gruß Frank
Seht euch doch oben einfach meinen Regex an, der inkludiert nur per Definition gültige Variablen, steht auch in meinem Link.
'/\$([a-z_\x7f-\xff][a-z0-9_\x7f-\xff]*)/i'
Ansonsten einfach einmalige Platzhalter definieren, fertig Affe tot.
'/\$([a-z_\x7f-\xff][a-z0-9_\x7f-\xff]*)/i'
Ansonsten einfach einmalige Platzhalter definieren, fertig Affe tot.