04. oktober 2007 - 09:07
Der er
29 kommentarer og 1 løsning
preg_replace_callback php-kode i evaluering
Jeg har en preg_replace_callback hvor der kan ske at der er noget php kode med i mit input. Hvis det sker får jeg fejl. Hvordan kan jeg undgå det? Fejlen opstår i følgende linje: $str = preg_replace_callback('/(<[^>]+>)(([^<]+)(<\/\\1+>))?/', create_function('$matches', 'return $matches[1].$wordwrap_callback($matches[2], $wrap).$matches[3];'), $str);
Annonceindlæg tema
04. oktober 2007 - 09:16
#1
1) I stedet for at du bruger create_function() - lav en funktion ved siden af og angiv at det er den du bruger på callback-pladsen. Derved kommer du uden om at der kaldes eval() på din kode, og dermed skulle fejlen forsvinde af sig selv. 2) Man kan altis spekulere i om der overhovedet burde være PHP kode i din tekst...
04. oktober 2007 - 09:32
#2
hov.. jeg mener selvfølgelig ikke at php koden skal evalueres, men at den kun skal behandles som ren tekst.. :) jeg ved heller ikke om det er der fejlen præcis ligger.. jeg har lige ændret lidt på min kode, da den egentlig er en del af en class $str = preg_replace_callback('/(<[^>]+>)(([^<]+)(<\/\\1+>))?/', create_function('$match', 'return $match[1].$this->utf8_wordwrap_callback($match[2], $this->wrap).$match[3];'), $str); Fatal error: Using $this when not in object context in /var/www/www.electrobeat.dk/www/v3/req/functions.php(424) : runtime-created function on line 1 den kan åbenbart ikke finde ud af hvor den skal referere til?
04. oktober 2007 - 09:33
#3
så ikke lige du havde skrevet.. forsøger lige at lave en seperat funktion som du nævner
04. oktober 2007 - 09:40
#4
Warning: preg_replace_callback() [function.preg-replace-callback]: Requires argument 2, 'callback_wordwrap', to be a valid callback in function utf8_wordwrap(&$str) { if(preg_match("/^$this->pattern_split$/", $str)) { if(preg_match("/^$this->pattern_atag$/i", $str)) $str = preg_replace_callback("/$this->pattern_atag/i", 'callback_wordwrap_atag', $str); else $str = preg_replace_callback('/(<[^>]+>)(([^<]+)(<\/\\1+>))?/', 'callback_wordwrap_tag', $str); } else $str = preg_replace_callback('/[^ \n]+/', 'callback_wordwrap', $str); } function callback_wordwrap_atag($match) { return $match[1].$this->utf8_wordwrap_link($match[2], $this->wrap).$match[3]; } function callback_wordwrap_tag($match) { return $match[1].$this->utf8_wordwrap_callback($match[2], $this->wrap).$match[3]; } function callback_wordwrap($match) { return $this->utf8_wordwrap_callback($match[0], $this->wrap); } jeg ved egentlig heller ikke om det bare er nok at angive selve funktionen i sin preg_replace_callback uden objectet $this-> ?
04. oktober 2007 - 09:48
#5
Din callback funktion kaldes svjv. udenfor utf8_wordwrap klasens kontekst - du kan derfor ikke referere til $this.
04. oktober 2007 - 09:54
#6
jeg er ikke helt med? hvad udløser fejlen?
04. oktober 2007 - 09:56
#7
At du bruger "$this" i din callback_wordwrap_tag() funktion. Den er effektivt placeret udenfor klassen, og derfor kender den slet ikke $this. Der er intet du kan gøre for at udgå dette - sådan fungere callbacks i PHP (og andre sprog).
04. oktober 2007 - 10:00
#8
med andre ord findes der ikke en løsning på mit problem? :(
04. oktober 2007 - 10:07
#9
Jo, det gør der sikkert nok - men ikke når callback_wordwrap ikke ligger i den klasse $this henviser til.
Tag et kig på syntaksen for callback-parametre -
http://dk2.php.net/callback. Såfremt du har brug for det ligger i en anden klasse, må du placere din reference til objektet et sted du kan komme til det udenfor klassen - hvordan du skal gøre det afhænger af en række ting der ikke fremgår af spørgsmålet, men en mulighed var at have disse funktioner i en separat klasse som du instantierer og giver en reference til objektet $this henviser til der hvor du kalder preg_replace_callback.
04. oktober 2007 - 10:08
#10
Oprindelig havde jeg egentlig lavet mine preg's med /e flags Umiddelbart virkede det, men hvis man ville poste php kode (som selvfølgelig ikke skulle evalueres men gå igennem som ren tekst) fik jeg fejl I starten af min class og inden jeg påbegynder formateringen af stringen kører jeg den ellers igennem en stripslashes() function utf8_wordwrap(&$str) { if(preg_match("/^$this->pattern_split$/", $str)) { if(preg_match("/^$this->pattern_atag$/i", $str)) $str = preg_replace("/$this->pattern_atag/ie", 'stripslashes("\\1".$this->utf8_wordwrap_link("\\2", $this->wrap)."\\3")', $str); else $str = preg_replace('/(<[^>]+>)(([^<]+)(<\/\\1+>))?/e', 'stripslashes("\\1".$this->utf8_wordwrap_callback("\\2", $this->wrap)."\\3")', $str); } else $str = preg_replace('/[^ \n]+/e', 'stripslashes($this->utf8_wordwrap_callback("\\0", $this->wrap))', $str); } function utf8_wordwrap_callback($str, $wrap) { if($wrap) { $str_len = str_utf8len($str); $wrap_count = ceil($str_len / $wrap); if($wrap_count > 1) { $pointer = 0; for($i = 0; $i <= $wrap_count; $i++) { $arr[] = $this->utf8_substr($str, $pointer, $wrap); $pointer += $wrap; } $str = implode(' ', $arr); } } return $str; }
04. oktober 2007 - 10:11
#11
Du kan jo "udkommentere" din PHP-kode før at du sender den igennem: Ret "<?" og "?>" til f.eks. "[?" og "?]", send resultatet igennem din preg_replace_callback(), og bagefter retter du dem tilbage til "<?" og "?>"...
04. oktober 2007 - 10:17
#12
pidgeot > alle mine funktioner er i en og samme klasse
04. oktober 2007 - 10:20
#13
ja, det var selvfølgelig en mulighed, nielle men jeg har også ladet mig fortælle at det er en dårlig ide at bruge /e pga at det kan være svært at lave "kriterier" for sine matches?
04. oktober 2007 - 10:31
#14
Den har jeg ikke lige en menining om. Hvorfor skulle det være svært?
09. oktober 2007 - 16:05
#15
nielle > det ved jeg ikke? det er ikke mig der er eksperten :) jeg kan bare huske at jeg på et tidspunkt blev rådet til at bruge preg_replace_callback() jeg har lidt travlt i øjeblikket, men ser på det så snart jeg har tid
09. oktober 2007 - 18:21
#16
Der er nogle sikkerhedsmæssige aspekter af at bruge .../e - men andet er der vist ikke med det. :^)
16. oktober 2007 - 08:39
#17
Er du kommet videre med denne her?
16. oktober 2007 - 17:17
#18
hey nielle nej, og gør det nok heller ikke lige indenfor de næste dage, men smid et spm så deler vi points jeg må oprette det igen senere :)
16. oktober 2007 - 19:13
#19
Jeg smider et svar :^) Men vi kan da bare fortsætte her når du engang får tid og lyst :^)
17. oktober 2007 - 19:16
#20
Men nu skal jeg måske også lige være helt sikker på at jeg ved hvad /e modifieren gør :) Den evaluerer vel kun selve output? Men hvad nu hvis man smider noget php kode igennem? Hvis jeg smider en string ind i min preg_replace med /e får jeg fejl Catchable fatal error: Object of class sql2txt could not be converted to string in /var/www/www.electrobeat.dk/www/v3/req/functions.php(425) : regexp code on line 1
17. oktober 2007 - 19:18
#21
altså hvis der ryger rå php kode igennem.. koden skal ikke eksekveres min preg: preg_replace('/[^ \n]+/e', 'stripslashes($this->utf8_wordwrap_callback("\\0", $this->wrap))', $str);
17. oktober 2007 - 19:31
#22
Du kan læse om 'e' her:
http://dk2.php.net/manual/en/reference.pcre.pattern.modifiers.php Kort fortalt forsøger den at kalde eval() på de der replaces med. Hvis der derfor er noget PHP-kode lignende i dette så skal dette opfylde korrekt PHP syntaks og ellers kommer der en fejlmeddelelse á la det du viser.
17. oktober 2007 - 19:42
#23
med andre ord kan det altså ikke lade sig gøre at bruge /e samtidig med at der muligvis er noget php kode i input'et?
17. oktober 2007 - 19:43
#24
her er hele min funtion for at give dig lidt overblik over det jeg vil eventuel php kode i input'et skal ikke evalueres function utf8_wordwrap(&$str) { if(preg_match("/^$this->pattern_split$/", $str)) { if(preg_match("/^$this->pattern_atag$/i", $str)) $str = preg_replace("/$this->pattern_atag/ie", 'stripslashes("\\1".$this->utf8_wordwrap_link("\\2", $this->wrap)."\\3")', $str); else $str = preg_replace('/(<[^>]+>)(([^<]+)(<\/\\1+>))?/e', 'stripslashes("\\1".$this->utf8_wordwrap_callback("\\2", $this->wrap)."\\3")', $str); } else $str = preg_replace('/[^ \n]+/e', 'stripslashes($this->utf8_wordwrap_callback("\\0", $this->wrap))', $str); }
17. oktober 2007 - 19:45
#25
Problemet er mere om der kommer noget PHP kode ind via $str.
17. oktober 2007 - 20:11
#26
du mener ind i mine "match" eks. \\1 \\2 osv.
18. oktober 2007 - 08:21
#27
Jeg har nu forsøgt at omskrive det hele med preg_replace_callback, men det virker ikke, dog får jeg ingen fejl. Der bliver kun returneret små bider af min tekst Jeg prøvede også tidligere det her, men havde problemer med at referere til min callback funktioner i "preg_replace_callback" idet alle funktioner findes i en class function utf8_wordwrap(&$str) { if(preg_match("/^$this->pattern_split$/", $str)) { if(preg_match("/^$this->pattern_atag$/i", $str)) $str = preg_replace_callback("/$this->pattern_atag/i", array($this, 'utf8_wordwrap_link_callback'), $str); else $str = preg_replace_callback('/(<[^>]+>)(([^<]+)(<\/\\1+>))?/', array($this, 'utf8_wordwrap_callback'), $str); } else $str = preg_replace_callback('/[^ \n]+/', array($this, 'utf8_wordwrap_callback3'), $str); /* if(preg_match("/^$this->pattern_split$/", $str)) { if(preg_match("/^$this->pattern_atag$/i", $str)) $str = preg_replace("/$this->pattern_atag/ie", 'stripslashes("\\1".$this->utf8_wordwrap_link("\\2", $this->wrap)."\\3")', $str); else $str = preg_replace('/(<[^>]+>)(([^<]+)(<\/\\1+>))?/e', 'stripslashes("\\1".$this->utf8_wordwrap_callback("\\2", $this->wrap)."\\3")', $str); } else $str = preg_replace('/[^ \n]+/e', 'stripslashes($this->utf8_wordwrap_callback("\\0", $this->wrap))', $str); */ } function utf8_wordwrap_link_callback($arr) { return $arr[1].$this->utf8_wordwrap_link($arr[2], $this->wrap).$arr[3]; } function utf8_wordwrap_link_callback2($str, $wrap) { $str_len = str_utf8len($str); if($str_len > $wrap) { $str_seq = floor($wrap * 1.2 / 2); $str = $this->utf8_substr($str, 0, $str_seq).'[...]'.$this->utf8_substr($str, $str_len-$str_seq, $str_len); } return $str; } function utf8_wordwrap_callback($arr) { return $arr[1].$this->utf8_wordwrap_callback2($arr[2], $this->wrap).$arr[3]; } function utf8_wordwrap_callback2($str, $wrap) { if($wrap) { $str_len = str_utf8len($str); $wrap_count = ceil($str_len / $wrap); if($wrap_count > 1) { $pointer = 0; for($i = 0; $i <= $wrap_count; $i++) { $arr[] = $this->utf8_substr($str, $pointer, $wrap); $pointer += $wrap; } $str = implode(' ', $arr); } } return $str; } function utf8_wordwrap_callback3($arr) { return $this->utf8_wordwrap_callback($arr[0], $this->wrap); }
18. oktober 2007 - 17:17
#28
endelig :) tak for hjælpen
18. oktober 2007 - 23:03
#29
Skal det forstås som at du fik knækket den? :^)
18. oktober 2007 - 23:49
#30
ja umiddelbart vil jeg tro det :)
Vi tilbyder markedets bedste kurser inden for webudvikling