Avatar billede hoppe11 Nybegynder
28. juni 2007 - 16:05 Der er 15 kommentarer og
1 løsning

slashes ved preg_replace og modifier /e

hvordan kan det være at den escaper quotes osv. i en preg_replace med /e?

eks.
her bliver der escapet
$str = preg_replace('/.*/e', '"\\0"', $str);

her gør der ikke
$str = preg_replace('/.*/', '\\0', $str);
Avatar billede erikjacobsen Ekspert
28. juni 2007 - 16:30 #1
http://dk.php.net/manual/en/reference.pcre.pattern.modifiers.php
"Single quotes, double quotes, backslashes and NULL chars will be escaped by backslashes in substituted backreferences."

Det er faktisk lidt smart, da du så kan kalde funktioner med e-modifieren:

$str = preg_replace('/.*/e', 'minfunktion("\\0")', $str);
Avatar billede ranglen Nybegynder
28. juni 2007 - 18:38 #2
Du skal bare være forsigtig med hvad input du fanger, da det bliver evalueret af php bagefter. Det kan give en bruger mulighed for at hacke din side. Hvis du søger på funktionsnavnet og injektion kan du få lidt mere info om emnet
Avatar billede erikjacobsen Ekspert
28. juni 2007 - 18:44 #3
Avatar billede hoppe11 Nybegynder
28. juni 2007 - 18:54 #4
jeg kunne selvfølgelig læse i manualen :)

men jeg synes resultatet bliver det samme her
$str = preg_replace('/.*/e', 'minfunktion(stripslashes("\\0"))', $str);

altså jeg får umiddelbart ingen fejlmeddelelser fordi der ikke er escaped nogle af de forskrevne tegn
Avatar billede hoppe11 Nybegynder
28. juni 2007 - 18:59 #5
ranglen >
jeg kan ikke helt se for mig hvordan det skulle kunne lade sig gøre? vil du uddybe lidt? :)
Avatar billede erikjacobsen Ekspert
28. juni 2007 - 19:01 #6
Hvorfor vil du bruge e-modifier? Hvorfor vil du bruge stripslashes?
Avatar billede hoppe11 Nybegynder
28. juni 2007 - 19:05 #7
erik >
det skal alt sammen bruges i en class som evaluerer tekst jeg trækker ud fra min database inden den skrives til siden.. eks. url2link(), smiley(), utf8_wordwrap() osv.

min kode (stadig kun delvist færdig):
class sql2txt
{
    private $str_arr = array();
   
    private $wrap;
    private $link;
    private $smiley;
    private $html;
   
    private $pattern_split = '<[^>]+>(?:[^<]+<\/[^>]+>)?';
    private $pattern_atag = '(<a [^>]+>)([^<]+)(<\/a>)';
   
    /*
    if($html)
    {
        if($link)
        {
            str_split();
            link();
            smiley();
            wrap();
        }
        else
        {
            smiley();
            wrap();
        }
    }
    else
    {
        if($link)
        {
            strip_tags($str, '<a>');
            link();
            smiley();
            wrap();
            strip('< >');
        }
        else
        {
            strip('< >');
            smiley();
            wrap();
        }
    }
    */
   
    function str($str, $wrap = 10, $link = 1, $smiley = 1, $html = 0)
    {
        global $UID, $USER;
       
        $this->str_arr[0] = $str;
       
        $this->wrap = $wrap;
        $this->link = $link;
        $this->smiley = $smiley;
        $this->html = $html;
       
        if($UID && !$USER['set_smilies']) $this->smiley = 0;
       
        if($this->html)
        {
           
        }
        else
        {
            if($this->link)
            {
                array_walk_recursive($this->str_arr, array($this, 'str_strip_atags'));
                array_walk_recursive($this->str_arr, array($this, 'str_strip'));
               
                array_walk_recursive($this->str_arr, array($this, 'url2link'));
                array_walk_recursive($this->str_arr, array($this, 'str_tagsplit'));
            }
            else array_walk_recursive($this->str_arr, array($this, 'str_strip'));
        }
       
        if($this->smiley)
        {
            array_walk_recursive($this->str_arr, array($this, 'smiley'));
            array_walk_recursive($this->str_arr, array($this, 'str_tagsplit'));
        }
       
        array_walk_recursive($this->str_arr, array($this, 'utf8_wordwrap'));
       
        return $this->str_arr;
    }
   
    function str_strip_atags(&$str)
    {
        $str = preg_replace("/$this->pattern_atag/i", '\\2', $str);
    }
   
    function str_strip(&$str)
    {
        $trans_arr = array(
            '<' => '&lt;',
            '>' => '&gt;'
        );
       
        $str = strtr($str, $trans_arr);
    }
   
    function url2link(&$str)
    {
        $protocol = '(https?|ftp):\/\/';
        $user = $pass = '[a-z0-9_\-\.]+';
        $host = '[a-z0-9\-\.]+\.[a-z]{2,4}+';
        $port = '[0-9]{1,5}';
        $path = '[a-z0-9_\-\+\.%&=\/\(\)~;]+';
        $query = '\?[a-z0-9_\-\+\.%&=#]+';
       
        $uri = "$host(:$port)?($path)?($query)?";
       
        $pattern_arr = array(
            "/$protocol(($user(:$pass)?@)?$uri)/im" => '<a href="\\0" target="_blank">\\0</a>',
            "/(^| )(www\.$uri)/im" => '\\1<a href="http://\\2" target="_blank">http://\\2</a>',
            "/(^| )($user)@($host)/im" => '$1$2[at]$3'
        );
       
        $str = preg_replace(array_keys($pattern_arr), array_values($pattern_arr), $str);
    }
   
    function str_tagsplit(&$str)
    {
        $str = preg_split("/($this->pattern_split)/i", $str, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
    }
   
    function utf8_strlen($str)
    {
        return preg_match_all('/[\x00-\x7F\xC0-\xFD]/', $str, $var_empty);
    }
   
    function utf8_substr($str, $start, $end)
    {
        return preg_replace('/^(?:[\x00-\x7F]|[\xC0-\xFF][\x80-\xBF]+){0,'.$start.'}((?:[\x00-\x7F]|[\xC0-\xFF][\x80-\xBF]+){0,'.$end.'}).*/', '\\1', $str);
    }
   
    function utf8_wordwrap(&$str)
    {
        if(preg_match("/^$this->pattern_split$/i", $str))
        {
            if(preg_match("/^$this->pattern_atag$/i", $str)) $str = preg_replace("/$this->pattern_atag/ie", '"\\1".$this->utf8_wordwrap_link(stripslashes("\\2"), $this->wrap)."\\3"', $str);
            else $str = preg_replace('/(<[^>]+>)([^<]+)(<\/[^>]+>)/ie', '"\\1".$this->utf8_wordwrap_callback(stripslashes("\\0"), $this->wrap)."\\3"', $str);
        }
        else $str = preg_replace('/[^ \n]+/e', '$this->utf8_wordwrap_callback(stripslashes("\\0"), $this->wrap)', $str);
    }
   
    function utf8_wordwrap_callback($str, $wrap)
    {
        if($wrap)
        {
            $str_len = $this->utf8_strlen($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_link($str, $wrap)
    {
        $str_len = $this->utf8_strlen($str);
       
        if($str_len > $wrap)
        {
            $str_seq = floor($wrap * 0.8 / 2);
            $str = $this->utf8_substr($str, 0, $str_seq).'[...]'.$this->utf8_substr($str, $str_len-$str_seq, $str_len);
        }
       
        return $str;
    }
   
    function smiley(&$str)
    {
        $str = preg_replace('/([:;]\-?[\)\(\/\|pdoxs])(<| |$)/ime', '$this->smiley_callback("\\1", "\\2")', $str);
    }
   
    function smiley_callback($match1, $match2)
    {
        global $SMILEY_ARR;
       
        $smiley = strtolower(str_replace('-', '', $match1));
       
        if(stristr($_SERVER["HTTP_USER_AGENT"], 'msie')) $str .= '<span style="display:inline-block; height:'.$SMILEY_ARR[$smiley][0].'px; width:'.$SMILEY_ARR[$smiley][1].'px; background-image:url(\'gfx/smiley.'.$SMILEY_ARR[$smiley][2].'.png\')"></span>';
        else $str .= '<img src="gfx/smiley.'.$SMILEY_ARR[$smiley][2].'.png">';
       
        if($match2 == '<') $str .= $match2;
        elseif($match2) $str .= '&nbsp;';
       
        return $str;
    }
}
$sql2txt = new sql2txt();

$str = $sql2txt->str($str);
print_r($str);
?>
Avatar billede erikjacobsen Ekspert
28. juni 2007 - 19:27 #8
Jo, men vil du ikke forklare hvad det er du skal bruge det til?
Avatar billede hoppe11 Nybegynder
28. juni 2007 - 19:52 #9
den skal lave urls til links, lave smilies, lave wordwrap osv :)

alt tekst skal behandles af scriptet efter det trækkes ud af mysql og skrives til siden
Avatar billede hoppe11 Nybegynder
28. juni 2007 - 19:57 #10
*efter det trækkes ud af mysql og før det skrives til siden
Avatar billede erikjacobsen Ekspert
28. juni 2007 - 20:33 #11
Ok, men jeg læser ikke så meget kode igennem for at lede efter noget jeg ikke ved hvad er. Stripslashes er dog ikke løsningen. Problemet ved e-modifier er at det er svært at få korrekt og lovlig php-kode ind i andet argument, når man ikke har restriktioner på input. Og det er derfor man har lavet http://php.net/preg_replace_callback
Avatar billede hoppe11 Nybegynder
28. juni 2007 - 22:12 #12
jeg tror jeg er med på hvad du mener..

du mener man skal holde sig til preg_replace_callback så vidt muligt?
Avatar billede erikjacobsen Ekspert
28. juni 2007 - 22:27 #13
Formentlig, ja. Ellers giv os nogle simple problemer/eksempler på hvad der går galt.
Avatar billede hoppe11 Nybegynder
28. juni 2007 - 23:18 #14
Som sådan er der ikke noget galt, jeg ville bare vide hvorfor der blev added slashes ved /e... Det var sådan set bare det spm'et gik på

- men jeg kunne vel bare have set i manualen..

Men nu fandt jeg jo også ud af at /e kan være en lidt "beskidt" måde at håntere en callback på

Var det dig der ikke samlede på points? :)
Avatar billede erikjacobsen Ekspert
28. juni 2007 - 23:20 #15
Korrekt :)
Avatar billede hoppe11 Nybegynder
29. juni 2007 - 00:40 #16
men du skal stadig have mange tak for hjælpen :)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester