3v4l.org

run code in 300+ PHP versions simultaneously
<?php $html = 'this is just some example text.'; $terms = array( 'example'=>'explanation about example' ); // sort by reverse order of key size // (to be sure that the longest string always wins instead of the first in the pattern) uksort($terms, function ($a, $b) { $diff = mb_strlen($b) - mb_strlen($a); return ($diff) ? $diff : strcmp($a, $b); }); // build the pattern inside a capture group (to have delimiters in the results with the PREG_SPLIT_DELIM_CAPTURE option) $pattern = '~\b(' . implode('|', array_map(function($i) { return preg_quote($i, '~'); }, array_keys($terms))) . ')\b~i'; // prevent eventual html errors to be displayed $libxmlInternalErrors = libxml_use_internal_errors(true); // determine if the html string have a root html element already, if not add a fake root. $dom = new DOMDocument; $dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); $fakeRootElement = false; if ( $dom->documentElement->nodeName !== 'html' ) { $dom->loadHTML("<div>$html</div>", LIBXML_HTML_NODEFDTD | LIBXML_HTML_NOIMPLIED); $fakeRootElement = true; } libxml_use_internal_errors($libxmlInternalErrors); // find all text nodes (not already included in a link or between other unwanted tags) $xp = new DOMXPath($dom); $textNodes = $xp->query('//text()[not(ancestor::a)][not(ancestor::style)][not(ancestor::script)]'); // replacement foreach ($textNodes as $textNode) { $parts = preg_split($pattern, $textNode->nodeValue, -1, PREG_SPLIT_DELIM_CAPTURE); $fragment = $dom->createDocumentFragment(); foreach ($parts as $k=>$part) { if ($k&1) { $anchor = $dom->createElement('a', $part); $anchor->setAttribute('class', 'text-info'); $anchor->setAttribute('data-toggle', 'tooltip'); $anchor->setAttribute('data-original-title', $terms[strtolower($part)]); $fragment->appendChild($anchor); } else { $fragment->appendChild($dom->createTextNode($part)); } } $textNode->parentNode->replaceChild($fragment, $textNode); } // building of the result string $result = ''; if ( $fakeRootElement ) { foreach ($dom->documentElement->childNodes as $childNode) { $result .= $dom->saveHTML($childNode); } } else { $result = $dom->saveHTML(); } echo $result;
Finding entry points
Branch analysis from position: 0
2 jumps found. (Code = 43) Position 1 = 38, Position 2 = 46
Branch analysis from position: 38
2 jumps found. (Code = 77) Position 1 = 58, Position 2 = 115
Branch analysis from position: 58
2 jumps found. (Code = 78) Position 1 = 59, Position 2 = 115
Branch analysis from position: 59
2 jumps found. (Code = 77) Position 1 = 71, Position 2 = 108
Branch analysis from position: 71
2 jumps found. (Code = 78) Position 1 = 72, Position 2 = 108
Branch analysis from position: 72
2 jumps found. (Code = 43) Position 1 = 75, Position 2 = 101
Branch analysis from position: 75
1 jumps found. (Code = 42) Position 1 = 107
Branch analysis from position: 107
1 jumps found. (Code = 42) Position 1 = 71
Branch analysis from position: 71
Branch analysis from position: 101
1 jumps found. (Code = 42) Position 1 = 71
Branch analysis from position: 71
Branch analysis from position: 108
1 jumps found. (Code = 42) Position 1 = 58
Branch analysis from position: 58
Branch analysis from position: 108
Branch analysis from position: 115
2 jumps found. (Code = 43) Position 1 = 118, Position 2 = 129
Branch analysis from position: 118
2 jumps found. (Code = 77) Position 1 = 121, Position 2 = 127
Branch analysis from position: 121
2 jumps found. (Code = 78) Position 1 = 122, Position 2 = 127
Branch analysis from position: 122
1 jumps found. (Code = 42) Position 1 = 121
Branch analysis from position: 121
Branch analysis from position: 127
1 jumps found. (Code = 42) Position 1 = 132
Branch analysis from position: 132
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 127
Branch analysis from position: 129
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 115
Branch analysis from position: 46
filename:       /in/Av5pu
function name:  (null)
number of ops:  134
compiled vars:  !0 = $html, !1 = $terms, !2 = $pattern, !3 = $libxmlInternalErrors, !4 = $dom, !5 = $fakeRootElement, !6 = $xp, !7 = $textNodes, !8 = $textNode, !9 = $parts, !10 = $fragment, !11 = $part, !12 = $k, !13 = $anchor, !14 = $result, !15 = $childNode
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
    3     0  E >   ASSIGN                                                   !0, 'this+is+just+some+example+text.'
    5     1        ASSIGN                                                   !1, <array>
   12     2        INIT_FCALL                                               'uksort'
          3        SEND_REF                                                 !1
          4        DECLARE_LAMBDA_FUNCTION                          ~18     [0]
   16     5        SEND_VAL                                                 ~18
   12     6        DO_ICALL                                                 
   19     7        INIT_FCALL                                               'implode'
          8        SEND_VAL                                                 '%7C'
          9        INIT_FCALL                                               'array_map'
         10        DECLARE_LAMBDA_FUNCTION                          ~20     [1]
         11        SEND_VAL                                                 ~20
         12        INIT_FCALL                                               'array_keys'
         13        SEND_VAR                                                 !1
         14        DO_ICALL                                         $21     
         15        SEND_VAR                                                 $21
         16        DO_ICALL                                         $22     
         17        SEND_VAR                                                 $22
         18        DO_ICALL                                         $23     
         19        CONCAT                                           ~24     '%7E%5Cb%28', $23
         20        CONCAT                                           ~25     ~24, '%29%5Cb%7Ei'
         21        ASSIGN                                                   !2, ~25
   22    22        INIT_FCALL                                               'libxml_use_internal_errors'
         23        SEND_VAL                                                 <true>
         24        DO_ICALL                                         $27     
         25        ASSIGN                                                   !3, $27
   25    26        NEW                                              $29     'DOMDocument'
         27        DO_FCALL                                      0          
         28        ASSIGN                                                   !4, $29
   26    29        INIT_METHOD_CALL                                         !4, 'loadHTML'
         30        SEND_VAR_EX                                              !0
         31        SEND_VAL_EX                                              8196
         32        DO_FCALL                                      0          
   27    33        ASSIGN                                                   !5, <false>
   29    34        FETCH_OBJ_R                                      ~34     !4, 'documentElement'
         35        FETCH_OBJ_R                                      ~35     ~34, 'nodeName'
         36        IS_NOT_IDENTICAL                                         ~35, 'html'
         37      > JMPZ                                                     ~36, ->46
   30    38    >   INIT_METHOD_CALL                                         !4, 'loadHTML'
         39        ROPE_INIT                                     3  ~38     '%3Cdiv%3E'
         40        ROPE_ADD                                      1  ~38     ~38, !0
         41        ROPE_END                                      2  ~37     ~38, '%3C%2Fdiv%3E'
         42        SEND_VAL_EX                                              ~37
         43        SEND_VAL_EX                                              8196
         44        DO_FCALL                                      0          
   31    45        ASSIGN                                                   !5, <true>
   34    46    >   INIT_FCALL                                               'libxml_use_internal_errors'
         47        SEND_VAR                                                 !3
         48        DO_ICALL                                                 
   37    49        NEW                                              $43     'DOMXPath'
         50        SEND_VAR_EX                                              !4
         51        DO_FCALL                                      0          
         52        ASSIGN                                                   !6, $43
   38    53        INIT_METHOD_CALL                                         !6, 'query'
         54        SEND_VAL_EX                                              '%2F%2Ftext%28%29%5Bnot%28ancestor%3A%3Aa%29%5D%5Bnot%28ancestor%3A%3Astyle%29%5D%5Bnot%28ancestor%3A%3Ascript%29%5D'
         55        DO_FCALL                                      0  $46     
         56        ASSIGN                                                   !7, $46
   41    57      > FE_RESET_R                                       $48     !7, ->115
         58    > > FE_FETCH_R                                               $48, !8, ->115
   42    59    >   INIT_FCALL                                               'preg_split'
         60        SEND_VAR                                                 !2
         61        FETCH_OBJ_R                                      ~49     !8, 'nodeValue'
         62        SEND_VAL                                                 ~49
         63        SEND_VAL                                                 -1
         64        SEND_VAL                                                 2
         65        DO_ICALL                                         $50     
         66        ASSIGN                                                   !9, $50
   43    67        INIT_METHOD_CALL                                         !4, 'createDocumentFragment'
         68        DO_FCALL                                      0  $52     
         69        ASSIGN                                                   !10, $52
   44    70      > FE_RESET_R                                       $54     !9, ->108
         71    > > FE_FETCH_R                                       ~55     $54, !11, ->108
         72    >   ASSIGN                                                   !12, ~55
   45    73        BW_AND                                           ~57     !12, 1
         74      > JMPZ                                                     ~57, ->101
   46    75    >   INIT_METHOD_CALL                                         !4, 'createElement'
         76        SEND_VAL_EX                                              'a'
         77        SEND_VAR_EX                                              !11
         78        DO_FCALL                                      0  $58     
         79        ASSIGN                                                   !13, $58
   47    80        INIT_METHOD_CALL                                         !13, 'setAttribute'
         81        SEND_VAL_EX                                              'class'
         82        SEND_VAL_EX                                              'text-info'
         83        DO_FCALL                                      0          
   48    84        INIT_METHOD_CALL                                         !13, 'setAttribute'
         85        SEND_VAL_EX                                              'data-toggle'
         86        SEND_VAL_EX                                              'tooltip'
         87        DO_FCALL                                      0          
   49    88        INIT_METHOD_CALL                                         !13, 'setAttribute'
         89        SEND_VAL_EX                                              'data-original-title'
         90        CHECK_FUNC_ARG                                           
         91        INIT_FCALL                                               'strtolower'
         92        SEND_VAR                                                 !11
         93        DO_ICALL                                         $62     
         94        FETCH_DIM_FUNC_ARG                               $63     !1, $62
         95        SEND_FUNC_ARG                                            $63
         96        DO_FCALL                                      0          
   50    97        INIT_METHOD_CALL                                         !10, 'appendChild'
         98        SEND_VAR_EX                                              !13
         99        DO_FCALL                                      0          
   45   100      > JMP                                                      ->107
   52   101    >   INIT_METHOD_CALL                                         !10, 'appendChild'
        102        INIT_METHOD_CALL                                         !4, 'createTextNode'
        103        SEND_VAR_EX                                              !11
        104        DO_FCALL                                      0  $66     
        105        SEND_VAR_NO_REF_EX                                       $66
        106        DO_FCALL                                      0          
   44   107    > > JMP                                                      ->71
        108    >   FE_FREE                                                  $54
   55   109        FETCH_OBJ_R                                      ~68     !8, 'parentNode'
        110        INIT_METHOD_CALL                                         ~68, 'replaceChild'
        111        SEND_VAR_EX                                              !10
        112        SEND_VAR_EX                                              !8
        113        DO_FCALL                                      0          
   41   114      > JMP                                                      ->58
        115    >   FE_FREE                                                  $48
   60   116        ASSIGN                                                   !14, ''
   62   117      > JMPZ                                                     !5, ->129
   63   118    >   FETCH_OBJ_R                                      ~71     !4, 'documentElement'
        119        FETCH_OBJ_R                                      ~72     ~71, 'childNodes'
        120      > FE_RESET_R                                       $73     ~72, ->127
        121    > > FE_FETCH_R                                               $73, !15, ->127
   64   122    >   INIT_METHOD_CALL                                         !4, 'saveHTML'
        123        SEND_VAR_EX                                              !15
        124        DO_FCALL                                      0  $74     
        125        ASSIGN_OP                                     8          !14, $74
   63   126      > JMP                                                      ->121
        127    >   FE_FREE                                                  $73
   62   128      > JMP                                                      ->132
   67   129    >   INIT_METHOD_CALL                                         !4, 'saveHTML'
        130        DO_FCALL                                      0  $76     
        131        ASSIGN                                                   !14, $76
   70   132    >   ECHO                                                     !14
   71   133      > RETURN                                                   1


Dynamic Functions:
Dynamic Function 0
Finding entry points
Branch analysis from position: 0
2 jumps found. (Code = 43) Position 1 = 11, Position 2 = 13
Branch analysis from position: 11
1 jumps found. (Code = 42) Position 1 = 18
Branch analysis from position: 18
1 jumps found. (Code = 62) Position 1 = -2
Branch analysis from position: 13
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/Av5pu
function name:  {closure}
number of ops:  20
compiled vars:  !0 = $a, !1 = $b, !2 = $diff
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   12     0  E >   RECV                                             !0      
          1        RECV                                             !1      
   13     2        INIT_FCALL                                               'mb_strlen'
          3        SEND_VAR                                                 !1
          4        DO_ICALL                                         $3      
          5        INIT_FCALL                                               'mb_strlen'
          6        SEND_VAR                                                 !0
          7        DO_ICALL                                         $4      
          8        SUB                                              ~5      $3, $4
          9        ASSIGN                                                   !2, ~5
   15    10      > JMPZ                                                     !2, ->13
         11    >   QM_ASSIGN                                        ~7      !2
         12      > JMP                                                      ->18
         13    >   INIT_FCALL                                               'strcmp'
         14        SEND_VAR                                                 !0
         15        SEND_VAR                                                 !1
         16        DO_ICALL                                         $8      
         17        QM_ASSIGN                                        ~7      $8
         18    > > RETURN                                                   ~7
   16    19*     > RETURN                                                   null

End of Dynamic Function 0

Dynamic Function 1
Finding entry points
Branch analysis from position: 0
1 jumps found. (Code = 62) Position 1 = -2
filename:       /in/Av5pu
function name:  {closure}
number of ops:  7
compiled vars:  !0 = $i
line      #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   19     0  E >   RECV                                             !0      
          1        INIT_FCALL                                               'preg_quote'
          2        SEND_VAR                                                 !0
          3        SEND_VAL                                                 '%7E'
          4        DO_ICALL                                         $1      
          5      > RETURN                                                   $1
          6*     > RETURN                                                   null

End of Dynamic Function 1

Generated using Vulcan Logic Dumper, using php 8.0.0


preferences:
302.1 ms | 1037 KiB | 23 Q