Beiträge von Wiimm

Ich habe einen Blog Artikel verfasst - Wie benutze ich die Suche richtig - Bitte diesen beachten und auch umsetzen bevor Ihr ein Neues Thema eröffnet!

    Vorab:
    Es geht hier nicht um anschwärzen, wie mir in den letzten Jahren vorgeworfen wurde, sondern um das Aufdecken von Fehlern und deren Korrektur. Ich kenne das aus meinen eigenen Open-Source-Projekten, bei denen ich solche Korrekturen und Hinweise immer gerne entgegen genommen habe und auch weiterhin werde.



    Zum Thema:
    Ich wollte die ShoutBox erweitern, so dass 2 Gruppen (Abteilungen) jeweils eine eigene haben. Bei der Umsetzung ist mir folgendes Kode-Stück als Ressourcen-Fresser aufgefallen:

    • Zeile 2 ist der Ressourcen-Fresser: Hier wird der komplette Inhalt (alle Zeilen, alle Spalten) der Shout-Tabelle geladen, um die Anzahl der Zeilen zu bestimmen. Bei mehreren 1000 Beiträgen kann das schon spürbar Zeit und Speicher kosten. Der Einsatz von »count(*)« und die Abfrage des Ergebnisses ist hier klar besser.
    • Die Anzahl (maxsites) wird aber nur im IF-Zweig benötigt. Daher sollte die Abfrage aus Zeile 2ff in den IF-Zweig verschoben werden.
    • Fraglich ist, ob überhaupt die Anzahl benötigt wird. Man kann das OFFSET+LIMIT durchaus auch blind berechnen. Sollte dann z.B. Seite 5 angefordert werden, aber nicht existieren, dann werden halt Null Zeilen ausgegeben.

    Ich denke, dass ist Zufall. Und um den Zufall auszuschalten, kann man in der Datei include/inc.config.php die 2. Zeile hinter der ersten einfügen:

    Code
    1. setlocale(LC_TIME, 'de_DE.utf8','de_DE', 'de_DE@euro', 'de', 'ge');
    2. date_default_timezone_set('Europe/Berlin');


    Hintergrund: Sowohl Locale als auch Zeitzone gelten (unter Unixoiden) für den gesamten Prozess bis zur nächsten Änderung. Da Apache einen Prozess mehrere tausend Male nutzt, sind die Einstellungen Abhängig vom Vorbenutzer. Und dass kann auch ein anderer virtueller Host sein.

    Probe: Ersetze 'Europe/Berlin' durch 'UTC'.


    Wenn man UNIX_TIME in der Datenbank verwendet und die Werte als Ganzzahl ausliefert, dann spielt die eingestellte SQL_Zeit-Zone keine Rolle.

    Es gibt einen Fehler in content/shout.php, wenn man einen DB-Namen mit Minuszeichen verwendet. Es liegt an den fehlenden Quotes in de Abfrage. Dadurch meckert das System ständig mit "Beim Anlegen der MySQL-Tabelle xxx trat ein Fehler auf ...". Die Lösung ist der folgende Patch:

    Im Prinzip reicht die Anpassung der ersten Code-Zeile (Zeilen 7+8, Ergänzung der Back-Hacks "`"). Weil ich dabei war, habe ich den überflüssigen Schnick-Schnack auch gleich entfernt.

    @oldie
    Das mit Spiel 14 ist schon längst gegessen, war aber letzte Nacht aktuell, wie man an den vielen Themen sieht.


    @ Wiimm
    mal wieder
    ....
    auserdem verführt mir Wimme die User viel zu viel zum herum Murksen im code


    Willst Du mich mit "Murks" beleidigen?
    Meine Patches sind kein Murks, sondern gut getestete Tipps, die etwas an der Reihenfolge der Tabellen ändern. Und die Auswirkung ist auch gut dokumentiert. So habe z.B. ich nie gesagt, dass der Kode hier irgendwelche Fehler behebt oder besser ist, sondern nur als Alternative angepriesen. Außerdem ist es hier im Forum üblich, Änderungen am Quelltext als Fehlerbereinigung zu posten.


    Als Murks könnte man höchstens soetwas wie deinen Tipp zum Ändern eines Regex nehmen, der syntaktisch falsch ist und damit scheitern muss. Oder aber die Aussage, dass es unnötig ist, ein Sicherheitsloch zum Indentätsdiebstahl zu schließen, obwohl es sehr einfach möglich ist. Dieses würde ich aber nie so schreiben, es sei denn ich werde wie hier angegriffen.


    Und das "mal wieder" ist eine herabsetzende Bemerkung, die ich nicht verdient habe.


    Im übrigen versuche ich immer höflich und sachlich zu sein, niemanden zu diffamieren oder herabzusetzen und kann mich auch für Fehler entschuldigen.


    NACHTRAG:
    Ich entwickle auch OpenSource und habe mit Wiimmfi ein großes offenes Projekt. ich freue mich immer auf Code-Vorschläge, egal, ob sich sie annehme oder zurückweise. Allein für das Gespräch und eine versuchte Anregung bin ich dankbar.

    Ein Vorschlag für eine zukünftige alternative Punktevergabe, die man evtl. per Option einstellen kann. Multiplikatoren für eine Finalrunde sind wie im alten System möglich. Außerdem gilt dieses als Diskussionsgrundlage.


    Regeln: Es gibt je einen Punkt für:

    • Für die richtige Toranzahl der Heimmannschaft.
    • Für die richtige Toranzahl der Gastmannschaft.
    • Für die richtige Tor-Differenz.
    • Für die richtige Tendenz (Sieg, Unentschieden, Niederlage).
    • Optional: Einen Sonderpunkt, wenn man insgesamt 4 oder mehr Tore getippt hat und bereits mindestens einen anderen Punkt erhalten hat.


    Wenn man nun vom Sonderpunkt (Regel 5) absieht:
    Aus den ersten drei Regeln kann man nur 0, 1 oder 3 Punkte holen. Bei 3 stimmt auch die Tendenz, so dass es zu 4 Punkten aufgewertet wird. Daraus folgt, dass man 0–2 Punkte für ein teilweise korrektes Ergebnis oder 4 Punkte für das korrekte Ergebnis erhält. 3 Punkte ist nicht möglich. Und damit setzt sich ein perfekter Tipp von den anderen ab.


    Optionaler Sonderpunkt (Regel 5)
    Der optionale Sonderpunkt sorgt dafür, dass Tipps ab 3:1 oder 2:2 einen Bonus erhalten, sofern zutreffend. Dieses ist ein Anreiz, von den beiden häufigen Tipps 2.1 und 1:1 abzulassen und etwas höheres zu tippen.

    Da geht doch der berechnete Rang mit ein. Und wenn ich Rangliste / Auf einen Blick richtig deute, dann gehen Dinge wie "Anzahl richtiger Tipps" in die Sortierung als Sortierfaktor mit ein. Ich kann zumindest bei unserem kleinen 15-Personen-Tipp im Moment nichts gegenteiliges feststellen.


    Aber wie gesagt: Änderungen an diesen vorgerechneten Rängen bedeuten für mich extra Einarbeitungszeit, die ich eher nicht aufbringen möchte.

    Die Tabelle der Mitspieler wird jetzt anders sortiert, da der an anderer Stelle berechnet Rang berücksichtigt wird. Der ifnull()-Teil wird benötigt, um Spieler ohne Tipp ans Tabellenende zu bannen. Der erste Post ist entsprechend aktualisiert.

    Code
    1. ORDER BY ifnull(r.rang,999999999), u.usr


    Und da sind wir schon beim noch offenen Thema. Die Ränge werden durch diverse Funktionen vorberechnet. Eine einfache Modifikation der SQL-Abfrage ist daher nicht möglich. Es müssten die Funktionen angepasst werden, was zusätzliche Einarbeitung in den PHP-Code benötigt. Und dieses scheue ich.


    Außerdem berücksichtigen dieses Funktionen doch den Wunsch nach ...
    * Punkteanzahl
    * Anzahl richtiger Tipps
    * Anzahl Tipps mit richtiger Tordifferenz
    * Anzahl Tipps mit richtiger Tendenz
    * dann kann man immer noch alphabetisch sortieren
    ..., oder irre ich mich?


    Evtl. reden wirr auch aneinander vorbei und meinen unterschiedliche Statistiken.
    Daher meine Frage: Welche Statistik meint ihr?

    Hätte ich auch selbst drauf kommen könne, Danke Kurt!


    Wir reden über Rangliste / Auf einen Blick?
    Eine erste Recherche ergab, dass ich hierfür die globale Funktion returnRanglisteKompakt() anfassen muss. Dieses hat dann Auswirkungen auf diverse Tabellen. Evtl.muss ich auch die Rangberechnung anpassen.


    Allerdings warte ich erstmal den Bug Fix mit Spiel 14 ab, da ich sonst keine vernünftige Tabelle habe, an der ich die Sortierung verifizieren kann (Fast jeder Mitspieler hat einen eigenen Rang).

    Sollte machbar sein. Kann mir jemand sagen, welche Felder was bedeuten:

    Ich habe den Patch für die Tipp-Übersicht ergänzt:

    Code
    1. ORDER BY tipps.gast - tipps.heim,
    2. tipps.gast * tipps.gast - tipps.heim * tipps.heim,
    3. tipps.heim DESC,
    4. name

    Die erste Zeile (höchste Priorität) sorgt dafür, dass höhere Differenzen ganz nach oben bzw. ganz nach unten rutschen. Die zweite Zeile sortiert 4:1 vor 3:0, aber 1:4 nach 0:3. Das macht die Tabelle symmetrisch. Die dritte Zeile ist relevant für Unentschieden (1:1 vor 0:0) und die letzte Zeile sortiert dann bei identischen Tipp nach Namen.

    Diesmal geht es um die Tipp-Übersicht. Ich finde es interessanter (werde mir aber noch die Rückmeldung der Mitspieler einholen), wenn die Tipps nach dem Tipp-Ergebnis sortiert sind anstatt alphabetisch nach dem Namen des Spielers. So kann man viel schneller Extrem-Tipps und andere Ausreißer ausmachen und auch sehen, wer dasselbe getippt hat.


    Daher wird die Tabelle nach Tor-Differenz sortiert und bei Gleichheit nach der Anzahl der Tore.
    Der Patch hierzu:

    Hier ist ein Patch, der dafür sorgt, dass die Tabelle der Mitspieler nicht mehr alphabetisch, sondern gemäß Punkte sortiert werden.
    Dazu musste der Punkte-Stand mittels LEFT-JOIN in die Hauptabfrage einfließen, um nach ihr sortieren zu können. Die Einzelabfrage des Punktestandes konnte dann entfallen.


    Das komische Konstrukt mit "<<< __EOT__" und "__EOT__;" ist ein sogenanntes "here document", wobei der frei wählbare Marker EOT = End-Of-Text bedeutet.. Alles dazwischen wird als mehrzeilige Zeichenkette betrachtet. Ich empfinde es viel übersichtlicher als die vielen Zeichenketten-Operationen. Das ganze birgt aber eine Falle: PHP verlangt, dass der Ende-Marker (hier "__EOT__;" ganz alleine in einer Zeile steht und *NICHT* eingerückt ist.


    Nachtrag:
    Beim Stöbern in diesem Forum habe ich gerade "Rangliste: Auf einen Blick ..." entdeckt. Dieses macht den Patch evtl unnötig. Ich werde ihn aber bei mir belassen. Dann haben wir halt ne 2.Übersicht, die nach Punkten sortiert ist und ein wenig optimierter arbeitet.

    Ein gut gemeinter Design-Tipp.


    Auf der Suche nach einem Fehler ist mir etwas anderes aufgefallen, was man geschickter umsetzten kann. Als Beispiel nehme ich mal die Bonus-Tipps:


    Im Prinzip wird der folgende SQL-Code zum Speichern eines Bonus-Tipps verwendet, wobei beide Anweisungen durch weiteren php-Code getrennt sind. Ähnliches findet man auch an anderen Stellen:

    SQL
    1. DELETE from bonus_tippsWHERE usr = $USER_ID and bid = $BID_ID;INSERT INTO bonus_tipps (bid,usr,answer,type,date)VALUES (...)

    Wenn man aber einen eindeutigen Schlüssel der Art

    Code
    1. unique key (bid,user,type);

    ... hätte, dann könnte man folgendes verwenden:

    SQL
    1. INSERT INTO bonus_tipps (bid,usr,answer,type,date)
    2. VALUES (...)
    3. ON DUPLICATE KEY UPDATE
    4. answer = $ANSWER,
    5. date = UNIX_TIMESTAMP();

    Dieses ist nicht nur eine Schönheits-Operation, sondern eine übliche Vorgehensweise mit dem entscheidenden Vorteil, dass es eine atomare Aktion ist. Außerdem würden auf DB-Seite doppelte Einträge verhindert.


    Im ersten Fall ist theoretisch eine Laufzeit-Problem vorhanden, wenn z.B. der Benutzer ein Formular absendet, dieses stockt und er es nochmals absendet. Sollten dann beide gleichzeitig zur Ausführung kommen, dann kann es 2 Einträge für den Bonus-Tipp des Spielergeben.

    Ich habe auch nicht unentlich zeit alles zusammen zutragen

    Das bedeute, dass keiner der Entwickler sein System auf dem laufenden hält und einen Überblick über die allgemeinen Updates hat! Und es wird auch keine Versionskontrolle eingesetzt!
    Ist das wirklich so?


    Und ernsthaft:
    Als Entwickler das eigene System aktuell zu halten erspart ja gerade Zeit. Dieses gilt vor allen für den Support.



    etwas eigen Initiative sollte schon sein

    Ist denn dieses Thema sowie die Fehlersuche (3 Bugs gefunden), aktive Hilfe bei SMTP, Sicherheitslücke geschlossen nicht "etwas Eigeninitiative"? Das fehlen dieser kann man mir wohl nicht vorwerfen.



    Irgendwo anders schriebst Du mir, dass man normalen Anwendern nicht zumuten kann, die php-Dateien zu editieren um DB-Fehler zu loggen. Und hier erwartest du, dass alle Anwender dieselbe Arbeit verrichten um die wilden Patches, die zum Teil mehrfach korrigiert wurden, in der korrekten Form finden und dann selbst einbauen und dabei testen, ob sie miteinander funktionieren.


    Daher nochmals meine Fragen:
    * Hat keiner der Entwickler (oder ersatzweise Anwender) sein System auf dem aktuellen Stand?
    * Wird denn kein SVN oder GIT zur Unterstützung eingesetzt, das man schnell mal aus-checken kann?


    Ein schnelles DIFF mit alten und neuem System und man hat einen Patch, den andere mit eigenen Modifikationen relativ gefahrlos einspielen können.

    Über das ganze Forum sind diverse Korrekturen verteilt, u.a:
    * SMTP
    * Forum
    * Zeitanzeige
    * Registrierung
    * Sicherheitslücke schließen
    und viele mehr.


    Ist hier ein Update oder ein großer Sammel-Patch geplant?
    Oder wenigstens ein Thema, in dem alles zusammengetragen wird?


    Denn die vielen verteilten Einzelkorrekturen sind kaum nachvollziehbar.

    Hintergrundwissen zu PHP date_default_timezone_set() und setlocale()
    Ich spreche hier hauptsächlich aus Linux-Erfahrungen!


    Beide Funktionen verändern den Kontext des aktuellen Prozesses. Dieses ist zwar Betriebssystem-abhängig, aber man sollte dieses einfach grundsätzlich annehmen. Da ein Prozess bis zu seinem Ende viele Aufgaben des Web-Servers übernimmt und damit viele Seiten erstellt, kann man nie wissen, wie die augenblickliche Einstellung ist. Daher ist es immer sinnvoll, zu Beginn (oder nach dem Laden der Anwender-Einstellungen) beide Funktionen aufzurufen.


    Aus diesem Grunde kann auch der Effekt "mal richtige, dann falsche Zeitzone, dann wieder richtige" auftreten.


    Wenn man nun lokale Monatsnamen und Wochentagesnamen oder lokales Zeitformat verwenden möchte, dann muss man die Funktion strftime() verwenden. Denn leider ignorieren date() und auch class Datetime sowie Verwandte den eingestellten LOCALE. Das mag bei php7 anders sein.