RegEx zahl auslesen und in einem Query verwenden
Malcolm Beck´s
- php
hi,
ich habe einen DB-Eintrag der wie folgt aussieht:
„
[mynews]3[/mynews]
und irgendwas anderes
“
Das „[mynews]3[/mynews]“ soll ersetzt werden und die eingeschlossene Zahl benötige ich für Limit in einem Query, also habe ich folgendes probiert:
$var = preg_replace('#\[mynews\](.*)\[\/mynews\]#',"$1", $marginalien);
$news_abfrage = "SELECT
date, news
FROM
meine_news
ORDER BY
id
DESC
LIMIT $var
";
Dieses funktioniert zwar, aber nur, wenn in dem Feld „[mynews]3[/mynews]“ steht, nichts anderes.
Ein var_dump($var);
ergab:
string(38) "3 "
Woher kommen hier 38 zeichen? Ansich ist das Ergebnis ja „3“, also dass, was ich benötige.
mfg
Ein
var_dump($var);
ergab:string(38) "3 "
Woher kommen hier 38 zeichen? Ansich ist das Ergebnis ja „3“, also dass, was ich benötige.
38 = 2 mal 19
Das was du erlaubst, wenn du (.*) verwendest.
mfg Beat
hi,
38 = 2 mal 19
Das was du erlaubst, wenn du (.*) verwendest.
Nein, ich hatte es vernachlässigt, in den Quelltext zu sehen, da steht:
string(40) "3
<object width="240" height="199">
"
Das heisst, irgendwas stimmt mit dem Ausdruck nicht.
In der DB steht:
„
[mynews]3[/mynews]
<object width="240" height="199">
“
$var = preg_replace('#\[mynews\](.*)\[/mynews\]#', "$1", $marginalien);
Ansich habe ich mit diesem Ausdruck keine Probleme, was läuft hier falsch?
------------
Habe es gerade doch noch hinbekommen:
$var = preg_replace('#\[mynews\](.*)\[/mynews\]\s*(.*)#', "$1", $marginalien);
Kritik an dieser Variante erwünscht.
mfg
Hallo Malcolm,
Ansich habe ich mit diesem Ausdruck keine Probleme, was läuft hier falsch?
alles. Ein wundervolles Beispiel für den unnötigen Einsatz von regulären Ausdrücken.
$var = preg_replace('#\[mynews\](.*)\[/mynews\]\s*(.*)#', "$1", $marginalien);
Kritik an dieser Variante erwünscht.
a) Wenn Du schon reguläre Ausdrücke benutzt.
warum speicherst Du in Deiner Backreferenz alles, wenn Du für Deine LIMIT-Klausel nur die erste Ziffernfolge benötigst, die nach [mynews] und vor [/mynews] auftritt?
b) Viel besser: verzichte auf den RegExp.
Das konzeptionelle Problem sehe ich darin, dass Du mühsam eine Information, die Du zwingend benötigst, mittels regexp aus einer Zeichenkette extrahierst. Ich halte das *nicht* für eine gute Idee. Ganz besonders dann nicht, wenn die Zeichenkette ohnehin zuerst aus einer DB ausgelesen wird.
Speichere diese offensichtlich wichtige Information in einer eigenen Spalte ab - und Du erledigst Dein Problem weit eleganter als mit dem elegantesten und korrektesten regulären Ausdruck, den man sich vorstellen kann.
Durch die getrennte Speicherung wird die LIMIT-Klausel zum Kinderspiel und Du kannst Du Dein preg_replace() durch den .-Operator ersetzen, was nicht nur eleganter sondern auch leichter lesbar ist.
Korrigiere daher Dein Tabellendesign.
Freundliche Grüße
Vinzenz
hi Vinzenz,
alles. Ein wundervolles Beispiel für den unnötigen Einsatz von regulären Ausdrücken.
$var = preg_replace('#\[mynews\](.*)\[/mynews\]\s*(.*)#', "$1", $marginalien);
warum speicherst Du in Deiner Backreferenz alles, wenn Du für Deine LIMIT-Klausel nur die erste Ziffernfolge benötigst, die nach [mynews] und vor [/mynews] auftritt?
Ich komme sonst nicht an die benötigte Ziffer.
b) Viel besser: verzichte auf den RegExp.
Ja, gerne ;)
Speichere diese offensichtlich wichtige Information in einer eigenen Spalte ab - und Du erledigst Dein Problem weit eleganter als mit dem elegantesten und korrektesten regulären Ausdruck, den man sich vorstellen kann.
Ok, dass wäre kein Problem.
Durch die getrennte Speicherung wird die LIMIT-Klausel zum Kinderspiel und Du kannst Du Dein preg_replace() durch den .-Operator ersetzen, was nicht nur eleganter sondern auch leichter lesbar ist.
Hier fehlt mir die Logik, dass zu programmieren. Nehmen wir das Feld „Marginalien“, wo ich jeder Seite etwas anderes zuordnen kann.
Jetzt möchte ich mir die möglichkeit schaffen, auf jeder Seite (wenn benötigt) die News einzublenden, eben mit einer Limit-Klausel.
Das Feld „Marginalien“ ist Longtext, so dass auch unter den News oder davor noch etwas anders stehen kann.
Ein Beispiel was vorkommen könnte:
ID | Marginalien
----+------------
112 | Einige Infos
| Ein Link
| [News]
[News] soll dann halt aus der Tabelle für News ausgelesen werden und mit einem Limit ausgegeben werden. Wie kann ich sowas sonst bewerkstelligen?
Das ist mit einer meiner hauptprobleme, die ich mit MySQL derzeit noch habe.
Sobald ich eine Funktion benötige, die im Fliesstext der Daten vorkommt, komme _ich_ um RegEx einfach nicht drumrum.
Korrigiere daher Dein Tabellendesign.
Ich versuche es Krampfhaft.
mfg
hi,
wo schon mal ein Thread gestartet ist ;)
Ich beschäftige mich in letzter Zeit ein wenig mit Caching, nur heute ist mir mal was aufgefallen, was dass Caching etwas schwierig macht.
Nehmen wir eine Seite mit einem Tree-Menu dass z. B. für eine Kategorie eine Liste öffnet, also:
Kategorie[1]
Link-1
Link-2
Link-3
Kategorie[2]
Kategorie[3]
Sagen wir jetzt einfach mal, alle Seiten und unterseiten sind im Cache des Browsers. Jetzt bekommt „Kategorie[1]“ noch eine Unterseite mit dem Title „Link-4“, das Resultat wäre jetzt:
Kategorie[1]
Link-1
Link-2
Link-3
Link-4
Kategorie[2]
Kategorie[3]
Das bedeutet ja, dass sich die Seite „Kategorie[1]“ und alle unterseiten geändert haben (ein neuer Link wird in jede Seite eingefügt), Theoretisch würde dass ja bedeuten, dass die Last-Modified header der betreffenden Seiten alle das gleiche Aktuelle Datum bekommen müssten, oder wie wird das gehandhabt?
Für mich war das Last-modified nur bezogen auf die Ressource, die sich geändert hat, in diesem Fall sind ja aber eigentlich alle Ressourcen geändert worden.
mfg
Hi,
Für mich war das Last-modified nur bezogen auf die Ressource, die sich geändert hat, in diesem Fall sind ja aber eigentlich alle Ressourcen geändert worden.
Das beantwortet doch wohl die Frage, welche Ressourcen also auch neu an den Client auszuliefern sind, hinreichend eindeutig.
MfG ChrisB
hi,
Für mich war das Last-modified nur bezogen auf die Ressource, die sich geändert hat, in diesem Fall sind ja aber eigentlich alle Ressourcen geändert worden.
Das beantwortet doch wohl die Frage, welche Ressourcen also auch neu an den Client auszuliefern sind, hinreichend eindeutig.
Das stimmt. Ich hatte lange Zeit geglaubt, dass der Last-modified-Header jeder Ressource eher unterschiedlich sein muss|sollte. Ich glaube, ich werde vorerst drauf verzichten, bis ich es richtig verstanden habe.
mfg
Hi,
Ich hatte lange Zeit geglaubt, dass der Last-modified-Header jeder Ressource eher unterschiedlich sein muss|sollte.
Er sollte das letzte Aenderungsdatum der Ressource angeben.
Natuerlich kann das auch mal bei "allen" der gleiche Zeitpunkt sein - bei einer Konstellation wie imvorliegenden Beispiel eben. Wenn sich bei der sich durch alle Dokumente ziehenden Navigation etwas aendert, dann bewirkt das auch einen neuen Aenderungszeitpunkt fuer alle betroffenen Ressourcen - so lange, bis sich an den einzelnen Ressourcen dann wieder individuelle Aenderungen ergeben.
MfG ChrisB
hi,
Ich hatte lange Zeit geglaubt, dass der Last-modified-Header jeder Ressource eher unterschiedlich sein muss|sollte.
Er sollte das letzte Aenderungsdatum der Ressource angeben.
Natuerlich kann das auch mal bei "allen" der gleiche Zeitpunkt sein - bei einer Konstellation wie imvorliegenden Beispiel eben. Wenn sich bei der sich durch alle Dokumente ziehenden Navigation etwas aendert, dann bewirkt das auch einen neuen Aenderungszeitpunkt fuer alle betroffenen Ressourcen
Das dürfte eigentlich keine Hürde darstellen, dass zu programmieren.
Ich werde heute meine DB dementsprechend versuchen anzupassen.
Danke für den Hinweis.
mfg
P. s.: mein denkfehler lag darin, dass ich das Datum des Last-Modified auch in den Seiten als „Zuletzt Aktualisiert“ darstelle, da würde es falsch wirken, wenn 6 Seiten so aussehen, als seien sie alle zum gleichen Zeitpunkt geändert worden, was ja Inhaltlich gesehen, nicht richtig ist.
Hi,
P. s.: mein denkfehler lag darin, dass ich das Datum des Last-Modified auch in den Seiten als „Zuletzt Aktualisiert“ darstelle, da würde es falsch wirken, wenn 6 Seiten so aussehen, als seien sie alle zum gleichen Zeitpunkt geändert worden, was ja Inhaltlich gesehen, nicht richtig ist.
Das ist dann sehr wohl richtig, wenn du die Navigation, die sich geaendert hat, zum "Inhalt" hinzuzaehlst.
Es kommt also hier ganz wesentlich darauf an, *worauf* du die Groesse "letzte Aenderung" bezogen sehen willst.
HTTP bezieht sie natuerlich auf die gesamte Ressource - denn diese ist fuer sich atomar.
Aber wenn du auf deinen Seiten lediglich angeben willst, wann sich der eigentliche Inhalt zuletzt geaendert hat, dann kann dieser Zeitpunkt natuerlich davon abweichen - weil er damit einer anderen Definition unterliegt, weil du das Dokument in mehrere Teile zerlegst, "Hauptinhalt" und "Sonstiges". Das ist aber eine Betrachtungsweise, die HTTP nicht teilen kann.
MfG ChrisB
hi,
P. s.: mein denkfehler lag darin, dass ich das Datum des Last-Modified auch in den Seiten als „Zuletzt Aktualisiert“ darstelle, da würde es falsch wirken, wenn 6 Seiten so aussehen, als seien sie alle zum gleichen Zeitpunkt geändert worden, was ja Inhaltlich gesehen, nicht richtig ist.
Das ist dann sehr wohl richtig, wenn du die Navigation, die sich geaendert hat, zum "Inhalt" hinzuzaehlst.
Wieder mal vergessen, meinen Gedankengang zu ende zu bringen, Sorry.
Ich bezog das „Zuletzt Aktualisiert“ natürlich auf den Inhalt, also den Artikel an sich. Technisch gesehen ändern sich alle Ressourcen, die den Link in der Navigation mit sich tragen, für den User aber dürfte das Datum der Navigationserweiterung keine rolle spielen.
Jetzt muss ich mir erstmal überlegen, wie ich dass Generell mit den ganzen Datumsangaben in der DB lösen kann, dass kann ja was werden.
Danke für die Hilfe.
mfg
Hi,
Jetzt muss ich mir erstmal überlegen, wie ich dass Generell mit den ganzen Datumsangaben in der DB lösen kann, dass kann ja was werden.
In der Datenbank wirst du ja vermutlich reine Inhalte haben, waehrend deine Navigation in einem include-File lagert.
Ob der Last-Modified-Header einer Ressource angepasst werden muss, und wie auf einen Conditional-GET-Request mit einem If-Modified-Since-Header zu antworten ist, entscheidet sich also an Hand zweier Kriterien:
Zum einem dem Aenderungsdatum des Inhaltes aus der Datenbank,
und zum anderen dem Aenderungsdatum des include-Files der Navigation.
Beide Datuemer sind also zu vergleichen, und das "neuere" ist das relevante.
Wenn deine Ressourcen noch aus weiteren zusaetzlichen Quellen gespeist werden (Template-Dateien, weitere includes mit fuer die Ausgabe relevanten Bestandteilen), dann haben deren Aenderungsdaten natuerlich ebenfalls noch mit in die Betrachtung einzufliessen.
MfG ChrisB
hi,
Jetzt muss ich mir erstmal überlegen, wie ich dass Generell mit den ganzen Datumsangaben in der DB lösen kann, dass kann ja was werden.
In der Datenbank wirst du ja vermutlich reine Inhalte haben, waehrend deine Navigation in einem include-File lagert.
Nein, ich lese alles aus der DB aus, Inhalte und auch die Gesamte Navigation.
Meine Idee ist jetzt, dass die einzelnen Artikel ein eigenes Datum bekommen, dass ich als Hinweis für den User in der jeweiligen Seite anzeige, in der Tabelle für die Navigation bekommt dann jede Kategorie (die unterseiten hat) ein Datum zugewiesen, dass dann den Last-Modified-Header bildet.
Eventuell lege ich noch ein Feld an, in dem gespeichert wird, wann der Artikel erstmals geschrieben wurde.
Ob der Last-Modified-Header einer Ressource angepasst werden muss, und wie auf einen Conditional-GET-Request mit einem If-Modified-Since-Header zu antworten ist, entscheidet sich also an Hand zweier Kriterien:
Zum einem dem Aenderungsdatum des Inhaltes aus der Datenbank,
und zum anderen dem Aenderungsdatum des include-Files der Navigation.
Und da wird es schon wieder schwierig, wenn ein Artikel eine Aktualisierung bekommt, muss dessen Last-Modified das Aktuelle Datum bekommen, wenn ein Menupunkt hinzukommt, alle Ressourcen dieser Kategoerie.
Wieviele Timestamp werde ich da brauchen?
Wenn deine Ressourcen noch aus weiteren zusaetzlichen Quellen gespeist werden (Template-Dateien, weitere includes mit fuer die Ausgabe relevanten Bestandteilen), dann haben deren Aenderungsdaten natuerlich ebenfalls noch mit in die Betrachtung einzufliessen.
Das mit dem Template wird am schwierigsten, wenn sich das Template ändert, müssten ja Logischerweise alle Ressourcen das Aktuelle Datum als Last-Modified-Header bekommen.
Das werde ich wohl mit einer kleinen Template-Funktion lösen.
mfg
hi,
einen hab i noch ;)
MySQL 5
Da mich die derzeitige aufteilung meiner DB nicht fröhlich stimmt, möchte ich das ganze neu gestalten und bei Gelegenheit auch versuchen, dass ganze zu Normalisieren.
Da ich generell nicht wirklich viel von der Theorie der Normalisierung verstehe, habe ich einfach mal was nach meinem verständnis zusammen gestellt.
Es geht um ein ganz Simples CMS; hier mal meine Idee zum Tabellen-Design.
--
-- Tabellenstruktur für Tabelle `my_head`
--
CREATE TABLE IF NOT EXISTS `my_head` (
`id` int(8) unsigned NOT NULL auto_increment,
`my_title` varchar(200) collate utf8_unicode_ci NOT NULL,
`my_description` varchar(250) collate utf8_unicode_ci NOT NULL,
`my_keywords` varchar(250) collate utf8_unicode_ci NOT NULL,
`my_last_update` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
`my_styles_scripts` longtext collate utf8_unicode_ci NOT NULL,
`my_autor` varchar(200) collate utf8_unicode_ci NOT NULL,
`my_autor_email` varchar(200) collate utf8_unicode_ci NOT NULL,
PRIMARY KEY (`id`),
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=0 ;
INSERT INTO `my_head` (`id`, `my_title`, `my_description`, `my_keywords`, `my_last_update`, `my_styles_scripts`, `my_autor`, `my_autor_email`)
VALUES
('', '', '', '', '', '', '', '');
-- -------------------------------------------------------------------
--
-- Tabellenstruktur für Tabelle `my_content`
--
CREATE TABLE IF NOT EXISTS `my_content` (
`id` int(8) unsigned NOT NULL auto_increment,
`my_body_id` varchar(200) collate utf8_unicode_ci NOT NULL,
`my_headline` varchar(250) collate utf8_unicode_ci NOT NULL,
`my_content` longtext collate utf8_unicode_ci NOT NULL,
PRIMARY KEY (`id`),
FULLTEXT KEY `my_content` (`my_content`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=0 ;
INSERT INTO `my_content` (`id`, `my_body_id`, `my_headline`, `my_content`)
VALUES
('', '', '', '');
-- -------------------------------------------------------------------
--
-- Tabellenstruktur für Tabelle `my_menu`
--
CREATE TABLE IF NOT EXISTS `my_menu` (
`id` int(8) unsigned NOT NULL auto_increment,
`my_link_name` varchar(200) collate utf8_unicode_ci NOT NULL,
`my_link_target` varchar(200) collate utf8_unicode_ci NOT NULL,
`my_link_gruppe` varchar(200) collate utf8_unicode_ci NOT NULL,
PRIMARY KEY (`id`),
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=0 ;
INSERT INTO `my_menu` (`id`, `my_link_name`, `my_link_target`, `my_link_gruppe`)
VALUES
('', '', '', '');
-- -------------------------------------------------------------------
--
-- Tabellenstruktur für Tabelle `my_sub_menu`
--
CREATE TABLE IF NOT EXISTS `my_sub_menu` (
`id` int(8) unsigned NOT NULL auto_increment,
`my_link_name` varchar(200) collate utf8_unicode_ci NOT NULL,
`my_link_target` varchar(200) collate utf8_unicode_ci NOT NULL,
`my_link_is_tree` varchar(200) collate utf8_unicode_ci NOT NULL,
PRIMARY KEY (`id`),
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=0 ;
INSERT INTO `my_sub_menu` (`id`, `my_link_name`, `my_link_target`, `my_link_is_tree`)
VALUES
('', '', '', '');
-- -------------------------------------------------------------------
--
-- Tabellenstruktur für Tabelle `my_menu_linking`
-- Verknüpfung der Menupunkte
CREATE TABLE IF NOT EXISTS `my_menu_linking` (
`id` int(8) unsigned NOT NULL auto_increment,
`my_menu_id` int(8) NOT NULL,
`my_sub_menu_id` int(8) NOT NULL,
`my_menu_update` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=0 ;
INSERT INTO `my_menu_linking` (`id`, `my_menu_id`, `my_sub_menu_id`)
VALUES
('', '', '');
-- -------------------------------------------------------------------
--
-- Tabellenstruktur für Tabelle `my_content_linking`
-- Verknüpfung der Inhalte und Menu IDs
CREATE TABLE IF NOT EXISTS `my_content_linking` (
`id` int(8) unsigned NOT NULL auto_increment,
`my_head_id` int(8) NOT NULL,
`my_content_id` int(8) NOT NULL,
`my_menu_id` int(8) NOT NULL,
`my_sub_menu_id` int(8) NOT NULL,
PRIMARY KEY (`id`),
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=0 ;
INSERT INTO `my_menu_linking` (`id`, `my_head_id`, `my_content_id`, `my_menu_id`, `my_sub_menu_id`)
VALUES
('', '', '', '', '');
Taugt das was? Kann man das als Halbwegs gut bezeichnen?
Ein Paar Tipps zur Wahl der richtigen Felder (varchar, int, longtext) sind natürlich willkommen.
mfg