/PHP5 - kleines News-CMS mit simplexml
Andreas Korthaus
- xml
Hallo!
Bin gerade mal dabei mit der simplexml Extension von PHP5 "zu spielen". Ich versuche gerade mal, ein möglichst einfaches News-CMs zu schrieben. Die News sollen in einer XML-Datei gespeichert sein, es soll die Möglichkeit geben, die Titel der letzten 5 News auszugeben, und die gesamten News entweder auf jeweils einer Seite, oder aller auf eine Seite (mit Pager...).
Ich hab mir mal folgende XML-Struktur überlegt:
<?xml version="1.0" encoding="ISO-8859-1"?>
<news>
<item id="32" public="1">
<title>news #32</title>
<description>Newstext...</description>
<timestamp>1234567890</timestamp>
<author>Andreas Korthaus</author>
</item>
<item id="31" public="0">
<title>news #31</title>
<description>Newstext....</description>
<timestamp>1234567890</timestamp>
<author>Andreas Korthaus</author>
</item>
</news>
Per PHP (5) kann ich das Dank simplexml jetzt wie folgt einlesen:
<?php
$newsfile = 'news.xml';
if (!file_exists($newsfile)) {
exit("Fehler: $newsfile konnte nicht geoeffnet werden");
}
else {
$xml = simplexml_load_file($newsfile);
foreach ($xml->item as $news) {
echo $news->title."($news[id])\n";
}
}
?>
Die Sache hat nur einen Haken: Ich kann zwar dem $xml Objekt weitere Item-Objekte hinzufügen, aber ich wüsste jetzt nicht, wie ich die sauber am Anfang einfüge, so dass die neusten News immer oben stehen. Was wäre hier ein effizienter Weg, die 5 neusten News abzufragen, oder eben - wie würde man elegant neue News _vor_ den anderen News in die XML-Datei einbauen?
Nachdem ich das Objekt manipuliert habe, kann ich es wieder recht einfach in die Datei schreiben:
<?php
$xml->asXML($newsfile);
?>
Hat jemand von Euch ne Idee wie man das elegant löst? Performance ist hier weniger wichtig, weil die XML-Datei in absehbarer Zeit keine nennenswerte Größe annehmen wird.
Viele Grüße
Andreas
PS: wenn die XML-Struktur schwachsinnig/ausbaufähig ist - schont mich nicht ;-)
Hallo,
Die Sache hat nur einen Haken: Ich kann zwar dem $xml Objekt weitere Item-Objekte hinzufügen, aber ich wüsste jetzt nicht, wie ich die sauber am Anfang einfüge, so dass die neusten News immer oben stehen.
jo mei, ich hab mich da noch gar nicht mit beschäftigt, mit diesem ganzen PHP5 Kram, also warum fragst Du ausgerechnet mich? ;-) Aber es sieht doch so aus, als sei "$xml->item" ein indiziertes Array? Hast Du das mal mit print_r($xml->item) ausgegeben?
Wenn das stimmt, kannst Du doch array_unshift($xml->item, mixed var [, mixed ...]) nehmen.
Gruß, Andreas
Hi!
jo mei, ich hab mich da noch gar nicht mit beschäftigt, mit diesem ganzen PHP5 Kram, also warum fragst Du ausgerechnet mich? ;-) Aber es sieht doch so aus, als sei "$xml->item" ein indiziertes Array? Hast Du das mal mit print_r($xml->item) ausgegeben?
Naja, bei simplexml ist es irgendwie ein Zwitter, sowohl Array als auch Objekt. Das ist zwar praktisch weil es sehr einfach funktioniert, aber anfangs etwas verwirrend ;-)
Grüße
Andreas
Naja, bei simplexml ist es irgendwie ein Zwitter, sowohl Array als auch Objekt. Das ist zwar praktisch weil es sehr einfach funktioniert, aber anfangs etwas verwirrend ;-)
was kommt denn raus, wenn Du print_r($xml->item) ausgibst?
Gruß, Andreas
Naja, bei simplexml ist es irgendwie ein Zwitter, sowohl Array als auch Objekt. Das ist zwar praktisch weil es sehr einfach funktioniert, aber anfangs etwas verwirrend ;-)
was kommt denn raus, wenn Du print_r($xml->item) ausgibst?
<?php
header ('Content-Type: text/plain');
$xml = simplexml_load_file('news.xml');
print_r($xml);
?>
SimpleXMLElement Object
(
[item] => Array
(
[0] => SimpleXMLElement Object
(
[title] => news #32
[description] => Newstext...
[timestamp] => 1234567890
[author] => Andreas Korthaus
)
[1] => SimpleXMLElement Object
(
[title] => news #31
[description] => Newstext....
[timestamp] => 1234567890
[author] => Andreas Korthaus
)
)
)
Wobei 0 und 1 für die beiden "item"s stehen. Allerdings haben diese Elemente noch Attibute, id und public. Diese werden hier nicht dargestellt, sind aber vorhanden, siehe Code im 1. Posting.
Grüße
Andreas
Wobei 0 und 1 für die beiden "item"s stehen.
eben, also richtig vermutet: ein indiziertes Array. Das Einfügen von neuen Elementen dürfte also nicht so schwierig sein...
Allerdings haben diese Elemente noch Attibute, id und public. Diese werden hier nicht dargestellt, sind aber vorhanden, siehe Code im 1. Posting.
das scheint mir das eigentliche Problem. Wie bekommt man die Attribute in so ein neues Element rein? Aber die mußt Du doch auch irgendwie auslesen können, sonst sind die ja witzlos. Wenn Du z.B. sowas auslesen kannst:
<?
echo $xml->item[0][id];
oder
echo $xml->item[0]->getAttribut('id');
?>
Ausgabe: 32
(so'ne ähnliche Abfrage machst du doch auch im Ausgangsposting: echo $news->title."($news[id])\n";)
Dann kannst Du es ja auch verändern. Und das könnstest Du mit den neu eingefügten Elementen _nachträglich_ machen. Nur mal so ne Idee, hehe...
Gruß, Andreas
Hi!
Wobei 0 und 1 für die beiden "item"s stehen.
eben, also richtig vermutet: ein indiziertes Array. Das Einfügen von neuen Elementen dürfte also nicht so schwierig sein...
Naja, es ist wie gesagt so eine besondere Datenstruktur. Lesen und Maipulieren ist kein Problem, aber wie es aussieht - hinzufügen wohl schon.
Allerdings haben diese Elemente noch Attibute, id und public. Diese werden hier nicht dargestellt, sind aber vorhanden, siehe Code im 1. Posting.
das scheint mir das eigentliche Problem.
ja.
Wie bekommt man die Attribute in so ein neues Element rein? Aber die mußt Du doch auch irgendwie auslesen können, sonst sind die ja witzlos. Wenn Du z.B. sowas auslesen kannst:
<?
echo $xml->item[0][id];
oder
echo $xml->item[0]->getAttribut('id');
?>Ausgabe: 32
(so'ne ähnliche Abfrage machst du doch auch im Ausgangsposting: echo $news->title."($news[id])\n";)
ja,
(string) $xml->item[0]['id']
Wenn ich jetzt mal folgendes probiere:
$xml = simplexml_load_file($newsfile);
$xml->item[1]->title='hallo';
echo $xml->asXML();
erhalte ich:
<?xml version="1.0" encoding="ISO-8859-1"?>
<news>
<item id="32" public="1">
<title>news #32</title>
<description>Newstext...</description>
<timestamp>1234567890</timestamp>
<author>Andreas Korthaus</author>
</item>
<item id="31" public="0">
<title>hallo</title>
<description>Newstext....</description>
<timestamp>1234567890</timestamp>
<author>Andreas Korthaus</author>
</item>
</news>
Und wenn ich dann folgendes probiere:
$xml = simplexml_load_file($newsfile);
$xml->item[2]->title='hallo';
echo $xml->asXML();
erhalte ich:
Fatal error: Objects used as arrays in post/pre increment/decrement must return values by reference
Wird dann wohl nur per DOM gehen.
Dann kannst Du es ja auch verändern.
Woraus schließt Du das?
Und das könnstest Du mit den neu eingefügten Elementen _nachträglich_ machen. Nur mal so ne Idee, hehe...
Ich wüßte nicht wie das funktionieren könnte.
Außerdem kann ich mich irgendwie nicht so richtig mit XML als Format für derartige Datenhaltung (das gilt auch für dieses Forum ;-)) anfreunden. (und das trotz
http://www.amazon.de/exec/obidos/ASIN/3772360203/ ;-))
Grüße
Andreas
Und wenn ich dann folgendes probiere:
$xml = simplexml_load_file($newsfile);
$xml->item[2]->title='hallo';
müsste denn hier nicht erstmal ein neues Objekt vom Typ '$xml->item' erstellt werden? 'item[2]' existiert doch gar nicht. z.B. so:
array_push($xml->item, $xml->item[1]);
$xml->item[2]->title='hallo';
gibt's bestimmt auch ne Funktion für. Man müßte ja eigentlich auch ein Objekt von der Klasse kopieren können, von der auch $xml->item[1...n] abgeleitet sind. Was sagt denn 'get_class($xml->item[1])' bzw. 'get_class($xml->item)'?
Dann kannst Du es ja auch verändern.
Woraus schließt Du das?
Lebenserfahrung ;-)
nein im Ernst: $xml->item[0]['id'] ist nach seiner Schreibweise doch ein Element aus einem assoziativen Array. Und da kann man doch einfach einen neuen Wert zuweisen: $xml->item[0]['id'] = '33'
Also, ich stell mir das jetzt so vor:
$xml->item[1] ist einerseits ein Objekt mit Eigenschaften (die inneren Elemente):
->title
->description
...etc.
und andererseits auch ein assoziatives Array (die Attribute):
['id']
['public']
Und das könnstest Du mit den neu eingefügten Elementen _nachträglich_ machen. Nur mal so ne Idee, hehe...
Ich wüßte nicht wie das funktionieren könnte.
nachdem Du das neue Objekt erstellt hast (s.o.):
$xml->item[2]['id'] = '33'
Außerdem kann ich mich irgendwie nicht so richtig mit XML als Format für derartige Datenhaltung (das gilt auch für dieses Forum ;-)) anfreunden.
hehe, geht mir ähnlich ;-) Die Zitatesammlung muß ich ja auch in XML schreiben - furchtbar!
(und das trotz
http://www.amazon.de/exec/obidos/ASIN/3772360203/ ;-))
mit diesen Hot&Spicy-Büchern kann ich auch nicht so richtig was anfangen. Ich habe "Grundkurs Computerpraxis" (rororo) - find ich ganz gut.
Gruß, Andreas
Hi!
(und das trotz
http://www.amazon.de/exec/obidos/ASIN/3772360203/ ;-))mit diesen Hot&Spicy-Büchern kann ich auch nicht so richtig was anfangen. Ich habe "Grundkurs Computerpraxis" (rororo) - find ich ganz gut.
So war das nicht gemeint ;-)
Das Buch ist wirklich wunderbar und hat mir schon sehr geholfen - nur leider enthält es kein Kapitel zum Thema "XML zur Datenhalten" oder sowas ;-)
Grüße
Andreas
PS: Guck Dir das Buch nochmal genauer an, z.B. auch dessen Autor - da kann man durchaus was erwarten :)