preg_replace bringt keine Veränderung

ThoRr

Mitglied
Hi,

ich habe ein höchst seltsames Problem. In einer includeten Datei habe ich eine Funktion, die eine Datei einliest und dann in dieser Ersetzungen mittels preg_replace vornimmt. Allerdings zeigt preg_replace an dieser Stelle überhaupt keine Wirkung.

PHP:
	// Generate the menu
	$file = ROOT_PATH . DESIGN_PATH . '/menu.html';
	$file_handle = fopen($file, 'r');
	$file_menu = fread($file_handle, filesize($file));
	fclose($file_handle);
	
	if (preg_match('/<!-- BEGIN menuitem -->(.*)<!-- END menuitem -->/', $file_menu, $matches))
	{
		// Menu item "Startseite"
		$pattern = array(
			'/\{menuitem.HREF\}/',
			'/\{menuitem.TEXT\}/');
		$replace = array(
			'?sel=home',
			'Startseite');
		$menu_items = preg_replace($pattern, $replace, $matches[1]);
		
		// Menu item "Seiten"
		$pattern = array(
			'/\{menuitem.HREF\}/',
			'/\{menuitem.TEXT\}/');
		$replace = array(
			'?sel=pages',
			'Seiten');
		$menu_items .= preg_replace($pattern, $replace, $matches[1]);
	}
	
	$file_menu = preg_replace('/.*/', '', $file_menu, null, $count);
	
	echo($file_menu . $count);

Das ist nicht der Originalcode, sondern ich war in meiner Fehlersuche schon so weit, dass ich einfach mal versucht habe, den ganzen String mittels .* zu erfassen. Allerdings hat auch das nichts gebracht. Übrigrens gelangt PHP auch nicht in die if-Schleife, obwohl in dem Dateiinhalt sich genau das vorfindet, was ich im Pattern notiert habe.

Generell an meiner Serverkonfiguration kann es nicht liegen, da dieser Minimalcode ohne Probleme funktioniert:
PHP:
<?php

$pattern = '/.*/';
$replacement = '';
$subject = 'Text';

$subject = preg_replace($pattern, $replacement, $subject);

echo($subject);

?>

LG
 
Hallöle,

meines Erachtens nach liegt das daran, dass du die Datei im Modus "r" öffnest, der dich nur zum Lesen der Datei berechtigt.
Willst du hingegen lesen und schreiben, dann solltest du vllt. "r+" oder "w+" benutzen:


PHP:
$file_handle = fopen($file, 'r+');

oder

PHP:
$file_handle = fopen($file, 'w+');

Hoffe der Ansatz bringt dir was und noch 'n schönen Abend.
 
Ich habe gleich mehrere Fragen:

1. Welcher von den preg_replaces geht denn genau nicht wie er soll?
2. Du möchtest wirklich zwei mal $matches[1] replacen? Wie soll das gehen?
3. Kannst du mal den Originalcode zeigen, außerdem die menu.html anhängen und ein Beispiel, wie es aussehen soll, wenn das ganze ersetzt ist?

@Alex_T: Er versucht doch gar nicht, die Datei neu zu schreiben, der gibt die geänderten Daten mit echo aus...
 
Hallo Alex,

danke für deine Antwort.

Allerdings ist dies nicht das Problem - ich möchte den Inhalt der Datei lediglich verändert ausgeben. Wenn ich preg_replace in eine Variable schreiben lasse, wieviele Ersetzungen durchgeführt worden sind, dann ist die Zahl unerklärlicherweise 0 - dabei bedeuet ja .* beliebig viele Zeichen oder keines, sodass eigentlich alle Fälle abegedeckt wären. Trotzdem wird auf dieses Suchmuster nichts gefunden.

Edit:
Oh, da ist noch eine Antwort eingegangen, während ich geschrieben habe.

Stimmt, da sind mehrere preg_replaces - sorry, ich war zu sehr mit dem Schreiben beschäftigt und dachte, da wäre nur dieser eine. Es handelt sich um den letzten.

Ich verwende zweimal $matches[1] als Quelle für die Funktion. Das, was hinterher rauskommt, hänge ich an die $menu_items-Variable an. Dieser Teil ist jedoch ungetestet, da die if-Bedingung fälschlicherweise falsch ist.

Die menu.html sieht folgendermaßen aus:
HTML:
<div class="navigation">
	<h2>Navigation</h2>
	<ul class="navigation-list">
		<!-- BEGIN menuitem --><li><a href="{menuitem.HREF}">{menuitem.TEXT}</a></li>
		<!-- END menuitem -->
	</ul>
</div>

<div class="content">

Komischerweise funktioniert der (unterste) preg_replace auch dann nicht, wenn ich ihm nur "Beispieltext" als subject gebe.
 
Zuletzt bearbeitet:
Echt mysteriös - füge ich meinen Testcode von oben an die Stelle ein, dann arbeitet er, wie auch in der Testdatei alleine. Daher dachte ich, dass es vielleicht, warum auch immer, an der $files_menu-Variable läge. Wenn ich allerdings folgenden Code nehme, dann funktioniert es auch nicht:

PHP:
/**
 * Output page header
 */
function page_header()
{
	require(ROOT_PATH . DESIGN_PATH . '/header.html');
	
	// Generate the menu
	$file = ROOT_PATH . DESIGN_PATH . '/menu.html';
	$file_handle = fopen($file, 'r');
	$file_menu = fread($file_handle, filesize($file));
	fclose($file_handle);
	
	if (preg_match('/<!-- BEGIN menuitem -->(.*)<!-- END menuitem -->/', $file_menu, $matches))
	{
		// Menu item "Startseite"
		$pattern = array(
			'/\{menuitem.HREF\}/',
			'/\{menuitem.TEXT\}/');
		$replace = array(
			'?sel=home',
			'Startseite');
		$menu_items = preg_replace($pattern, $replace, $matches[1]);
		
		// Menu item "Seiten"
		$pattern = array(
			'/\{menuitem.HREF\}/',
			'/\{menuitem.TEXT\}/');
		$replace = array(
			'?sel=pages',
			'Seiten');
		$menu_items .= preg_replace($pattern, $replace, $matches[1]);
	}
	
	$subject = preg_replace('/.*/', '', 'bla', null, $count);
	
	echo($subject . $count);
}
(der untere Teil ist modifiziert)

Zum Vergleich der Code, in dem das unterste preg_replace seine Arbeit korrekt vollrichtet:
PHP:
/**
 * Output page header
 */
function page_header()
{
	require(ROOT_PATH . DESIGN_PATH . '/header.html');
	
	// Generate the menu
	$file = ROOT_PATH . DESIGN_PATH . '/menu.html';
	$file_handle = fopen($file, 'r');
	$file_menu = fread($file_handle, filesize($file));
	fclose($file_handle);
	
	if (preg_match('/<!-- BEGIN menuitem -->(.*)<!-- END menuitem -->/', $file_menu, $matches))
	{
		// Menu item "Startseite"
		$pattern = array(
			'/\{menuitem.HREF\}/',
			'/\{menuitem.TEXT\}/');
		$replace = array(
			'?sel=home',
			'Startseite');
		$menu_items = preg_replace($pattern, $replace, $matches[1]);
		
		// Menu item "Seiten"
		$pattern = array(
			'/\{menuitem.HREF\}/',
			'/\{menuitem.TEXT\}/');
		$replace = array(
			'?sel=pages',
			'Seiten');
		$menu_items .= preg_replace($pattern, $replace, $matches[1]);
	}
	
	$pattern = '/xt/';
	$replacement = '';
	$subject = 'Text';
	
	$subject = preg_replace($pattern, $replacement, $subject);
	
	echo($subject);
	/*$file_menu = preg_replace('/.*\/', '', 'bla', null, $count);
	
	echo($file_menu . $count);*/
}
 
Inzwischen versteh ich die Welt wieder ein wenig. Anscheinend hat die Funktion den Wert null für limit als 0 interpretiert, wobei ich damit eigentlich den Parameter leer lassen wollte. Aber immerhin funktioniert nun die einfache preg_replace-Ersetzung wieder.

Das Problem mit dem Menü besteht jedoch weiterhin. Diese Stelle:
HTML:
		<!-- BEGIN menuitem --><li><a href="{menuitem.HREF}">{menuitem.TEXT}</a></li>
		<!-- END menuitem -->
soll mittels
PHP:
 $file_menu = preg_replace('/<\!\-\- BEGIN menuitem \-\->.*<\!\-\- END menuitem \-\->/', 
	$menu_items,
	$file_menu);
durch $menu_items ersetzt werden. Allerdings werden keine Vorkommen für das Suchmuster gefunden, was mir unerklärlich ist. Ich habe mindestens zehnmal die Liste mit reservierten Zeichen für reguläre Ausdrücke durchgeschaut und konnte keins davon in meinem Suchmuster entdecken (bis auf -, das aber, so wie ich das verstanden habe, nur innerhalb von eckigen Klammern gilt).

Edit: Ah, ich habe das Problem gefunden. Der Platzhalter . gilt per Standard nicht für eine neue Zeile, die hier aber zwischen den beiden HTML-Kommentaren vorhanden ist. Wie kann ich das ändern?

Edit 2: Ok, das Problem hat sich nun nach Weiterklicken in der Hilfe auch gelöst. Ich muss s hinter den Ending Delimiter setzen. Vielen Dank an Saftmeister und Alex_T für eure Hilfe!
 
Zuletzt bearbeitet:
Zurück