Zur Navigation

Sprachweiche [2]

mit weiteren seltsamen RegEx-Problemen

11 Ranma (Gast)

Mein Code ist schon noch mein Code, auch wenn ich die Variablen umbenenne und mal eine vergesse. Jetzt kann ich mir schon wieder neue Variablennamen ausdenken, so ein MIst aber auch.

Ich weiß nicht ganz, was du meinst mit innerhalb des Arrays gespeichert. Wenn ich so etwas verwende wie $short[]= oder $long[]= , also den Namen des Arrays mit einem leerem Index, dann sollten ständig neue Werte hinzugefügt werden und der Index dabei automatisch um 1 hochgezählt werden. Genau das gefällt mir an einem Array. Ich brauche nichtmal die Anzahl der Elemente in einem Array zu kennen, um sie trotzdem mit FOREACH alle zu durchlaufen. Bei einer strengeren Programmiersprache wäre ich da völlig überfordert.

Bei neueren Versionen des Firefox steht innerhalb von $_SERVER['HTTP_ACCEPT_LANGUAGE'] gerne ;q=0. irgendeine Ziffer. Da dachte ich schon, ich müßte danach gewichten. Aber Firefox macht das tatsächlich selbst und bringt alle bevorzugte Sprachen in eine Reihenfolge. Man kann beim verstellen dieser Variablen auch die Reihenfolge einstellen. Also etwa mit ungefähr der Bedeutung: liefere mir die deutsche Version, falls die nicht existiert, dann die englische Version, falls die auch nicht existiert, dann die französische Version und so weiter. Sicherlich dürften die Möglichkeiten selten ausgeschöpft werden. Weil es sie nunmal in sehr flexibler Form gibt, muß ein Skript, das Mehrsprachigkeit erlauben will, in gleichermaßen flexibler Form darauf reagieren. Das heißt vor allem die Reihenfolge auswerten, nach den eigentlichen Inhalten. Die wiederum können durch Satzzeichen getrennt sein oder in eckigen Klammern stehen oder was immer anderen Herstellern noch eingefallen sein mag. Darum sucht mein RegEx nach einem Wortanfang und nun ein strpos() nach sinnvollen Indizes.

Mit um eins erhöhen meinte ich strpos()+1 als Index des Ergebnisses verwenden und das funktioniert. Und zwar so wie das nur mit Zahlen funktioniert. Anscheinend wird der Typ eines Array-Schlüssels öfter mal unbemerkt umgewandelt. Inzwischen habe ich nämlich herausgefunden, daß die Sortierung mit ksort() funktioniert. Die Schlüssel des Ergebnisses sind dabei sogar einstellig, also dürfte ksort() nicht nur sortieren, sondern benannte Schlüssel erwarten und die durch numerische ersetzen. Wahrscheinlich machen vor allem implizite Typumwandlungen das Verhalten von PHP schwer vorhersagbar.

Müßte ich ernsthaft mit mehr als zehn Werten in $_SERVER['HTTP_ACCEPT_LANGUAGE'] rechnen, dann müßte ich das Verhalten von ksort() auch noch mit natsort() und vielleicht noch weiteren Sortierfunktionen vergleichen. Wie gut, daß das kein realistischer Fall ist. Also habe ich jetzt mein gewünschtes Ergebnis für diesen Skriptteil. Als nächstes dachte ich daran etwas einfacheres als ein Forum zu versuchen und erstmal ein Wörterbuch zu bauen. Erst erschien mir das noch komplizierter, aber inzwischen nicht mehr. Danach soll es sich dann mit Hilfe seiner eigenen Datenbanktabelle und der Sprachweiche selbst lokalisieren. Übrigens erzähle ich das, weil ich festgestellt habe, daß ich umso intensiver an meinem Skript arbeite, je mehr ich hier darüber erzähle.

Auf die erste Schwierigkeit bin ich beim Wörterbuchbau schon gestoßen. Irgendwie ist aus einem SQL-Statement ein Boolean geworden. Anscheinend darf ich folgendes nicht machen:
SELECT ( Ziel, Zielsprache FROM Wörterbuch WHERE Quelle = Suchterm ) AND ( Quelle, Quellsprache FROM Wörterbuch WHERE Ziel = Suchterm )
Das ist ein Versuch das Wörterbuch gleich in beiden Richtungen durchsuchbar zu machen, so wie das bei den Wörterbüchern von LEO der Fall ist. Bei den meisten Wörterbüchern, die man online findet, muß man die Suchrichtung umschalten. Nachdem aber LEO schon lange zeigt, daß das nicht notwendig ist, erscheint mir das zu umständlich. Vielleicht ginge es, wenn mein mysqli_stmt_bind_result() mehr als nur zwei Variablen vorsähe? Vermutlich schon und dazu natürlich die gesamte Weiterverarbeitung doppelt schreiben, nur mit jeweils den unterschiedlichen Variablennamen. Ich war mir unsicher, weil dann die Variablen meistens leer bleiben dürften. Also probiere ich wohl einfach aus, was mit leeren Variablen passieren wird...
Ranma

20.09.2015 02:27

12 Jörg Kruse

Ich weiß nicht ganz, was du meinst mit innerhalb des Arrays gespeichert.

Mir fehlte die Information, wie du den Return-Wert in welchem Array unterbringst

Mit um eins erhöhen meinte ich strpos()+1 als Index des Ergebnisses verwenden und das funktioniert.

Also als Index von $short und / oder $long?

Es ist halt etwas mühsam aus einem Prosa-Text zu konstruieren, wie der Code aussehen könnte - deswegen meine Bitte nach dem konkreten Code :)

SELECT ( Ziel, Zielsprache FROM Wörterbuch WHERE Quelle = Suchterm ) AND ( Quelle, Quellsprache FROM Wörterbuch WHERE Ziel = Suchterm )
Das ist ein Versuch das Wörterbuch gleich in beiden Richtungen durchsuchbar zu machen, so wie das bei den Wörterbüchern von LEO der Fall ist.

Dann wäre hier aber ein OR statt eines AND angebracht. Bei einem AND werden nur Ergebnisse geliefert, in denen der Begriff in beiden Sprachen identisch ist. "handy" würde z.B. keine Ergebnisse liefern, weil "handy" ("handlich") != "Handy" ("mobile phone")

21.09.2015 18:01 | geändert: 21.09.2015 18:07

13 Ranma (Gast)

Natürlich waren die Indizes von $short und $long gemeint. So ziemlich mein gesamter Code steht in Beitrag Nr. 5. Aber der Teil funktioniert jetzt, mit ksort($long) und ksort($short) sortiert. Wird aber gleich nochmal wichtig.

Ich verwende ein Auswahlmenü <select><option></option></select>, wobei ich die <option></option>-Teile mittels einer FOREACH-Schleife aus $Babelfish befülle. Das sollte soweit eindeutig sein. Jetzt hätte ich aber gerne, daß das Auswahlmenü mit den Optionen aus $long beginnt, so daß die am wahrscheinlichsten verwendete Sprache oben steht, vielleicht auch vorausgewählt werden kann. Der Rest von $Babelfish soll dann trotzdem in die Liste. Also brauche ich erst $long und danach einen Array, der den Rest von $Babelfish enthält. Wie kann ich so einen erzeugen?

Die Suche in der Datenbank habe ich in zwei Suchanfragen zerlegt. Mit OR hätte das funktioniert? Darüber habe ich wohl nicht lange genug nachgedacht. Die Fehlermeldung berichtete von einem Boolean und ich wollte dort eine Query, also habe ich keinen weiteren solchen Operator ausprobiert. Jetzt sind es ungefähr fünf Zeilen mehr. Lohnt sich also kaum das wieder einzudampfen. Außer man könnte generell sagen, daß eine Methode (Suche mit einem OR) schneller als die andere (zwei einfache Suchen) ist?

Dann fällt mir noch auf, daß meine Datenbanktabelle für das Wörterbuch einen komplett leeren Datensatz enthält. Den habe ich wohl versehentlich angelegt. Was mich daran stört ist, daß einige der Spalten auf NOT NULL gesetzt sind. Obwohl nichts auf UNIQUE gesetzt ist, scheint das nicht reproduzierbar zu sein.
Ranma

22.09.2015 01:53

14 Jörg Kruse

Ich verwende ein Auswahlmenü <select><option></option></select>, wobei ich die <option></option>-Teile mittels einer FOREACH-Schleife aus $Babelfish befülle. Das sollte soweit eindeutig sein. Jetzt hätte ich aber gerne, daß das Auswahlmenü mit den Optionen aus $long beginnt, so daß die am wahrscheinlichsten verwendete Sprache oben steht, vielleicht auch vorausgewählt werden kann. Der Rest von $Babelfish soll dann trotzdem in die Liste. Also brauche ich erst $long und danach einen Array, der den Rest von $Babelfish enthält. Wie kann ich so einen erzeugen?

$Babelfish_without_long = array_diff($Babelfish, $long);

Außer man könnte generell sagen, daß eine Methode (Suche mit einem OR) schneller als die andere (zwei einfache Suchen) ist?

Man hat dann zumindest einen Kontextwechsel weniger

Was mich daran stört ist, daß einige der Spalten auf NOT NULL gesetzt sind.

Hattest du beim Anlegen der Tabelle was anderes definiert?

22.09.2015 16:12

15 Jörg Kruse

Nachtrag:

Zitat von Jörg
$Babelfish_without_long = array_diff($Babelfish, $long);

Das wird wohl nicht funktionieren, da $Babelfish und $long verschieden aufgebaut sind :(

Alternativ kannst du die Sprachbezeichungen in $Babelfish in einer Schleife auslesen und mittels in_array() schauen, ob diese in $long enthalten sind - falls nein, kannst du diese dann einem neuen Array $Babelfish_without_long hinzufügen

22.09.2015 16:49

16 Ranma (Gast)

Meine Lösung:
$longshort=array_map(NULL,$long,$short);
$without=array_diff($Babelfish,$longshort);
// Damit nur eine Foreach-Schleife durchlaufen werden muß:
$all=array_merge($longshort,$without);

Leider weiß ich noch nicht, ob es funktioniert hat, weil mein Skript an einem anderen Stelle abbricht. Das wird gleich ein neues Thema.

29.09.2015 01:16

17 Ranma (Gast)

Der Trick mit array_map() funktioniert. Das darauffolgende array_diff() führt jedoch zu:
Fatal error: array to string conversion
Das wird ungefähr zweihundertmal ausgegeben. Danach kommt aber doch noch ein Auswahlmenü mit dem Inhalt von $longshort und keinen weiteren Möglichkeiten.

Ich vermute, daß die mehrfache Ausgabe einer Fehlermeldung generell darauf hinweist, daß der Fehler erst zur Laufzeit auftritt?

Außerdem vermute ich nun, daß array_diff() nur eindimensionale Arrays verarbeiten kann?
Ranma

30.09.2015 03:22

19 Ranma (Gast)

Das führte zu einem frustrierendem Tag. Ich habe es erst mit dem Trick versucht, erst implode() auf beide Arrays und dann explode() auf das Ergebnis anzuwenden. Das brauchte drei zusätzliche foreach-Schleifen und abgesehen von den darin erzeugten noch vier weitere Hilfsvariablen vom Typ Array. Als Resultat wurden im Auswahlmenü erst zwei leere Einträge, dann die Werte von $longshort und schließlich statt den Werten von $without die Werte von $Babelfish, wobei die letzten beiden Werte davon fehlten, ausgegeben.

Also versuchte ich einen anderen Trick und statt der Umwandlung der Unterarrays in Strings die Umwandlung der zweidimensionalen Arrays in assoziative Arrays und schließlich noch die Umwandlung des Ergebnisses zurück in ein zweidimensionales Array.

Leider funktioniert $Babelfish_assoc=array_combine($Babelfish[][0],$Babelfish[][1]); nicht! Darum brauchte ich weitere zwei foreach-Schleifen und abgesehen von den darin erzeugten nochmal vier weitere Hilfsvariablen vom Typ Array. Also schließlich hatte ich jede Menge zusätzliche Zeilen Code, aber dafür funktionierte es endlich.

Weil es so viele Zeilen Code waren, dachte ich, daß ich das Ganze am besten in eine IF-Verzweigung und das Ergebnis in eine SESSION-Variable packe. Leider führt das dazu, daß die ganze Arbeit umsonst war! Also die gesamte Auswertung von $_SERVER['HTTP_ACCEPT_LANGUAGE'] befindet sich schließlich in $_SESSION['LANGUAGE'] aber diese Variable zu verwenden führt zu einer völlig leeren Auswahlliste. Immerhin ohne Fehlermeldung.

Kann es vielleicht sein, daß ich kein zweidimensionales Array in als Element von $_SESSION[] verwenden kann? Aber dann müßte tatsächlich immer wieder die gesamte Auswertung durchlaufen werden?
Ranma

01.10.2015 04:26

20 Jörg Kruse

Poste bitte mal den aktuellen Code - aus einer Beschreibung lässt er sich nur schwerlich rekonstruieren.

01.10.2015 10:54 | geändert: 01.10.2015 10:54