Du må være registrert og logget inn for å kunne legge ut innlegg på freak.no
X
LOGG INN
... eller du kan registrere deg nå
Dette nettstedet er avhengig av annonseinntekter for å holde driften og videre utvikling igang. Vi liker ikke reklame heller, men alternativene er ikke mange. Vær snill å vurder å slå av annonseblokkering, eller å abonnere på en reklamefri utgave av nettstedet.
  8 1058
Driver for tiden og utvikler et bbcode-system på en webside, men har støtt på et problem som tydligvis ikke lar seg løse (les: av meg, that is).

Nettsiden skal ha mulighet for å poste kildekoder med syntax highlighting.
Jeg bruker PEAR og pakken Text_Highlighter.

Nå over til problemet:

Kode

function sourceCodeHighlight ($str) {
$search = '/\[code=(.*?)\](.*?)\[\/codearea\]/is';

// Define the class
$highlighter =& Text_Highlighter::factory("$1");
// Call highlight method to display the code to web browser
$replace = $highlighter->highlight("$2"); 


$codeHighlighted = preg_replace($search, $replace, $str);
return $codeHighlighted;
}
Hva er det jeg gjør feil i koden over? Text_Highlighter klarer nemlig ikke å ta i mot variablene $1 og $2.
Når jeg tester koden over får jeg følgende feilmelding:

Kode

Fatal error: Call to undefined method PEAR_Error::highlight() in C:\xampp\htdocs\bbcode.php on line 89

Men hvis jeg kjører funksjonen direkte (les: uten bruk av variabler) fungerer det:

Kode

function sourceCodeHighlight ($str) {
$search = '/\[code=(.*?)\](.*?)\[\/codearea\]/is';

// Define the class
$highlighter =& Text_Highlighter::factory("mysql");
// Call highlight method to display the code to web browser
$replace = $highlighter->highlight("SELECT * FROM some_table WHERE id = 12"); 


$codeHighlighted = preg_replace($search, $replace, $str);
return $codeHighlighted;
}

Er det noen som har mer peiling enn meg som kan forklare meg hva som forårsaker feilmeldingen, og hvordan dette evt. skal la seg ordne?

På forhånd, takk
Text_Highlighter::factory returerer en PEAR_Error, og du prøver å kalle highlight() på den.

Sjekk alltid om du har korrekte variabler (dvs. om det har skjedd noe feil).

skal jeg gjette er det regexen som er feil og returnerer noe annet enn det du tror :-)

Og ihvertfall i andre språk skal du ikke bruke "" rundt $1 $2 osv når du bruker regexp matches. Da sender du vel bare "$1" til Text_Highlighter::factory().
m0b
m0b's Avatar
DonorAdministrator
Det er en feil med metoden factory(string), som gir deg en instans av klassen PEAR_Error i objektet $highlighter. PEAR_Error har trolig ikke metoden highlight(string), og dermed får du en feil på det.

Hva er $1? Er dette noe som er initialisert og lagt til i factoriet så den kan gjenkjennes og opprette instans av korrekt objekt med definisjoner for språket "$1"?

(Factory pattern er forresten noe rimelig herlig )
Sist endret av m0b; 28. august 2010 kl. 18:25.
s1gh's Avatar
Trådstarter
Slik jeg har forstått det skal dette returnere to variabler:
$search = '/\[code=(.*?)\](.*?)\[\/code\]/is';

Den første blir $1 og den andre $2.
Nå kan det godt tenkes at jeg har misforstått hele konseptet, og at det er dette som forårsaker feilmeldingen.

Men nå skal det også nevnes at det er slik jeg har gjort det i resten av bbcode-koden, og det fungerer strålende.

Eksempel:

Kode

<?php
function bbcode_replace($str) {
	$search = array(  
		'/\[b\](.*?)\[\/b\]/is', 
		'/\[i\](.*?)\[\/i\]/is', 
		);
	
	$replace = array(  
		'<strong>$1</strong>',  
		'<em>$1</em>',
		);
 
	$str = preg_replace($search, $replace, $str);  
	return str;
}
?>
Sist endret av s1gh; 28. august 2010 kl. 18:33.
Er det forskjell på hvordan PHP behandler ' og " ? Evt. print ut infoen i $1 og $2 så du kan se hva som går inn i funksjonen. Da ser du jo straks hva som går feil.
m0b
m0b's Avatar
DonorAdministrator
Å initialisere en variabel ved navn $search med en tilfeldig regexp gir deg vel ikke automagisk to variabler som heter $1 og $2, det nekter jeg å tro. I så tilfelle ville dette funket.

Kode

function foo() 
{
   $search = '/\[code=(.*?)\](.*?)\[\/code\]/is'; 
   echo $1 . ' ' . $2;
}
Det gjør det naturligvis ikke. I stacket til metoden sourceCodeHighlight har du fire variabler. $search, $highlighter, $replace og $codeHighlighted. Vi kartla at $1 og $2 ikke automagisk vil eksistere ved å legge inn en regexp i en variabel. Så det betyr at variabelen $1 må komme inn i kontekst etter første { og den linja som du deklarerer og initialiserer objektet $highlighter. Hva har du igjen, hvis du ekskluderer $search? Jo. Whitespace. Oppstår $1 og $2 der? Lite trolig

Static-funksjonen factory i klassen Text_Highlighter mottar en streng som key for å finne ut hvilken klasse den skal instansiere og returnere som referanse til objektet $highlighter. Hvis den ikke finner en key som eksisterer (altså, en klasse for det gitte argumentet) så vil den returnere klassen PEAR_Error. Slik du har satt det opp nå gir du metoden strengen "$1" som argument, og jeg ser for meg at det er det ikke noe som heter det i lista som factory har.

Det du må gjøre, er å fullføre regexpen din (mellom $search og $highlighter) og så mate det resultatet inn i factory, selvfølgelig etter å ha sjekket at du har fått matches. Deretter sjekker du om instansen av objektet returnert er som forventet, og så går du videre med replacinga.

Flexd: Ja, det er forskjell. Single quote er literal string. Special characters vil ikke bli tolket, men det vil de med double quote. Men det er nok ikke der problemet ligger her.
Sist endret av m0b; 28. august 2010 kl. 19:00.
Jeg vet ikke hvordan dette biblioteket fungerer, men $1 og $2 vil vel ikke være tilgjengelig der du bruker de? Du har tross alt kun derfinert regexp pattern som en string, uten å kjøre den i en preg_match/replace.

Du kan jo se om du får dette til å fungere

[code]<?php
function sourceCodeHighlight ($str) {

// Klar over du at starter med

Kode

 og lukker med [/codearea] ?
	$search = '/\[code=(.*?)\](.*?)\[\/codearea\]/is';
	
	preg_match($search, $str, $match);
	
	// Define the class
	$highlighter =& Text_Highlighter::factory($match[1]);
	
	// Call highlight method to display the code to web browser
	$replace = $highlighter->highlight($match[2]); 
	
	$codeHighlighted = preg_replace($search, $replace, $str);
	
	return $codeHighlighted;
}
Edit: |d13m0b var litt raskere ute
Sist endret av ma10as; 28. august 2010 kl. 19:00.
s1gh's Avatar
Trådstarter
Takk for svar, men før jeg rakk å sjekke tråden hadde jeg funnet ut av det. Det var jo selvfølgelig jeg som hadde misforstått alt.
Brukte preg_match for å se om jeg fant noe som matchet og utførte deretter en preg_replace - noe dere også har foreslått ser jeg.

Endte opp med følende kode:

Kode

function sourceCodeHighlight ($str) {

	if (preg_match("/\[code=(.*?)\](.*?)\[\/code\]/is", $str, $matches)) {
	
	// Define the class
	$highlighter =& Text_Highlighter::factory($matches[1]);
	//Call highlight method to display the code to web browser
	$highlightedCode = $highlighter->highlight($matches[2]); 
	return preg_replace("/\[code=(.*)\](.*?)\[\/code\]/is", $highlightedCode, $str);
	} 
	else {
		return $str;
	}
}
Uansett, takk for svar, folkens
Sist endret av s1gh; 28. august 2010 kl. 19:21.
Sitat av |d13m0b Vis innlegg
Å initialisere en variabel ved navn $search med en tilfeldig regexp gir deg vel ikke automagisk to variabler som heter $1 og $2, det nekter jeg å tro. I så tilfelle ville dette funket.

Kode

function foo() 
{
   $search = '/\[code=(.*?)\](.*?)\[\/code\]/is'; 
   echo $1 . ' ' . $2;
}
Det gjør det naturligvis ikke. I stacket til metoden sourceCodeHighlight har du fire variabler. $search, $highlighter, $replace og $codeHighlighted. Vi kartla at $1 og $2 ikke automagisk vil eksistere ved å legge inn en regexp i en variabel. Så det betyr at variabelen $1 må komme inn i kontekst etter første { og den linja som du deklarerer og initialiserer objektet $highlighter. Hva har du igjen, hvis du ekskluderer $search? Jo. Whitespace. Oppstår $1 og $2 der? Lite trolig

Static-funksjonen factory i klassen Text_Highlighter mottar en streng som key for å finne ut hvilken klasse den skal instansiere og returnere som referanse til objektet $highlighter. Hvis den ikke finner en key som eksisterer (altså, en klasse for det gitte argumentet) så vil den returnere klassen PEAR_Error. Slik du har satt det opp nå gir du metoden strengen "$1" som argument, og jeg ser for meg at det er det ikke noe som heter det i lista som factory har.

Det du må gjøre, er å fullføre regexpen din (mellom $search og $highlighter) og så mate det resultatet inn i factory, selvfølgelig etter å ha sjekket at du har fått matches. Deretter sjekker du om instansen av objektet returnert er som forventet, og så går du videre med replacinga.

Flexd: Ja, det er forskjell. Single quote er literal string. Special characters vil ikke bli tolket, men det vil de med double quote. Men det er nok ikke der problemet ligger her.
Vis hele sitatet...
Ah.. Jeg er bare vant med at jeg kan gjøre sånt i Ruby. $1-$n (antall captures) blir automagisk definert i Ruby når du matcher :-)