PHP Wie speichere ich das am besten ab?

theHacker

sieht vor lauter Ads den Content nicht mehr
Teammitglied
ID: 69505
L
20 April 2006
22.682
1.316
Hi.

Ich bin am tüfteln und hab schon x-mal alles umgeschrieben, weil ich selber nicht weiß, wie ichs am besten hinkriegt. Vielleicht habt ihr ja die ein oder andere Idee.

Ich möchte Texte speichern, die später mit <p>-, <br />-, <ul>-, <ol>- und <li>-Tags dargestellt werden sollen. Zusätzlich möchte ich jedem Absatz optional noch ein zusätzliches Datum zuordnen.

Meine Überlegung war zuerst, ein Array aufzubauen, das ich später ganz leicht verarbeiten kann.
PHP:
$text = array();
$text[] = array('type' => 'p', 'content' => 'hier Text', 'data' => 42);

$lis = array();
$lis[] = array(array('type' => 'p', 'content' => '1. Aufzählungspunkt', 'data' => 2));
$lis[] = array(array('type' => 'p', 'content' => '2. Aufzählungspunkt', 'data' => 3));
$text[] = array('type' => 'ul', 'content' => $lis);
Is aber unübersichtlich, aufgebläht und schwer zum Aufbauen.

Im Moment denk ich grad drüber nach, eine Art BB-Code zu machen und das Datum quasi als Attribut in den Tag einzubauen:
Code:
[p;42]hier Text[/p]
[ol]
[li][p;2]1.Aufzählungspunkt[/p][/li]
[li][p;3]2.Aufzählungspunkt[/p][/li]
[/ol]
Das Problem, was ich hier sehe, dass das Überprüfen, ob der BB-Code gültig is, aufwändiger wird.
 
Moin

Was ich aus deiner Frage nicht rauslesen kann: Wo willst du speichern? In einer Datei oder in der DB?

Beim Speichern in der DB würde ich 2 Tabellen anlegen. Eine für den Text und eine für die Aufzählungspunkte.

Ist der Aufbau immer gleich? Also der Text steht immer zwischen den <p>-Tags etc.? Dann würd ich die Tags erst bei der Abfrage reinpacken und gar nicht abspeichern. Ob <ul> oder <ol> würde ich in eine Spalte in der Tabelle zum Text zufügen.
Und wo sollen die <br \> hin? Mitten in den Text? Die werden doch mit nl2br übernommen.

Die Tabellen könnten z.B. so aussehen:
texttabelle: id, text, aufzählungstag(ol/ul), timestamp
aufzählungstabelle: textid, aufzählungspunktnummer, text, timestamp(nicht ersichtlich, ob du hierfür auch ein extra datum haben möchtest)

Denke ich vielleicht zu einfach, oder spricht irgendwas Anderes dagegen?

Gruß
Badhuman
 
Ich möchte Texte speichern, die später mit <p>-, <br />-, <ul>-, <ol>- und <li>-Tags dargestellt werden sollen. Zusätzlich möchte ich jedem Absatz optional noch ein zusätzliches Datum zuordnen.

mit Bbcode wird das schon schwerer, falls du ein Änderungsdatum meinst.

also für mich sieht das wie ein Baum aus ;)

Code:
- root
   - p;42
     - hier Text
   - ol
     - li
       - p;2
         - 1.Aufzählungspunkt
     - li
       - p;3
         - 2.Aufzählungspunkt

Das ließe sich dann als NestedSet abspeichern und du könntest zu jedem Element auch noch das Änderungsdatum speichern und es ließen sich nur bestimmte Teile ändern, so wie bei Wikipedia.

Ansonsten eben nen fertigen Bbcode-Parser nutzen, die lassen sich ja meist noch mit eigenem Markup füttern.
 
Was ich aus deiner Frage nicht rauslesen kann: Wo willst du speichern? In einer Datei oder in der DB?
MySQL-Datenbank.
Ist der Aufbau immer gleich? Also der Text steht immer zwischen den <p>-Tags etc.?
Nein, natürlich nicht. Es können auch mal 5 Absätze und keine Aufzählung, oder 2 Aufzählungen mit je 3 Absätzen dazwischen sein.
Du kannst dir nur sicher sein, dass - logischerweise - Texte nur innerhalb von Absätzen existieren kann.

Ich kann dir gerne ne Typ-2-Grammatik dazu angeben :biggrin:
Und wo sollen die <br \> hin? Mitten in den Text? Die werden doch mit nl2br übernommen.
<br />s sind kein Stress, die können eh nur im reinen Text liegen und dort liegen sie als \n vor, also kein Stress.
Die Tabellen könnten z.B. so aussehen:
texttabelle: id, text, aufzählungstag(ol/ul), timestamp
aufzählungstabelle: textid, aufzählungspunktnummer, text, timestamp(nicht ersichtlich, ob du hierfür auch ein extra datum haben möchtest)

Denke ich vielleicht zu einfach, oder spricht irgendwas Anderes dagegen?
Das is Quark, weil ich da keine Reihenfolge mehr hab. Und dann mit sortIds anfangen... nee :-?
Es würde schon Sinn machen, dass "am Stück" alles zu haben, sonst JOIN ich mich dumm und dämlich, wenn ich den Text aus der DB haben will.
mit Bbcode wird das schon schwerer, falls du ein Änderungsdatum meinst.
Kein Änderungsdatum, sondern n allgemeines Datum. Im Prinzip ist es nur eine ID, mittels derer ich aus ner anderen Tabelle noch was an der Ausgabe des Absatzes verändere.
also für mich sieht das wie ein Baum aus ;)
Jupp. Drum hab ich auch ursprünglich mit dem Array rumjongliert, was ja auch nur eine Form des Baums is. Die Idee war dann, das Array einfach serialisiert in die DB werfen und fertig.
Das ließe sich dann als NestedSet abspeichern [...]
Ich muss zugeben, ich hatte mit NestedSets bis jetzt noch nix am Hut, aber so wie ich das aus der Wikipedia rausles, is das doch sehr ähnlich nem binären Suchbaum, oder?
[...] und es ließen sich nur bestimmte Teile ändern, so wie bei Wikipedia.
Ändern wird - denke ich - nicht so häufig vorkommen. Da mach ich mir mehr Sorgen, die UI zu schreiben, als an der Datenstruktur rumzufummeln :mrgreen:
Hauptaktionen werden sein: ein paar wenige Male einfügen und danach nur noch rauslesen, weswegen ich gerne ein einfaches
Code:
[FONT=Courier New][B][COLOR=#9932cc]SELECT[/COLOR][/B] text [B][COLOR=#9932cc]FROM[/COLOR][/B] tabelle [B][COLOR=#9932cc]WHERE[/COLOR][/B] id = 42;[/FONT]
anstreben würde.
Sowas wie absatzweises Lesen/Ändern, was ne Wiki bietet, brauch ich nicht.
Ansonsten eben nen fertigen Bbcode-Parser nutzen, die lassen sich ja meist noch mit eigenem Markup füttern.
Klingt vielversprechend. Hast du ne persönliche Empfehlung parat oder muss ich Google bemühen? :biggrin:

Ich mein, theoretisch könnt ich gleich XML verwenden und mein Datum einfach als
HTML:
<p data="42">...</p>
unterbringen. Trotzdem steh ich dann vor dem Problem, Usereingaben überprüfen zu müssen. Und eine Art BB-Code dürfte dem durchschnittlichen Benutzer wohl von Internetforen am vertrautesten sein.
 
Jupp. Drum hab ich auch ursprünglich mit dem Array rumjongliert, was ja auch nur eine Form des Baums is. Die Idee war dann, das Array einfach serialisiert in die DB werfen und fertig.Ich muss zugeben, ich hatte mit NestedSets bis jetzt noch nix am Hut, aber so wie ich das aus der Wikipedia rausles, is das doch sehr ähnlich nem binären Suchbaum, oder?
öhm neija, ne Ähnlichkeit ist schon da :D
Ist eben einfach eine Abbildung eines Baumes mit 0..n Kindern auf eine relationale Datenbank.

Hast du ne persönliche Empfehlung parat oder muss ich Google bemühen? :biggrin:
Google :mrgreen:
I.R. landet man doch aber bei dem von Christian Seiler wird nur schon lange nicht mehr gepflegt :-?
Die ez Components haben seit kurzem etwas für Dokumente, ich weiß, dass das Wiki-Syntaxen unterstützt, ob Bbcode weiß ich nicht.
Edit: kein Bbcode :(

Trotzdem steh ich dann vor dem Problem, Usereingaben überprüfen zu müssen. Und eine Art BB-Code dürfte dem durchschnittlichen Benutzer wohl von Internetforen am vertrautesten sein.
HTML mit HTMLPurifier ist auch kein Problem, das ist ne echt klasse Komponente ;)
Dann kann man einfach einen fertigen WYSIWYG-Editor nutzen.
 
Bin mir nicht sicher, ob meine Antwort nicht wieder einen Rückschritt bedeutet, aber: Wie wäre es mit einer Klasse?
PHP:
class Text
{
    private $type;
    private $content;
    private $data;

    const p = 0;
    const ul = 1;
    const ol = 2;
    const li = 3;

    public function __construct ($type, $content, $data = null)
    {
        if (in_array($type, array(self::p, self::ul, self::ol, self::li)) {
            $this->type = $type;
            $this->content = $content;
            $this->data = $data;
        }
    }

    /*... weitere Methoden ...*/
}
Damit sähe die Eingabe für Dein Beispiel so aus:
PHP:
$text = array();

$text[] = new Text(Text::p, 'hier Text', 42);

$lis = array();
$lis[] = new Text(Text::li, new Text(Text::p, '1. Aufzählungspunkt', 2));
$lis[] = new Text(Text::li, new Text(Text::p, '2. Aufzählungspunkt', 3));
$text[] = new Text(Text::ol, $lis);
Mit der Einführung der entsprechenden Methoden in die Klasse kannst Du dann auch die Verarbeitung steuern.
 
Bin mir nicht sicher, ob meine Antwort nicht wieder einen Rückschritt bedeutet, aber: Wie wäre es mit einer Klasse?
Ne, Rückschritt nicht. Klingt eher wie meine Array-Variante, aber ein wenig flexibler :)
I.R. landet man doch aber bei dem von Christian Seiler wird nur schon lange nicht mehr gepflegt :-?
Sowas wollt ich hören :D Hab ich mir gestern mal angeguckt, sieht sehr schön aus und hat sogar diese Absatzerkennung (die ich schon bei mir testweise implementiert hatte).

Ich hab mir das Hirn schon zermartert, aber irgendwie gefällt mir das alles nicht, wenn ich an das User-Interface denke.

Um mal etwas präziser zu werden:
Ich will, dass man Texte nach dem genannten Schema anlegen kann. Konkret:
Code:
zeichen = "A" | "B"  | ... .
text = (absatz | ordered_list | unordered_list)+ .
absatz = zeichen+ .
list_item = absatz+ .
ordered_list = list_item+ .
unordered_list = list_item+ .
Optional möchte ich jedem Absatz ein Bild zuweisen können. Das zu Beginn angesprochene Datum ist hier also nur die ID, die das Bild in einer anderen Tabelle eindeutig zuordnet.

Das - eigentlich größere - Problem, als das Datenformat, ist, wie ich diesen Text eingeben lasse.

Mein bisheriger Versuch war, ich gebe erst den reinen Text ein. Der wird zeichenweise durchgegangen, halt geguckt, wo ein Absatz beginnt (\n\n => Absatz-Ende + Absatz-Neubeginn) und dann den Baum in Form des Arrays aufbauen. Habe ich den Baum, kenne ich die Absätze und kann diese auf einer weiteren Seite mit entsprechenden Upload-Formularelementen darstellen und so die Möglichkeit für die Zuordnung eines Bilds geben.

Problem bei diesem Ansatz war, dass ich nicht weiß, wie ich Aufzählungen im Text erkenne.

Also muss eine Auszeichnungssprache her. BB-Code, um diese Stellen zu markieren, wo Aufzählungen sind.
Die nette Klasse wandelt den BB-Code direkt in HTML um. Das is mir aber auch nicht dienlich, weil ich ja vorher die Absätze alle in Händen brauch, um die Bilder einzufügen (bei der Ausgabe) bzw. das Upload-Formular zeigen muss (beim Erstellen des Textes).

Es gibt zwar dieses - nicht wirklich dokumentierte - Attribut StringParser_BBCode::$_noOutput, womit ich eine interne Zwischendarstellung in Baum-Form kriege, aber da krieg ich nur Tags und keine Attribute. BB-Code, wie in Post #1, ist somit also nicht möglich. Genauer hab ichs mir nicht angeguckt, vielleicht würde ich - mit eingeschalteter Absatzerkennung - wenigstens die Absätze als Knoten im Baum kriegen. Weiß ich ned.

Der "einfachste" Ansatz wäre, dem Benutzer mit "Erstelle Absatz"-, "Erstelle Aufzählung"-, "Erstelle Aufzählungspunkt"-Buttons den Text gleich in Form meines Baums eingeben zu lassen.
Das Problem hier is halt, dass das die benutzerunfreundlichste Lösung is, weil der ne halbe Ewigkeit braucht, um seinen Text einzugeben. (AJAX kann das zwar etwas verbessern, aber das möchte ich jetzt erstmal ausklammern.)