Codes knippen / Database

Status
Niet open voor verdere reacties.

RonaldGJ

Gebruiker
Lid geworden
28 apr 2007
Berichten
419
Beste mensen,

ik heb een klein simpel systeem op mijn website om tutorials te schrijven. Nu wil ik graag dat stukken php code een kleur krijgen. Dat wil met de highlight_string() functie. Maar als er een tutorial wordt getypt is natuurlijk niet alles code. Daarom moet alles tussen de tags [ php] en [ /php] gehightlighted worden. Net als op die forum gebeurd. De tutorials die getypt worden zet ik in de database.

Hoe kan ik dit het beste knippen en alleen het stuk code highlighten en alles goed in en uit de database halen?

Vast hartelijk bedankt,

Gr. Ronald!:)
 
PHP:
$bericht = "[ php]$var = 1;[ /php] en de rest van mijn bericht";
preg_replace("/\[ php\](.+)\[\/php\]/Usi", "highlight_string('\\1')", $bericht);
echo $bericht;
Iets in die trend denk ik.

edit: wel even de spaties weghalen in $bericht aangezien hij anders wordt geparsed hier :)
 
Hij vervangt het [ php] en [ /php] goed voor hightlight_string('...'), maar hij voert de highlight niet uit. De output van de code is nu:

highlight_string(' = 1;') en de rest van mijn bericht

Idee?

Gr. Ronald!:)
 
Omdat ik het toch wel een aparte vraag vond heb ik me er wat in verdiept.

Het resultaat:
HTML:
function formatPHP($string) {
  $escapeChars = array(
    "[" => "\[",
    "]" => "\]",
    "/" => "\/",
    "<" => "\<",
    ">" => "\>",
    "$" => "\\$",
    "?" => "\?"
  );
  if(preg_match_all("/\[php\](.+)\[\/php\]/Usi", $string, $matches)) {
    $count = 0;
    foreach($matches[0] AS $value) {
      if(preg_match("/\[php\]\<\? (.+)\?\>\[\/php\]/Usi", $value)) {
        $returns[] = preg_replace("/\[php\](.+)\[\/php\]/Usie", "highlight_string('\\1', true)", $value);
      } elseif(preg_match("/\[php\](.+)\?\>\[\/php\]/Usi", $value)) {
        $returns[] = preg_replace("/\[php\](.+)\[\/php\]/Usie", "highlight_string('<?php \\1', true)", $value);
      } elseif(preg_match("/\[php\]\<\?(.+)\[\/php\]/Usi", $value)) {
        $returns[] = preg_replace("/\[php\](.+)\[\/php\]/Usie", "highlight_string('\\1 ?>', true)", $value);
      } else {
        $returns[] = preg_replace("/\[php\](.+)\[\/php\]/Usie", "highlight_string('<?php \\1 ?>', true)", $value);
      }
      foreach($escapeChars AS $char => $rep) {
        $value = str_replace($char, $rep, $value);
      }
      $matches[0][$count] = '/'. $value .'/';
      $count++;
    }
    $result = preg_replace($matches[0], $returns, $string);
  } else {
    $result = $string;
  }
  return $result;
}
$bericht = '[php]<? $var = 1;[/php] en de rest van mijn [php]//bericht $test[/php] en nog [php]$meer; ?>[/php]';
echo formatPHP($bericht);
Sorry voor deze slordig weergave, de parser hier heeft veel moeite met mijn code in php-tags :evil:

Foutjes worden afgevangen
- Geen echte php-tags (<?php <? en ?>)
- Geen begin php-tag
- Geen eind php-tag

Hopelijk werkt het naar behoren.
 
Het werkt prima:thumb:.

Hartelijk bedankt voor de moeite! Ik ga nu weg, maar als ik terug ben ga ik de code even uitpluizen, want ik wil altijd graag weten hoe het in elkaar zit.

Als ik er nog vragen over heb, iets niet snap ofzo, vraag ik het je hier wel als dat goed is?

Bedankt,

Gr. Ronald!:)
 
Ik wil het je nu ook wel even uitleggen.

De preg_match_all() kijkt of er
PHP:
is gevonden. Alle resultaten die hij vindt zet hij in $matches.

Vervolgens ga ik $matches[0] uitlezen met een foreach

De eerste IF-statement kijkt of er
PHP:
<? {tekst} ?>
voorkomt. Bij true wijzigt hij de tags door highlight_string({tekst}) en zet het resultaat in de array $returns. Zit die er niet in gaat hij naar de ELSEIF.

De eerste ELSEIF kijkt of er
PHP:
 {tekst} ?>
voorkomt. (Oftewel de begintag mist). Bij true wijzigt hij de tags door highlight_string(<?php {tekst}) en zet het resultaat in de array $returns. Zit die er niet in gaat hij naar de ELSEIF.

De tweede ELSEIF kijkt of er
PHP:
<? {tekst}
voorkomt. (Oftewel de eindtag mist). Bij true wijzigt hij de tags door highlight_string({tekst} ?>) en zet het resultaat in de array $returns. Zit die er niet in gaat hij naar de ELSE.

In de ELSE komt alles waar geen tags in gevonden zijn. Hier worden beide tags toegevoegd aan highlight_string().

In dit gedeelte:
PHP:
      foreach($escapeChars AS $char => $rep) {
        $value = str_replace($char, $rep, $value);
      }
      $matches[0][$count] = '/'. $value .'/';
      $count++;
Escape ik alle tekens welke in de $escapeChars-array staan en zet ze weer in het juiste array-veld van $matches[0] (Daarom loopt $count mee). Zou ik die niet doen dan gaat het vervangen niet goed.

Wanneer dat allemaal gedaan is vervang ik alle waardes uit $matches[0] door de waardes uit $returns en return ik die.

Wordt er geen
PHP:
gevonden dan wordt gewoon de originele string teruggegeven.
 
Het wil toch nog niet helemaal zoals ik wil.

Als ik gewoon de functie formatPHP neerzet en daaronder die met $bericht. Dan geeft hij het prima weer.

Zet ik een tekst in de DB met [ php].....[ /php] en haal het er uit en zet het in formatPHP($variabele); dan geeft hij gewoon de [ php] en [ /php] nog weer. Hij highlight um dus in dit geval niet en ik kom er niet achter waarom.

Idee?

Gr. Ronald!
 
Zet om te testen eens eerst een echo op de variabele en daarna de functie
PHP:
echo $row['text'] .'<br /><br />';
echo formatPHP($row['text']);
Zo kun je kijken wat er in wellicht fout gaat.

Als je de code even doorgeeft welke fout gaat kan ik kijken wat ik er aan kan doen.
 
Ik heb eerst een gewone echo gedaan, daarna een echo met formatPHP(). Ze worden beide hetzelfde weergegeven.

Ik heb helemaal bovenin het php bestand de functie staan.
Dan heb ik het stukje om de gegevens uit de database te halen en weer te geven:

PHP:
			$id = $rij['id'];
			$titel = $rij['titel'];
			$tutorial = $rij['tutorial'];
			echo "<span class='tut_title'>".$titel."</span><br>";
			echo nl2br($tutorial);
			echo formatPHP(nl2br($tutorial));
			echo "<hr noshade>";
			echo "<a href='?page=tutorials&tut=".$_GET['tut']."'>Terug naar ".$tut." tutorial menu</a><br>"; 
			echo "<a href='?page=tutorials'>Terug naar tutorial menu</a>";

Hij haalt het dus prima uit de database, maar hij voert de formatPHP niet uit.

Ik heb ook een probeersel gedaan door direct onder de functie, dus zonder in de if's, een formatPHP() uit te voeren en dan doet hij het wel goed.

De regel die ik direct onder de functie heb staan is die jij ook als voorbeeld had gedaan:

PHP:
$bericht = '[ php]<? $var = 1;[ /php] en de rest van mijn [ php]//bericht $test[ /php] en nog [ php]$meer; ?>[ /php]';
echo formatPHP($bericht);

met natuurlijk die php tags zonder die spaties.

Of ik maak een klein foutje dat ik niet zie, of hij wil niet in de if ofzo werken, maar ik hoor het graag!

Gr. Ronald!:)
 
En wat gebeurd er wanneer je de variabele bericht ook binnen de IF-statements laat uitvoeren? (Dus direct onder de functie $bericht aanmaken en deze later uitvoeren.

Je code wordt dan zo (inclusief een extra witregel tussen de "normale" tutorial en degene met PHP-kleurtjes)
PHP:
            $id = $rij['id']; 
            $titel = $rij['titel']; 
            $tutorial = nl2br($rij['tutorial']);
            $phpTutorial = formatPHP($tutorial);
            //Errorchecking
            $bericht = formatPHP($bericht);
            // end errorchecking
            echo '<span class="tut_title">'. $titel .'</span><br>
            '. $tutorial .'<br /><br />'. $phpTutorial .'<br /><br />'. $bericht .'
            <hr noshade /> 
            <a href="?page=tutorials&tut='. $_GET['tut'] .'">Terug naar '. $tut .' tutorial menu</a><br />
            <a href="?page=tutorials">Terug naar tutorial menu</a>';
Mocht het nu nog niet lukken zou je dan de volledige code hier willen plaatsen?
 
$tutorial en $phpTutorial geeft hij gewoon weer, samen met de php tags. Dus niet highlighted.

$bericht daarentegen, die heb ik onder de functie staan en dan zoals jij zegt er later een formatPHP($bericht) van doen, die doet het wel.

Dus ik krijg bijvoorbeeld:

Dit is een tutorial om zelf functies te maken.

[ php]
function som($num1,$num2){
$som = $num1 + $num2;
return $som;
}

echo som(4,9);
[ /php]

Dit echoot: 13 (4 + 9)

---------------------------------------------------------------------------------------------------------------

Dit is een tutorial om zelf functies te maken.

[ php]
function som($num1,$num2){
$som = $num1 + $num2;
return $som;
}

echo som(4,9);
[ /php]

Dit echoot: 13 (4 + 9)

---------------------------------------------------------------------------------------------------------------

<? $var = 1; ?> en de rest van mijn <?php //bericht $test ?> en nog <?php $meer; ?>

-----------------------------------------------------------------------------------------------------------------

Deze drie waren het. De eerste 2 niet highlighted en met die tags weer zonder spaties. En die laatste geeft ie wel highlighted weer.
 
Het probleem zat hem in het escapen van bepaalde characters.

Dit rijtje moest er nog even bij ; ( ) * + :)

Als het goed is moet het met deze functie lukken:
HTML:
function formatPHP($string) {
  $escapeChars = array(
    "[" => "\[",
    "]" => "\]",
    "/" => "\/",
    "<" => "\<",
    ">" => "\>",
    "$" => "\\$",
    "?" => "\?",
    ";" => "\;",
    "(" => "\(",
    ")" => "\)",
    "*" => "\*",
    "+" => "\+",
  );
  if(preg_match_all("/\[php\](.+)\[\/php\]/Usi", $string, $matches)) {
    $count = 0;
    foreach($matches[0] AS $value) {
      if(preg_match("/\[php\]\<\? (.+)\?\>\[\/php\]/Usi", $value)) {
        $returns[] = preg_replace("/\[php\](.+)\[\/php\]/Usie", "highlight_string('\\1', true)", $value);
      } elseif(preg_match("/\[php\](.+)\?\>\[\/php\]/Usi", $value)) {
        $returns[] = preg_replace("/\[php\](.+)\[\/php\]/Usie", "highlight_string('<?php \\1', true)", $value);
      } elseif(preg_match("/\[php\]\<\?(.+)\[\/php\]/Usi", $value)) {
        $returns[] = preg_replace("/\[php\](.+)\[\/php\]/Usie", "highlight_string('\\1 ?>', true)", $value);
      } else {
        $returns[] = preg_replace("/\[php\](.+)\[\/php\]/Usie", "highlight_string('<?php \\1 ?>', true)", $value);
      }
      foreach($escapeChars AS $char => $rep) {
        $value = str_replace($char, $rep, $value);
      }
      $matches[0][$count] = '/'. $value .'/';
      $count++;
    }
    $result = preg_replace($matches[0], $returns, $string);
  } else {
    $result = $string;
  }
  return $result;
}
 
Laatst bewerkt:
Oke ik moet nu weg, ik ga het vanavond even proberen en laat je weten of het werkt!

Bedankt zover:thumb:.

Gr. Ronald!:)
 
Hij doet het nu met het highlighten!:thumb:

Maar omdat ik het onder elkaar wil zetten, dus precies weergeven zoals ik het in de DB heb gezet doe ik een nl2br(), anders staat het naast elkaar, maar nu krijg ik achter de tekst overal <br /> te staan.

Weet je hoe ik dit moet oplossen?

PHP:
<?php <br /> 
function som($num1,$num2){<br /> 
    $som = $num1 + $num2;<br /> 
    return $som;<br /> 
}<br /> 
<br /> 
echo som(4,9);<br /> 
?>

Vast bedankt,

Gr. Ronald!:)
 
Binnen higlight_string hoef je geen nl2br te gebruiken.

Je kunt het oplossen door na $escapeChars
PHP:
$string = str_replace('<br />', '', $string);
te zetten.

Blijkt niet te werken, houdt je hetzelfde probleem. Ben er mee bezig...
 
Laatst bewerkt:
Nieuwe poging:

Nieuwe functionaliteit toegevoegd:
Je kunt nu specifiek aangeven of je nl2br wilt gebruiken of niet. Hierdoor blijft de input zonder <br /> maar krijg je toch het goede resultaat.

HTML:
<?php
function formatPHP($string, $breakline) {
  $escapeChars = array(
    "[" => "\[",
    "]" => "\]",
    "/" => "\/",
    "<" => "\<",
    ">" => "\>",
    "$" => "\\$",
    "?" => "\?",
    ";" => "\;",
    "(" => "\(",
    ")" => "\)",
    "*" => "\*",
    "+" => "\+"
  );
  if(preg_match_all("/\[php\](.+)\[\/php\]/Usi", $string, $matches)) {
    $count = 0;
    foreach($matches[0] AS $value) {
      if(preg_match("/\[php\]\<\?(.+)\?\>\[\/php\]/Usi", $value)) {
        $returns[] = preg_replace("/\[php\](.+)\[\/php\]/Usie", "highlight_string('\\1', true)", $value);
      } elseif(preg_match("/\[php\](.+)\?\>\[\/php\]/Usi", $value)) {
        $returns[] = preg_replace("/\[php\](.+)\[\/php\]/Usie", "highlight_string('<?php \\1', true)", $value);
      } elseif(preg_match("/\[php\]\<\?(.+)\[\/php\]/Usi", $value)) {
        $returns[] = preg_replace("/\[php\](.+)\[\/php\]/Usie", "highlight_string('\\1?>', true)", $value);
      } else {
        $returns[] = preg_replace("/\[php\](.+)\[\/php\]/Usie", "highlight_string('<?php \\1?>', true)", $value);
      }
      foreach($escapeChars AS $char => $rep) {
        $value = str_replace($char, $rep, $value);
      }
      $matches[0][$count] = '/'. $value .'/';
      $count++;
    }
    $result = preg_replace($matches[0], $returns, $string);
  } else {
    $result = $string;
  }
  if(isset($breakline) && $breakline == true) {
    return nl2br($result);
  } else {
    return $result;
  }
}
$bericht = '[php]<?p
function som($var1, $var2){
 $som = $num1 / $num2;
};
$var = 1;
echo ($var, 1);?>
<html>
<? test() ?>[/php]
en de
rest van mijn
[php]//bericht;
$test;[/php] en nog [php]$meer; ?>[/php]';

$bericht2 = '[php]
function som($num1,$num2){
  $som = $num1 + $num2;
return $som;
}

echo som(4,9);
// Resultaat: 13
[/php]';
echo formatPHP($bericht, true);
echo formatPHP($bericht2, true);
?>
 
Als ik die breakline op false zet doet hij het wel gewoon met enters, sorry dat ik dat niet eerst geprobeerd had, maar dat doet hij dus nu. Het enige nu nog is het volgende:

En dan zit ik met nog wat. Bij dat preg_replace() kijkt hij dus naar wat er in de tekst staat, maar hij kijkt alleen naa <? als begin, niet naar <?php. Dus ik had dit zelf toegevoegd, maar hij wil het op een of andere manier niet doen. Zie jij misschien de fout?

PHP:
      } elseif(preg_match("/\[php\]\<\?php(.+)\[\/php\]/Usi", $value)) {
	$returns[] = preg_replace("/\[php\](.+)\[\/php\]/Usie", "highlight_string('\\1?>', true)", $value);
      } elseif(preg_match("/\[php\]\<\?php(.+)\?\>\[\/php\]/Usi", $value)) {
	$returns[] = preg_replace("/\[php\](.+)\[\/php\]/Usie", "highlight_string('\\1', true)", $value);

ik had hierboven $returns[[, maar nu laat hij alsnog 2x <?php en ?> zien, dus:

PHP:
<?php 

<?php 

function som($num1,$num2){

    $som = $num1 + $num2;

    return $som;

}



echo som(4,9);

?>

?>

Bedankt,

Gr. Ronald!:)
 
Laatst bewerkt:
PHP:
if(preg_match("/\[php\]\<\?php(.+)\?\>\[\/php\]/Usi", $value)) {
        $returns[] = preg_replace("/\[php\](.+)\[\/php\]/Usie", "highlight_string('\\1', true)", $value);
      } elseif(preg_match("/\[php\](.+)\?\>\[\/php\]/Usi", $value)) {
        $returns[] = preg_replace("/\[php\](.+)\[\/php\]/Usie", "highlight_string('<?php \\1', true)", $value);
      } elseif(preg_match("/\[php\]\<\?php(.+)\[\/php\]/Usi", $value)) {
        $returns[] = preg_replace("/\[php\](.+)\[\/php\]/Usie", "highlight_string('\\1?>', true)", $value);
      } else {
        $returns[] = preg_replace("/\[php\](.+)\[\/php\]/Usie", "highlight_string('<?php \\1?>', true)", $value);
      }
Probeer die eens, ik krijg er geen problemen mee...
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan