PHP if (($lines[$x] == "\r") || ($lines[$x] == "")) 2x true möglich?

Wow, danke, das klappt :)

Wenn ich jetzt das "vendor" Verzeichnis auf meinen Webserver hochlade, kann ich den pgn-parser einfach nutzen?

Edit: Jop, kann ich, habe es grade ausprobiert.

Edit2: Es ist aber fürchterlich dokumentiert, wie hast Du denn herausgefunden, wie er funktioniert?
Ergänzung ()

Weiterer Bug aufgetreten: http://www.devphp.de/pgn/readsuggest.php?id=15
PGN: http://www.devphp.de/pgn/pgnfiles/19Neckar-Open2015.pgn

Dort wird nach dem ECO-Feld weiter Input Felder erzeugt, obwohl schon Züge in den Zeilen stehen.
Weiter wird das Result und Date nur verkürzt ausgegeben. "Result 1-" statt "Result 1-0", Datum Verkürzt auf 9 Zeichen.

Die Verkürzung tritt seltsamerweise auch bei meiner Version auf:
http://www.devphp.de/pgn/readpgn.php?id=15

Ich habe eine leise Ahnung warum das so ist, je nach dem woher die Datei stammt, könnte \r\n als newline oder nur \n dort in den Zeilen stehen. Dann müsste man das zurechtgestutze der Werte um 1 verringern.
 
Zuletzt bearbeitet:
Bei der Zeile stimmt das substr nicht:
Code:
$infoValue = substr($line, strpos($line, '"') + 1, -3);
Aendern zu:
Code:
$infoValue = substr($line, strpos($line, '"') + 1, -2);

Composer habe ich mir angeeignet weil ich mit dem Framework Laravel arbeite, durch diverse Tutorials und Google :D
 
Ahso, die Frage war auf den pgn-parser bezogen, wie hast Du die Beispieldatei geschrieben? In der Readme ist ja gar nichts zu lesen, wie man ihn benutzt. Kann er auch die Header Felder auslesen?
Und die zusätzlichen/falschen Inputs? Woher kommen die? Die Textarea bleibt leer bei der .pgn von den Neckar Open.
 
Hm stimmt schon. Für die Schachseite habe ich 2 Wochen den Quellcode von dem pgn-viewer gelesen und modifiziert. Der zeigt die .pgn als Schachbrett an. Die unteren Knöpfe habe ich dazu geschrieben und noch einige andere Sachen, Koordinaten z.b. Das erste mal öffnen des Quellcode war lustig. Habe geschaut wie viele Zeilen er hat, ca. 4200. Da dachte ich mir "wtf? Das ist die Suche nach der Nadel im Heuhaufen". Naja nach einiger Zeit habe ich die "Nadeln" dann gefunden und umgeschrieben. Habe 2 Wochen gebraucht um alles so zu ändern, dass es mir gefällt. Habe sogar den Author angeschrieben, der mir noch einige wichtige Tips gegeben hat. Aber jetzt noch den pgn-parser von amyboyd analysieren? Naja, nicht so viel lust zu. Er/sie hätte ja mal einfach ein paar Zeilen mehr in die Readme schreiben können und mir viel Mühe ersparen können :)
 
Zuletzt bearbeitet:
Naja, so kompliziert ist es echt nicht. Der nächste Schritt wäre, direkt beim Upload die Daten der .pgn aufzudröseln und in die MySQL Datenbank zu schreiben. Dann hab ich das gefummel mit den Dateien nicht mehr. Dazu könnte man "SELECT * FROM Table WHERE White = :name OR Black = :name" ausführen und hätte alle Partien des Spielers, dazu eine Eröffnungsdatenbank etc. Wenn ich das noch für Zugumstellungen, die zur gleichen Position führen, schaffe, wäre das der Overkill :)
 
Zuletzt bearbeitet:
Hi, ich bin's mal wieder :)
Ich habe jetzt versucht das MovesArray mit serialize() in die Datenbank zu schreiben. Klappt auch ganz gut, das schreiben zumindest. Jetzt habe ich mit phpMyAdmin mir das angeschaut und festgestellt, dass dort folgendes steht:
Code:
a:120:{i:0;s:2:"e4";i:1;s:2:"c5";i:2;s:3:"Nf3";i:3;s:2:"e6";i:4;s:2:"d4";i:5;s:4:"cxd4";i:6;s:4:"Nxd4";i:7;s:3:"Nc6";i:8;s:3:"Nc3";i:9;s:3:"Qc7";i:10;s:3:"Be3";i:11;s:2:"a6";i:12;s:3:"Be2";i:13;s:3:"Nf6";i:14;s:3:"O-O";i:15;s:3:"Bb4";i:16;s:3:"Na4";i:17;s:3:"Be7";i:18;s:4:"Nxc6";i:19;s:4:"bxc6";i:20;s:3:"Nb6";i:21;s:3:"Rb8";i:22;s:4:"Nxc8";i:23;s:4:"Qxc8";i:24;s:3:"Bd4";i:25;s:3:"Qc7";i:26;s:2:"e5";i:27;s:3:"Nd5";i:28;s:2:"c4";i:29;s:3:"Nb4";i:30;s:3:"Bc3";i:31;s:2:"c5";i:32;s:3:"Bf3";i:33;s:3:"O-O";i:34;s:3:"Qe2";i:35;s:2:"f5";i:36;s:4:"Rfd1";i:37;s:4:"Rfd8";i:38;s:3:"Rd2";i:39;s:2:"a5";i:40;s:2:"a3";i:41;s:3:"Nc6";i:42;s:4:"Bxc6";i:43;s:4:"dxc6";i:44;s:4:"Rad1";i:45;s:2:"g6";i:46;s:3:"Kf1";i:47;s:3:"Kf7";i:48;s:3:"Ke1";i:49;s:3:"Ke8";i:50;s:2:"h3";i:51;s:4:"Rxd2";i:52;s:4:"Rxd2";i:53;s:3:"Rd8";i:54;s:3:"Qd1";i:55;s:4:"Rxd2";i:56;s:4:"Qxd2";i:57;s:3:"Bd8";i:58;s:3:"Qe3";i:59;s:3:"Qa7";i:60;s:3:"Kd1";i:61;s:2:"a4";i:62;s:3:"Qh6";i:63;s:4:"Qd7+";i:64;s:3:"Ke2";i:65;s:3:"Qf7";i:66;s:3:"Qe3";i:67;s:3:"Qe7";i:68;s:2:"g3";i:69;s:3:"Qa7";i:70;s:3:"Qd3";i:71;s:3:"Qd7";i:72;s:3:"Qc2";i:73;s:3:"Qa7";i:74;s:3:"Bd2";i:75;s:3:"Bc7";i:76;s:3:"Bc3";i:77;s:3:"Qa6";i:78;s:3:"Qd3";i:79;s:3:"Qb7";i:80;s:3:"Qe3";i:81;s:3:"Bb6";i:82;s:3:"Qh6";i:83;s:3:"Bd8";i:84;s:3:"Qe3";i:85;s:3:"Bb6";i:86;s:2:"h4";i:87;s:3:"Qf7";i:88;s:3:"Qf3";i:89;s:3:"Qd7";i:90;s:2:"h5";i:91;s:2:"g5";i:92;s:2:"h6";i:93;s:3:"Bd8";i:94;s:2:"g4";i:95;s:2:"f4";i:96;s:3:"Qe4";i:97;s:3:"Bb6";i:98;s:3:"Qc2";i:99;s:3:"Qa7";i:100;s:3:"Qd1";i:101;s:3:"Bc7";i:102;s:3:"Qh1";i:103;s:3:"Qa6";i:104;s:3:"Qe4";i:105;s:3:"Bd8";i:106;s:4:"Qxh7";i:107;s:5:"Qxc4+";i:108;s:3:"Qd3";i:109;s:5:"Qxd3+";i:110;s:4:"Kxd3";i:111;s:3:"Kf7";i:112;s:3:"Kc4";i:113;s:3:"Bb6";i:114;s:2:"f3";i:115;s:3:"Kg6";i:116;s:2:"b3";i:117;s:4:"axb3";i:118;s:4:"Kxb3";i:119;s:4:"Kxh6";}

das ist sehr cryptisch, aber mir fällt das a:120 auf. In jeder Zeile steht a: und einige Zahlen. Dazu habe ich folgendes MySQL Query:

Code:
$select = "SELECT * FROM " . $p->filetable . " WHERE MovesClean = :mc";
    
    $stmt = $p->con->prepare($select);
    $stmt->bindParam(":mc", $serialmoves);
    $stmt->execute();
    
    if ($stmt->rowCount() > 0) {
        echo "already in database<br>\n";
    } else {

Dieses Query soll verhindern, dass doppelte Paritien noch einmal geschrieben werden, bzw. dass jede Partie nur einmal in der DB steht.
Weiß jemand wofür das a:123 steht? Es funktioniert mir ein bisschen zu perfekt, ich habe aus einer .pgn mit 140+ Partien eine Partie ausgesucht und in eine andere Datei geschrieben und trotzdem wurde sie als dublikat aussortiert. Das funktioniert mir echt ein wenig zu perfekt.

Edit: Ach, eigenen Kopf vielleicht mal benutzen: a = Array, die Zahl ist die Anzahl der Elemente... höchstwarscheinlich... :)

Mfg
 
Zuletzt bearbeitet:
http://www.devphp.de/pgn/readsuggest.php?id=17
http://devphp.de/pgn/showpgn.php?id=17 oder:
http://www.devphp.de/pgn/pgnfiles/18Neckar-Open2014.pgn

Für die Googler oder sonstige, die es intressiert: In der .pgn stehen manchmal in "Zug-Zeilen" ein [ als erstes Zeichen, z.b. [%clk 1:38]....
Das kann man mit der Zeile
Code:
if ((strpos($line, '[') === 0) && (ctype_alpha(substr($line,1,1)) === true)) {...
beheben. Es wird dann nicht nur geprüft, ob die Zeile mit [ beginnt, sondern auch ob das Zeichen danach ein Buchstabe ist, also nicht % oder sonstiges. Ist natürlich immer noch nicht perfekt, denn in den Kommentaren könnte sicher auch "[Matt in 4 Zügen]" oder ähnliches stehen, aber fürs erste reicht der Hotfix.
 
Hi, es sind mal wieder einige Wochen ins Land gezogen, und mittlerweile habe ich tatsächlich die Dateien aufgedröselt und in die MySQL Datenbank geschrieben. Einige Probleme habe ich noch nicht in den Griff bekommen, z.b. werden manchmal führende Leerzeichen in die DB geschrieben in das "Züge" Feld. Das sieht dann so aus:
Code:
1.e4 e5 2.Nf3 Nc6 3.Bb5 a6 4.Ba4 Nf6 5.O-O Be7 6.Re1 b5 7.Bb3 O-O 8.c3 d5
 9.exd5 Nxd5 10.Nxe5 Nxe5 11.Rxe5 c6 12.Re1 Bd6 13.d3 Qh4 14.g3 Qh3 15.Re4 Qf5
 16.Nd2 Qg6 17.Re1 f5 18.a4 Rb8 19.axb5 axb5 20.Ne4 fxe4 21.dxe4 Bg4 22.Qd4 Bf3
 23.exd5 c5 24.Qh4 Rbe8 25.Be3 Qf5 26.Rac1 Be4 27.Bd1 Bxd5 28.Bc2 Qf3 29.Qxh7+ Kf7
 30.Qf5+ Kg8 31.Qxf3 Bxf3 32.Bd3 c4 33.Bf1 Re5 34.Bg2 Bh5 35.Bd4 Rxe1+ 36.Rxe1 Bf7
 37.Ra1 b4 38.cxb4 Bxb4 39.Ra8 Rxa8 40.Bxa8 g5 41.Kg2 Kh7 42.Be4+ Kh6 43.Be3 Kh5
 44.h3 Be6 45.g4+  1-0
Es sollte so aussehen:
Code:
1.e4 e5 2.Nf3 Nc6 3.Bb5 a6 4.Ba4 Nf6 5.O-O Be7 6.Re1 b5 7.Bb3 O-O 8.c3 d5
9.exd5 Nxd5 10.Nxe5 Nxe5 11.Rxe5 c6 12.Re1 Bd6 13.d3 Qh4 14.g3 Qh3 15.Re4 Qf5
16.Nd2 Qg6 17.Re1 f5 18.a4 Rb8 19.axb5 axb5 20.Ne4 fxe4 21.dxe4 Bg4 22.Qd4 Bf3
23.exd5 c5 24.Qh4 Rbe8 25.Be3 Qf5 26.Rac1 Be4 27.Bd1 Bxd5 28.Bc2 Qf3 29.Qxh7+ Kf7
30.Qf5+ Kg8 31.Qxf3 Bxf3 32.Bd3 c4 33.Bf1 Re5 34.Bg2 Bh5 35.Bd4 Rxe1+ 36.Rxe1 Bf7
37.Ra1 b4 38.cxb4 Bxb4 39.Ra8 Rxa8 40.Bxa8 g5 41.Kg2 Kh7 42.Be4+ Kh6 43.Be3 Kh5
44.h3 Be6 45.g4+  1-0

r15ch13's Code wird mittlerweile dafür verwendet, die DB zu füttern. Es steht sogar trim() dort, aber es kommt nichts getrimmtes an, bzw. nur die erste Zeile? ka...

PHP:
public function getMoves() {
        return trim($this->moves);
    }

Verstehe es nicht, wieso wird kommt das führende Leerzeichen in der DB an?
Wenn r15ch13 nochmal draufschauen könnte wär ich echt glücklich, ich schick ihm nochmal ne PM :)

Das Problem mit dem führenden Leerzeichen tritt auch manchmal bei den Namen auf, dort ist es noch schlimmer, denn mein Inhaltsverzeichnis ist dann an dieser Stelle kaputt.

Edit: z.b. hier:
http://devphp.de/pgn/edit.php?id=112
Dort steht bei Black " Gheng, Josef" statt "Gheng, Josef"
oder hier http://devphp.de/pgn/edit.php?id=1636
Im Moves Feld sind die führenden Leerzeilen, beim ersten Beispiel sind die Moves ok.

In der Datei steht tatsächlich [Black " Gheng, Josef"], aber es wird doch getrimmt?
 
Zuletzt bearbeitet:
Folgende Aenderungen an der Game-Klasse sollten das ganze beheben.

  • private $moves wird zum Array.
  • In der addMoves() wird trim() auf den Wert angewendet und fuegt ihn zum Array hinzu.
  • getMoves() verbindet mit implode() das Array $moves zu einem String.
  • In der addInfo() wird trim() auf den Wert angewendet. (Behebt " Gheng, Josef")

PHP:
class Game
{
    private $info  = [];
    private $moves = [];

    public function __construct()
    {
    }

    public function addInfo($name, $value)
    {
        $this->info[$name] = trim($value);
        return $this;
    }

    public function getInfo()
    {
        return $this->info;
    }

    public function addMoves($moves)
    {
        $this->moves[] = trim($moves);
        return $this;
    }

    public function getMoves()
    {
        return implode(" ", $this->moves);
    }
}
 
Wow, vielen Dank!

Das Problem bei den Namen taucht nicht mehr auf, das Inhaltsverzeichnis sieht tadellos aus.
Jetzt habe ich noch etwas modifiziert:
Code:
    public function getMoves()
    {
        return trim(implode(" ", $this->moves));
    }
... weil sonst immer ein führendes Leerzeichen in den Zugfeldern stand. Es begann sonst immer mit " 1." statt "1.".

Ok vielen Dank nochmal für Deine mitarbeit und Tips, sollten weitere Probleme auftreten, werde ich Dich wieder anquatschen :)

Oder ich schreibe das Ding noch einmal selber, da lernt man immer noch am meisten, wenn ich Zeit habe.

Für den Moment sieht es so aus, als liefe es perfekt, aber ich werde weiter testen, bis ich den nächsten Fehler finde :)

Edit: Und da ist das nächste Problem... bei einem upload sind leere Werte geschrieben worden, jetzt muss ich nur noch die Datei finden, bei der es passiert ist. Vielleicht schreibe ich den Dateinamen einfach mit in die DB, dann kann ich mir das regelmäßige löschen sparen und weiss in welcher Datei ich suchen muss.

Edit2: ok, das war einfach mit dem Dateinamen. Es ist bei dieser Datei aufgetreten
http://devphp.de/pgn/pgnfiles2/runde1.pgn
Dort wurden für White, Black, Round, Date etc. "NULL" in die DB geschrieben. Für mich sieht die Datei völlig valide aus. Es wurden lediglich die Züge korrekt geschrieben. Jetzt habe ich wieder einen hässlichen leeren Balken im Inhaltsverzeichnis. Hat jemand eine Idee warum?
 
Zuletzt bearbeitet:
Deine Aenderung tuts zwar, so wuerde man sich die leeren Eintraege im $moves Array direkt sparen.

PHP:
if(!empty(trim($line)) && !empty($game))
{
    $game->addMoves($line);
}

Fuer das DB Problem braeuchte man deinen Code der Werte in die DB schreibt. :)
 
Ich traue mich kaum ihn zu posten, weil er so UNGLAUBLICH hässlich ist, aber nun gut, hier ist er:

PHP:
require_once('class.pgn.php');
require_once('class.game.php');

require_once('vendor/autoload.php');

use AmyBoyd\PgnParser\Game;
use AmyBoyd\PgnParser\PgnParser;

$uploaddir = './pgnfiles2/';

if (!file_exists($uploaddir)) {
    mkdir($uploaddir, 0777, true);
}

// search for UMLAUTE etc, replace in filename:
$search = array('ä', 'ö', 'ü', 'ß', 'Ä', 'Ö', 'Ü', ' ');
$replace = array('ae', 'oe', 'ue', 'ss', 'Ae', 'Oe', 'Ue', '_');

$filename = basename($_FILES['userfile']['name']);
$filename = str_replace($search, $replace, $filename);
$uploadfile = $uploaddir . $filename;

$maxSize = 2000000;

// function starts here

function write2db($file, $pw, $mail, $name) {

    $p = new pgn();
    $g = new GameOfPgn();

    $games = $g->readGamesFromPgn($file);

    $parser = new PgnParser($file);

    $gms = 0;

    foreach ($games as $gamenum => $game) {

        $valuestring = "";
        $valuedblstring = "";
        $infoValueString = "";
        $sureInfo = "";
        $sureInfoValue = "";
        $sureInfoString = "";
        $sureInfoValueString = "";

        foreach ($game->getInfo() as $info => $infoValue) {

            $newcol = "ALTER TABLE " . $p->filetable . " ADD `" . $info . "` TEXT after `MovesClean`";

            try {
                if ($p->con->query($newcol)) {
                    echo("Query was successful ...<br>\n");
                } else {
                    echo("Query wasn't successful, check your script");
                }
            } catch (Exception $e) {
                // echo 'Exception abgefangen: ', $e->getMessage(), "\n";
            }

            // assemble strings
            $valuestring .= $info . ", ";
            $valuedblstring .= ":" . $info . ", ";
            $infoValue = rtrim($infoValue, "\""); // dirty hack, not a clean solution
            $infoValueString .= $infoValue . ", ";

            $sureInfo .= $info . "-_-//-_-";
            $sureInfoValue .= $infoValue . "-_-//-_-";

        }

        $gamemov = $parser->getGame($gms);
        $serialmoves = serialize($gamemov->getMovesArray());

        // insert into DB
        // find dubliactes 
        // try to select

        $select = "SELECT * FROM " . $p->filetable . " WHERE MovesClean = :mc";

        $stmt = $p->con->prepare($select);
        $stmt->bindParam(":mc", $serialmoves);
        $stmt->execute();

        if ($stmt->rowCount() > 0) {
            echo "Identische Partie schon in der Datenbank.<br>\n";
//            while ($row = $stmt->fetch()) { echo $row["White"]. " - " . $row["Black"];
//            }
        } else {

            $sureInfo = rtrim($sureInfo, "-_-//-_-");
            $sureInfoValue = rtrim($sureInfoValue, "-_-//-_-");

            $insert = "INSERT INTO " . $p->filetable . " (" . $valuestring . "Moves, MovesClean, UploadDate, UploadPW, CategoryID, UploadName, UploadEmail, FileName) VALUES (" . $valuedblstring . ":moves, :movesclean, :uploadDate, :uploadPW, :catID, :upname, :upEmail, :file)";

            $stmt = $p->con->prepare($insert);

            $sureInfoExplode = explode("-_-//-_-", $sureInfo);
            $sureInfoValueExplode = explode("-_-//-_-", $sureInfoValue);
            $infoexplode = explode(", ", $infoValueString);

            foreach ($sureInfoExplode as $key => $val) {
                $stmt->bindParam($sureInfoExplode[$key], mb_convert_encoding($sureInfoValueExplode[$key], "UTF-8", mb_detect_encoding($sureInfoValueExplode[$key])));
            }

            require_once ('../includes/PasswordHash.php');

            if ($name == "") {
                $name = "NoName";    
            }
            if ($pw == "") {
                $pw = "NoPassword";    
            }            
            if ($mail == "") {
                $mail = "NoEmail";    
            }            

            $cat = 0;

            $hasher = new PasswordHash(8, FALSE);
            $hash = $hasher->HashPassword($pw);

            $stmt->bindParam(":moves", $game->getMoves());
            $stmt->bindParam(":movesclean", $serialmoves);

            $stmt->bindParam(":uploadDate", $p->today);
            $stmt->bindParam(":upEmail", $mail);
            $stmt->bindParam(":upname", $name);
            $stmt->bindParam(":uploadPW", $hash);
            $stmt->bindParam(":catID", $cat);
            $stmt->bindParam(":file", $file);

            $stmt->execute();

            echo 'Partie in Datenbank geschrieben.' . "<br>\n";
            echo "<hr>";

            $gms++;
        }
    }

    echo count($games) . " Spiele in der Datei.";
    echo "<br>";
}

// FUNCTION ENDS HERE

// GET VARIABLES OF $_POST

if (!empty($_POST)) {

    $pw = filter_input(INPUT_POST, "pass", FILTER_SANITIZE_STRING);
    $name = filter_input(INPUT_POST, "name", FILTER_SANITIZE_STRING);
    $mail = filter_input(INPUT_POST, "mail", FILTER_SANITIZE_STRING);
}

// ACTUAL UPLOAD STARTS HERE //

if (file_exists($uploadfile)) {
    die("Die Datei $uploadfile existiert bereits.");
} else {
    $allowedExts = array("pgn");
    $temp = explode(".", $_FILES["userfile"]["name"]);
    $extension = end($temp);

    if (($_FILES["userfile"]["size"] < $maxSize) && in_array($extension, $allowedExts) && ($_FILES["userfile"]["error"] == 0)) {
        if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {
            // get content, encode it to UTF8, put content back into file
            $file_contents = file_get_contents($uploadfile);
            $encoded_content = mb_convert_encoding($file_contents, "UTF-8", mb_detect_encoding($file_contents));
            file_put_contents($uploadfile, $encoded_content);
            echo("Ihre Datei wurde erfolgreich übertragen.<br>\n");
            echo 'Alles unterhalb dieser Zeile sollte für Sie irrelevant sein<br>';
            echo'<a href="javascript:history.back()">Zurück</a><br><br>' . PHP_EOL;
            write2db($uploadfile, $pw, $mail, $name);
        } else {
            echo "Dateiupload fehlgeschlagen!\n";
            echo $uploadfile;
        }
    } else {
        echo "Dateiupload fehlgeschlagen!\n";
        echo("Zulässige Dateigröße überschritten?");
    }
}

Er ist sehr hässlich, aber meistens funktioniert er ja. Zum Verständnis:
$sureInfoExplode = explode("-_-//-_-", $sureInfo);
Das "-_-//-_-" habe ich benutzt, weil kommas etc. einfach nicht funktioniert haben. Es musste einfach etwas aussergewöhnliches sein, das sonst nicht in den Dateien vorkommt.

Die class.pgn.php könnte ich auch noch posten bei bedarf, aber dort steht soviel Müll drin, dass ich sie nochmal neu schreiben sollte. Zuerst war das ganze Projekt Dateien-basiert, jetzt ist es MySQL-basiert. In der Zeit hat sich viel "Müll" angesammelt in der Datei.

Die upload2.php könnte auch noch intressant sein, kann ich auch bei bedarf posten.

PasswordHash.php ist die PW-Hash funktion von Drupal, die ich gefunden habe beim stöbern. Funktioniert super.

Der pgn parser von AmyBoyd leistet hervorragende Arbeit bei der Identifizierung von Dublikaten.

Naja, sonst... läuft, ist aber hässlich wie die Nacht :)

Edit: hier ist das Formular, dass für den upload verantwortlich ist, es könnte helfen...
<form enctype="multipart/form-data" action="upload_file2.php" method="POST">

<label for="userfile">Wählen Sie ihre Datei aus: </label>
<input name="userfile" type="file"><br><br>
Veröffentlichen Sie Ihre Partie mit <input type="submit" value="Senden" class="send">
<br><br>
<b class="mb">Freiwillige Angaben:</b><br>
<label for="mail" class="lab">E-Mail</label>
<input name="mail" id="mail" type="text">
<br>
<label for="name" class="lab">Name</label>
<input name="name" id="name" type="text">
<br>
<label for="pw" class="lab">Passwort</label>
<input name="pw" id="pw" type="password">

</form>
Ergänzung ()

Oh, ich habe noch mehr Datein gefunden, die nicht korrekt geschrieben werden

./pgnfiles2/9Neckar-Open2005.pgn
./pgnfiles2/11Neckar-Open2007.pgn

Habe hier einen Screenshot vom phpmyadmin gemacht

http://devphp.de/img/myadmin.jpg

der Code ist also nicht nur hässlich, sondern auch buggy.
Nunja, immerhin werden einige Felder geschrieben, bei der runde1.pgn wurden nur die Züge geschrieben.
Endless bugfixing :(

http://www.devphp.de/pgn/openings2.php
Hier ist wieder etwas falsch angekommen, [Event ist kein Zug, aber wohl in das Moves Feld gerutscht.
Ich schreibe demnächst mal eine Seite die mir die fehlerhaften Reihen anzeigt.

Die ./pgnfiles2/9Neckar-Open2005.pgn scheint die größten Probleme zu machen, dort sind auch Reihen ohne "Moves" zu finden.
In diesen Reihen sind aber die anderen Felder ausgefüllt.

Wie auch immer, Schluss für heute =)
Ergänzung ()

PHP:
            foreach ($sureInfoExplode as $key => $val) {
                $stmt->bindParam($sureInfoExplode[$key], mb_convert_encoding($sureInfoValueExplode[$key], "UTF-8", mb_detect_encoding($sureInfoValueExplode[$key])));
            }

Was ich mir dabei gedacht habe, weiss ich selbst nicht mehr. Ich denke, dort habe ich foreach noch nicht wirklich verstanden. $sureInfoExplode[$key] müsste einfach durch $val zu ersetzen sein.

Ich habe hier mal eine .zip zusammengestellt, dann kann man das gesamte Projekt anschauen und testen.

http://devphp.de/pgn_project.zip

Ich hoffe, ich habe nichts vergessen einzupacken, readme lesen nach dem entpacken...
Ergänzung ()

Die Seite mit den falschen Reihen ist hier:

http://devphp.de/pgn/false_rows.php

PHP:
$sel = "SELECT * FROM " . $p->filetable . " WHERE White IS NULL";

$stmt = $p->con->prepare($sel);
$stmt->execute();

echo "<b>".$stmt->rowCount(). " White = NULL</b><br>".PHP_EOL;

while ($row = $stmt->fetch()) {
    
    foreach ($row as $key => $val) {
        if ($val != NULL && !is_numeric($key)) {
            echo "<b>".$key. "</b> : ".$val."<br>".PHP_EOL;
        }
    }
    echo "<hr>".PHP_EOL;
}
Das sind natürlich nicht alle, nur mit WHITE IS NULL
Intressant ist, dass manche Reihen im Feld "MovesClean" ein gefülltes serialize'd array haben, aber ein leeres "Moves" Feld. "MovesClean" ist das Array von AmyBoyd's pgn parser.

ID : 4433 dort ist ein mismatch zwischen Moves and MovesClean, im Array stehen andere Züge als im Moves.

Aha, das mismatch tritt häufiger auf, auffallend ist auch, dass die IDs immer in 2er Schritten inkrementieren, es scheint, dass dort 2 Reihen geschrieben werden...

http://devphp.de/img/myadmin2.png
Screenshot vom phpmyadmin, nach ID sortiert, jedes 2. Moves ist leer, MovesClean passt nicht zu den Moves... Nur wenige Felder gefüllt.... MovesClean passt weder zur Reihe davor noch danach...

Der Fehler muss in der geposteten Funktion liegen, aber wo genau? Kann ich mir im Moment nicht erklären...

http://devphp.de/img/myadmin3.png
Seitenweise 1x Moves belegt, 4x frei, keine Ahnung wo das Array her kommt, mismatches überall...
 
Zuletzt bearbeitet:
Erstmal: Wow das ist ja ein Chaos! Das musst du unbedingt aufraeumen! Wie waere es mal mit einem Framework? Microframework http://lumen.laravel.com/ oder normales http://laravel.com/

Ich glaube ich habe das Problem gefunden. In der Game-Klasse wird mit strpos($line, '[Event') geprueft ob eine neue Partie anfaengt. Nun gibt es in deinen Dateien auch [EventDate "2005.03.??"] und da wird nun neue Partie angefangen in der dann nur noch SourceDate, Source und die Moves enthalten sind.

Sollte dadurch geloest sein:
PHP:
if(strpos($line, '[Event') !== false)
durch folgendes ersetzen:
PHP:
if (preg_match('/(\[Event "(.*)"\])/', $line)) {

Edit: Und noch eine Aenderung beim erkennen der Partieinformationen.
PHP:
class GameOfPgn {
    private $info  = [];
    private $moves = [];
 
 
    public function addInfo($name, $value)
    {
        $this->info[$name] = trim($value);
        return $this;
    }
 
    public function getInfo()
    {
        return $this->info;
    }
 
    public function addMoves($moves)
    {
        $this->moves[] = trim($moves);
        return $this;
    }
 
    public function getMoves()
    {
        return trim(implode(" ", $this->moves));
    }
    
    function readGamesFromPgn($file) {
        if (!file_exists($file))
            return [];

        $content = file_get_contents($file);
        $lines = explode("\n", $content);
        $games = [];
        $game = null;

        foreach ($lines as $line) {
            // Neues Spiel gefunden
            if (preg_match('/(\[Event "(.*)"\])/', $line)) {
                if (!empty($game)) {
                    $games[] = $game;
                }

                $game = new GameOfPgn();
            }

            if(preg_match('/(\[(?P<name>.*) "(?P<value>.*)"\])/', $line, $matches)) {
                if (!empty($game) && isset($matches['name']) && isset($matches['value'])) {
                    $game->addInfo($matches['name'], $matches['value']);
                }
            } else {
                if(!empty(trim($line)) && !empty($game))
                {
                    $game->addMoves($line);
                }
            }
        }
        if (!empty($game)) {
            $games[] = $game;
        }
        return $games;
    }
}
 
Zuletzt bearbeitet: (Game-Klasse komplett hinzugefuegt)
Das ist unglaublich. Das wäre mir in 5 Jahren nicht aufgefallen. Das hätte man auch einfach mit einem zusätzlichen Leerzeichen, statt
PHP:
if(strpos($line, '[Event') !== false)
PHP:
if(strpos($line, '[Event ') !== false)
beheben können. Habe jetzt Deine Zeile genommen und es gibt bisher keine leeren Moves Felder, und keine leeren Werte in den Spalten "White" und "Black".

EINE, Zeile ist mir jedoch aufgefallen, dort steht im Moves Feld folgendes:
PHP:
[Event "11. Int. Neckar-Open 2007"]  1. d4 Nf6 2. c4 e6 3. Nc3 Bb4 4. Qc2 O-O 5. a3 Bxc3+ 6. Qxc3 b6 7. Bg5 Bb7 8. e3 d6 9. Ne2 Nbd7 10. Rd1 h6 11. Bh4 Ne4 12. Bxd8 Nxc3 13. Nxc3 Rfxd8 14. f3 c5 15. Kf2 Nf6 16. Be2 Kf8 17. b4 cxd4 18. exd4 a5 19. Rb1 axb4 20. axb4 Nd7 21. Rhc1 Rdc8 22. g4 Ke7 23. h4 Ra3 24. c5 Raa8 25. Bb5 Nf6 26. g5 hxg5 27. hxg5 Nh7 28. Bd3 Nxg5 29. f4 Nf3 30. d5 exd5 31. Kxf3 d4+ 32. Be4 Bxe4+ 33. Nxe4 Ra3+ 34. Kg4 1-0
Und das Event Feld ist NULL.
Das ist die erste Partie aus http://devphp.de/pgn/pgnfiles2/11Neckar-Open2007.pgn
Es scheint der einzige Fehler zu sein.

Nochmals vielen Dank für die Hilfe :)
 
In der geposteten Game Klasse ist Dir ein Fehler unterlaufen, in der readGamesFromPgn() gibt es keine $matches. $game->addInfo($matches['name'], $matches['value']) kann also nicht funktionieren. Kein Ahnung wo das her kommt.
 
Doch $matches wird in der Funktion preg_match 2 Zeilen darueber gefuellt.
 
Zurück
Oben