ugrás a tartalomhoz

Maximum execution time of 30 seconds exceeded hiba

toldigabor · 2014. Jún. 20. (P), 20.58
Van egy ilyen forráskódrészletem, amelyben a keresés során talált szövegekben az összes keresett szó összes előfordulását kiemeli a mark html tag-gel:
  1. $j=1;  
  2. mysql_data_seek($lekerdezes,0);  
  3. while ($rekord=mysql_fetch_array($lekerdezes))  
  4.  {  
  5.   $szoveg=$rekord['szoveg'];  
  6.   for ($k=0; $k<count($keresendok); $k++)  
  7.    {  
  8.     $keresendo_hossz=mb_strlen($keresendok[$k],'UTF-8');  
  9.     $alap_poz=0;  
  10.     while (mb_strpos(mb_strtolower($szoveg,'UTF-8'),mb_strtolower($keresendok[$k],'UTF-8'),$alap_poz,'UTF-8')!==false)  
  11.      {  
  12.       $szoveg_hossz=mb_strlen($szoveg,'UTF-8');  
  13.       $kezdo_poz=mb_strpos(mb_strtolower($szoveg,'UTF-8'),mb_strtolower($keresendok[$k],'UTF-8'),$alap_poz,'UTF-8');  
  14.       $veg_poz=$kezdo_poz+$keresendo_hossz;  
  15.       $szoveg=mb_substr($szoveg,0,$kezdo_poz,'UTF-8') . "<mark>" . mb_substr($szoveg,$kezdo_poz,$keresendo_hossz,'UTF-8') . "</mark>" . mb_substr($szoveg,$veg_poz,$szoveg_hossz,'UTF-8');  
  16.       $alap_poz=$veg_poz+1;  
  17.      }  
  18.    }  
  19.   echo "     <p><strong>" . $j++ . ".</strong> " . $szoveg . " <em><a href='valami_link.php'>" . $valami . "</a></em></p>\n";  
  20.  }  
De a fenti hibát produkálja. És az a gáz, hogy ha a mark helyett em-et írok már jó, de ha egy 3 karakteres html tag-gel emelem ki (mondjuk próba képpen a sup) akkor már jó, sőt ha a nyitó vagy a záró markból csak egyetlen karaktert is kiemelek, akkor sem ír már hibaüzenetet. Pont azzal az egyetlen karakterrel lesz tele a hócipője.
 
1

Próbálhatnál kevesebb

Vilmos · 2014. Jún. 20. (P), 22.03
Próbálhatnál kevesebb konvertálást végezni.
Például, az 5. sorban a "szoveg" változót rögtön lehetne alakítani, nem minden egyes előfordulási ponton. A "keresendo" tömbről ugyanez elmondható, a 8. sorban használod, a "dataseek" előtt már előkészített állapotban lehetne.
4

+1

numen · 2014. Jún. 21. (Szo), 12.41
És valóban:
– a szoveg_hossz-t elég a legkülső ciklusban kiszámolni,
– ugyanez igaz az mb_strtolower(szoveg)-re

– Én lehet, hogy megpróbálnék egy mb_ereg_replace -et case insensitive-en használni (az mb_eregi_replace-nál pont szerepel a problémád a hozzászólások közt)

– Csúnya megoldás, ha tényleg másik taget használsz, és CSS-re bízod a maradékot :P
2

str_replace

bonga · 2014. Jún. 20. (P), 23.06
Mi lenne, ha az egész keresés és cserét a php-ra bíznád? Úgy biztosan gyorsabb lenne és talán nem futnál bele a hosszú feldolgozási időkorlátba.
Arra gondolok, hogy a $keresendok tömbből először építeni kellene mondjuk egy $kiemelesek tömböt, amely a keresendő szavakat az elvárt alakban (<mark>szo</mark>) tartalmazza, és utána egy egyszerű str_replace($keresendok, $kiemelesek, $szoveg) függvényhívással megoldhatnád az egészet:
  1. $kiemelesek = array();  
  2. for ($i=0; $i<count($keresendok); $i++)  
  3.   $kiemelesek[$i] = '<mark>'.$keresendok[$i].'</mark>';  
  4.   
  5. $j=1;  
  6. mysql_data_seek($lekerdezes, 0);  
  7. while ($rekord = mysql_fetch_array($lekerdezes))  
  8. {  
  9.   $szoveg = str_replace($keresendok$kiemelesek$rekord['szoveg']);  
  10.   echo "     <p><strong>" . $j++ . ".</strong> " . $szoveg . " <em><a href='valami_link.php'>" . $valami . "</a></em></p>\n";  
  11. }  
3

Kis- és nagybetűk

toldigabor · 2014. Jún. 21. (Szo), 05.47
Ez a kis- és nagybetűk miatt problémás. Ha a keresés mondjuk nagykezdőbetűvel történt, akkor a szövegek előfordulásaiban így át fogja írni ott is nagykezdőbetűsre, ahol kiskezdőbetűs előfordulás volt.
5

preg_replace

bonga · 2014. Jún. 22. (V), 16.42
Azt hiszem, hogy ez így ebben a formában nem igaz, mert az srt_replace case sensitive, vagyis pont, hogy nem fogja átírni ott is nagy kezdőbetűsre, ahol kis kezdőbetűs előfordulás volt.
Viszont az igaz, hogy a case sensitiveness miatt nem is fogja kiemelni a csak kis-nagybetűből fakadó eltéréseket.

De akkor javaslok egy még egyszerűbb megoldást preg_replace-el, mert ez tutin kezeli az utf8-at is és a case eltérést is bármely karakteren:
  1. $j=1;    
  2. mysql_data_seek($lekerdezes, 0);    
  3. while ($rekord = mysql_fetch_array($lekerdezes))    
  4. {    
  5.   $szoveg = $rekord['szoveg'];  
  6.   foreach($keresendok as $kiemelendo)  
  7.   {  
  8.     $szoveg = preg_replace('/('.$kiemelendo.')/iu''<mark>${1}</mark>'$szoveg);  
  9.   }  
  10.   echo "     <p><strong>" . $j++ . ".</strong> " . $szoveg . " <em><a href='valami_link.php'>" . $valami . "</a></em></p>\n";    
  11. }  
Szerk.:
Ez a megoldás egészen addig jó lesz, amíg az biztos, hogy a $keresendok tömb biztosan csak szavakat/szórészleteket tartalmaz. Arra figyelni kell, hogy amennyiben regexp-pattern kerül bele, akkor az boríthatja a keresést/cserét.
6

preg_quote

complex857 · 2014. Jún. 22. (V), 17.03
A belső loop elvileg kiváltható ha a regexp pattern eleve tartalmaz minden kiemelendő kifejezést (magát a pattern-t elvileg elég egyszer a db sorok loopján kívül előállítani), valahogy így:
  1. $pattern = join('|'array_map('preg_quote'$keresendok));  
  2. while ($rekord = mysql_fetch_array($lekerdezes))  
  3. {  
  4.     $szoveg = preg_replace('/('.$pattern.')/iu''<mark>$1</mark>'$rekord['szoveg']);  
  5.     echo "...";  
  6. }  

preg_quote
a keresendő mintákban előforduló speciális jelentésű dolgokat is biztonságosan fogyaszthatóvá teszi későbbi mintaillesztésre.