[Apache, phpmyadmin, html, PHP, ...] Datenbank mit webbasiertem Zugriff erstellen

  • Ersteller Ersteller boss3D
  • Erstellt am Erstellt am
Ich hab mal in meinem Beitrag drei drüber ein Beispiel geschrieben. Ich finde es ist ganz hübsch geworden. ;-)

Wenn du es auf Teufel komm raus selber machen willst, lies bitte im Handbuch unter mysqli_real_escape_string() nach, damit du dir keine Sicherheitslücke schaffst.
 
Zuletzt bearbeitet:
aha, also wenn ichs richtig verstehe, dann ist PHP: addslashes - Manual recht rudimentär und geht nicht explizit (wenn dann eher zufällig ^^) auf die "bedürfnisse" der db ein? daher sollte man lieber eine db-speziefische escape-funktion nutzen. im größten notfall kann man aber sicher auch händisch mit str_replace "was eigenes bauen" *duck* also ich mein jetzt, wenn es irgendwas ganz krudes ist, wo es nix vorgefertigtes gibt ^^

aha, und PHP: mysqli::real_escape_string - Manual berücksichtigt wohl auch noch den charset der verbindung - oha oha. gut zu wissen :)
 
Jaja Wir alle Lieben XSS.
Ein einfaches Beisppiel wäre in einem Beschreibungsfeld deines Scripts einfach den folgenden Code einzutippen. Dieser wird dann in der Datenbank gespeichert und bei der Ausgabe in die Website eingebaut. Als Resultat wird dann bei Auswerten.php Das JavaScript ausgeführt.

PHP:
";echo"<script type='text/javascript'>alert('Hallo Welt!');</script>";echo"

Viel bösartiger wäre da aber noch das Anlegen eines neuen Users mit root Zugriff für die Datenbank per mysqli
 
joa, und dagegen hatte ich immer addspecialchars und äh irgendwas mit html genutzt ^^ (das machte glaube aus den tags dieses > und < zeugs, weiß grad nich mehr genau).
 
<script type="text/javascript">


Das wäre das gleiche JavaScipt in ASCII geschrieben und das wird dann von htmlspecialchars nicht erfasst.

Im Ergebnis wird das Javascript dann auch wieder ausgeführt und du hast genau das gleiche Problem wie ohne htmlspecialchars.

;)
 
Das wird durchaus erfasst. Kannst es ja mal ausprobieren.

Die & werden von htmlspecialchars zu & umgewandelt, wodurch keine Gefahr mehr besteht.
 
Zuletzt bearbeitet:
htmlspecialchars alleine macht m.E. eine Website jedenfalls nicht sicher. Ich muss nochmal schauen wo es stand, aber ich meine in Erinnerung zu haben, das es auf jeden fall auch dann noch genug Angriffsvektoren gibt.
 
Natürlich gibt es weitere Angriffsvektoren. Aber diese eine spezifische Sicherheitslücke kann man so schließen.

Mein Lieblingsangriff (funktioniert bei erstaunlich vielen Forensoftwares) ist, ein "Bild" einzubetten, das in Wirklichkeit ein Link ist.

EDIT: Netter Link zum Thema
http://piratesecurity.de/vektoren/
 
Zuletzt bearbeitet:
Ihr könnt den Thread gerne weiterhin für themenverwandte Diskussionen nutzen, ich lese immer noch interessiert mit. ;)

Auch wenn ich nach wie vor glaube, mit dem Thema in meiner beruflichen Zukunft nicht mehr in Berührung zu kommen, so hat es dennoch mein Interesse geweckt und ich möchte mir daher doch noch ein Buch kaufen um mich a) vertiefen und b) noch ein bisschen am Projekt (jetzt ohne Zeitdruck) weiterbasteln zu können. Habt ihr irgendwelche Vorschläge? Ich wäre jetzt erstmal auf das hier gekommen, aber ich bin mir nicht ganz sicher, ob das nicht "zu tief" ansetzt?! Ich bin zwar alles andere als erfahren mit php und mysql, aber Programmiergrundlagen von 0 weg brauche ich dann auch nicht. Schwer einzuschätzen. Andere Bücher wirken wieder eher wie für Fortgeschrittene ...

BTW: Jetzt dann am WE möchte ich auch den Code kommentieren. Ich werd's dann posten, damit mir bitte dann nochmal wer kurz drüberschaut.
 
Och, ich glaube wir haben den Thread lange genug für andere Themen missbraucht, man könnte ja auch einfach neue Threads erstellen... ;-)

Das Buch kenne ich nicht. Ohne das konkrete Buch zu kennen, habe ich festgestellt, dass der SQL-Teil von solchen PHP-und-MySQL-Büchern von den Autoren oft seeeehr stiefmütterlich behandelt wird (vermutlich nicht mal, weil die Autoren keine Ahnung von SQL hätten, sondern eher, weil der Platz in so einem Buch halt irgendwann ausgeht). Ich würde dir also empfehlen dir ein zusätzliches Buch zu SQL zu kaufen. Es ist oft sinnvoll möglichst viel in der Datenbank zu machen (join, Subqueries, trigger, usw. usf.), da schneller (sofern mit sinnvollen Indizes gearbeitet wird).

Was ich in zwei Amazon-Rezensionen gelesen habe: Scheinbar enthält das Buch keine Informationen über die Neuerungen in PHP 5.5, 5.4 und 5.3. Das ist zwar jetzt nicht "schlimm" (einerseits wirst du diese als Anfänger nicht sofort brauchen, andererseits ist es nicht soo viel Neues und man kann das online ganz gut nachschlagen), aber ich würde ein Buch, das "PHP 5.5 ..." heißt und nur auf dem Stand von PHP 5.2 ist aus Prinzip boykottieren. :-D

Code kommentieren ist immer ne gute Idee. Als Format haben sich die "DocBlocks" von PHPDOC bewährt: phpDocumentor
Wenn du in dem Format kommentierst, kannst du als Mensch deine Kommentare lesen, aber auch viele gute IDEs und PHP-Editoren können dir dann automatisch Zusatzinformationen zu deinem Code anzeigen und wenn du möchtest kannst du auch die PHPDOC-Software selbst verwenden.
 
So es juckt mich ja nach Abschluss des Projektes schon in den Fingern das ganze mal nachzubauen. Ich muss mich jetzt nur noch dazu motivieren das auch wirklich mal Anzufangen.

Vielleicht kann ich ja das ein oder andere Modul tatsächlich mal gebrauchen x-D. Man kann eigentlich nie genug Code auf Lager haben ;)
 
Beim Kommentieren hat's erfreulicherweise ziemlich wenig gegeben, das ich nicht verstanden habe. Das wäre folgendes:

1) Hier sehe ich natürlich auf der Website, was dieser Code macht, aber so wirklich erklären könnte ich die if-Zeile (nur diese, die echos sind klar) nicht. "<>" habe ich noch nie in irgendeiner Programmiersprache gesehen und wundere mich, dass das überhaupt funktioniert. Aber scheinbar heißt das semantisch "dazwischen"?! Irgendwie fehlt mir dann für meine Logik eine Variable, sodass ich sagen könnte, "Wenn Variable_x zwischen Jahr:Timestamp und Jahr:Timestamp liegt, dann...".
PHP:
/**
* ???
*/
if (date('Y', $wochenanfang) <> date('Y', $wochenende)) {
    echo '            Kalenderwoche '.$kw.': '.date('j.m.', $wochenanfang).' - '.date('j.m.Y', $wochenende);
} else {
    echo '            Kalenderwoche '.$kw.': '.date('j.m.Y', $wochenanfang).' - '.date('j.m.Y', $wochenende);
}
2) Dieses ganze Zeug hier durchblicke ich gar nicht. Zuerst wird $row_collector als array angelegt, aber dann kriegt es als Element $row, das wiederum ein array zu sein scheint, was das erste in meiner Logik schon zu einer zweidimensionalen Matrix machen würde. Dann kriegt $row_collector auch noch einen zweiten Index angehängt ... und am Ende sagt man dem Teil wieder, dass es "nur" ein array sein soll?! :what:
PHP:
$row_collector = array();
if (mysqli_num_rows($db_erg)) {
     while ($row = mysqli_fetch_assoc($db_erg)) {
            if (!isset($row_collector[$row['tID']])) {
                $row_collector[$row['tID']] = array();
                $row_collector[$row['tID']]['taet'] = $row['Taetigkeit'];
                $row_collector[$row['tID']]['data'] = array();
            }
            if (!isset($row_collector[$row['tID']]['data'][$row['pID']])) {
                $row_collector[$row['tID']]['data'][$row['pID']] = array();
                $row_collector[$row['tID']]['data'][$row['pID']]['prod'] = $row['Produkt'];
                $row_collector[$row['tID']]['data'][$row['pID']]['desc'] = $row['Beschreibung'];
                $row_collector[$row['tID']]['data'][$row['pID']]['user'] = $row['User'];
                $row_collector[$row['tID']]['data'][$row['pID']]['time'] = array();
            }
            $row_collector[$row['tID']]['data'][$row['pID']]['time'][$row['Datum']] = $row['Zeit'];
        }
3) ^^ Und woher kommen die ganzen Indexe wie "tID", "data", "prod", "desc", ... ? In der DB haben wir nichts gleichnamiges. :huh:

4) Und dann wäre noch dieses Teil hier in formular.php. Wieso ist es bei manchen Elementen nötig (?), über "row->" zuzugreifen (z. B. bei id und rechte), bei anderen (z. B. username) aber nicht, obwohl die in der DB in der selben Tabelle liegen? Was genau ist überhaupt der Sinn von diesem "$row->"?
PHP:
if ($row->passwort == $password) {
     $_SESSION['name'] = $username;
     $_SESSION['id'] = $row->id;
     $_SESSION['rechte'] = $row->rechte;
     $_SESSION['ip'] = $ipadresse;
     $_SESSION['last_on'] = $now[0];
 
hui, dann mal stück für stück ^^

1) das <> ist im endeffekt nur ne andere schreibweise für !=. auf deutsch: wenn beide verschieden sind ;) wenn du dir die dokumentation zu date anschaust, dann stellste ja fest, dass date('Y'); die jahreszahl zurückgibt. was ich hier geprüft habe ist schlicht und ergreifend, ob die jahreszahl des wochenanfangs dem des wochenendes entspricht. weil? jahreswechsel ;) eine woche schert sich nicht um nen glatten jahresabschluss ^^ zum bsp ist 2013 zu 2014 der wochenanfang (wie immer ein montag) der 30.12. gewesen. das wochenende hingegen war der 05.01. - nun gibts 2 einfache möglichkeiten: ich lasse die jahreszahl immer weg, dann stände hier "30.12. - 05.01.", oder ich zeige sie immer an. dann wäre das ein "30.12.2013 - 05.01.2014" .> finde ich schonmal deutlich besser. jedoch hat man eben bei der 2. anzeige das ganze jahr über dann 2mal 2014 stehn. die nächste woche gleich sähe in dem format so aus: "06.01.2014 - 12.01.2014". sicherlich richtig, aber ich finds halt störend. daher hab ich das über diese if-else gelöst gehabt. sind die jahreszahlen verschieden, zeige beide an, ansonsten nur die hintere. so steht mit diesem konstruckt beim jahreswechsel also immernoch "30.12.2013 - 05.01.2014", bei der darauffolgenden woche aber nur noch eine gekürzte fassung: "06.01. - 12.01.2014"

also als fazit: reine optik ^^

2 überspringe ich mal fix, das mach ich am ende...

3) tID und pID sind unsere aliasnamen ausm sql-string ;) da steht nachm select irgendwo was ala "t.ID AS tID" und "p.ID AS pID". deswegen nutze ich sie ja hauptsächlich, da man in php leider sonst probleme bekommt. beide spalten heißen ID - wie greift man nun auf die gewünschte zu - hatte ich ja schonmal lang und breit erwähnt. data, desc, time... sind schlicht selbstgewählte schlüssel für die arrays.

4) wegen dem sinn von ->... du fragst hier sicherlich per fetch_object ab. das sagts dir doch schon. OBJECT! ^^ was ist ein objekt? eine instanz(-variable) einer klasse. mit -> greifst du nun eben auf die klassen-variablen zu ;) würdest du fetch_assoc nehmen (was ein assoziatives array erstellt), dann hast du eben ein array und kein objekt, daher ist die zugriffsmethode auch anders. jut, wieso manchmal aus der db und manchmal aus der variable? das is eigentlich völlig bumms. hier isses nu so gelöst, dass NUR das aus der db bezogen wird, was so im code noch nich bekannt ist. die ip adresse wird nie gespeichert und im code ermittelt. der username wird per formular übergeben und in $username gespeichert. genau nach diesem wird in der db gesucht. die db wird dir also nie was anderes als usernamen zurückliefern, wie das was eh in der $username variable steht. wie gesagt -> es is völlig egal welchen wert du nimmst, sind eh die gleichen.


2) sow, jetzt dazu...
grundproblem für uns war doch deine wochenansicht. also prinzipiell ne schöne sache, umsetzungstechnisch aber eben verzwickt. wir speichern die daten ja nicht wochenweise, sondern die zeiten (die einzelnen tage) für sich. und zu allem überfluss noch in 2 verschiedenen tabellen (projektdaten und zeiten getrennt). nun haben wir zu EINEM projekt (eine zeile aus projekte) bis zu 7 daten (7 zeilen aus zeiten) die in EINE tabellenzeile zusammengefasst werden müssen. ich hab hier also einen "zeilen-zusammen-sammler" gebaut. eben einen "row-collector" ^^

unser großer sql-string bewirkt ja nun folgendes: zu jeder zeit, kopiert er vorne dran quasi noch die projektdaten (mal arg bildlich gesprochen, ob vorn oder hinten is bugi). unsere ergebniszeilen sehen also grob runtergerissen so aus:
((projekt-daten #1) (zeit-daten #1))
((projekt-daten #1) (zeit-daten #2))
((projekt-daten #1) (zeit-daten #3))
((projekt-daten #2) (zeit-daten #4))
...

hier haben wir also 3 verschiedene zeitdaten die immer die selben projektdaten "vorn dran" haben. in jedem durchgang von while ($row = mysqli_fetch_assoc($db_erg)) {} haben wir also immer ALLE daten. eigentlich sieht es ja noch nen stück verzwickter aus ^^ weil ein projekt ist ja eine tätigkeit/produkt kombination. also in projekt 1 UND projekt 2 kann die tätigkeit dennoch die selbe sein, nur das produkt ist verschieden. aber dieses verschiedene produkt macht es eben auch zu verschiedenen projekten.

in der letzten zeile siehst du bt den "maximal-ausbau" des mehrdimensionalen arrays. ich kann dir die struktur ja mal versuchen aufzuschlüsseln:
Code:
row_collector
 |
 |_ (tätigkeiten) // -> per id der tätigkeit (also für jede tätigkeit wird hier ein arrayfeld angelegt. bei 3 tätigkeiten, hat row_collector also 3 elemente.
      |
      |_ 'taet' // -> hier wird der klartext für die tätigkeit gespeichert. also die tätigkeit mit der id 1 heißt im klartext "hochschlafen" :ugly:
      |_ 'data' // -> das wird ein weiteres subarray und hierrein sollen dann die produkte
            |
            |_ (produkte) // -> wieder wie bei tätigkeiten, nur diesmal für alle produkte, die mit dieser tätigkeit in zusammenhang stehen (also nicht stehen können, sondern tatsächlich stehen)
                  |
                  |_ 'prod' // -> wieder der name des produkts als klartext
                  |_ 'desc' // -> die projektbeschreibung (genau hier ist es nämlich das projekt, weil eben produkt UND tätigkeit bekannt sind - beide kombiniert -> projekt. also auch die beschr speichern)
                  |_ 'user' // -> den kerl halt auch speichern, ist glaube der klartext, weil das wäre zum ausgeben gedacht (sofern mans braucht - admin, wenn er die daten mehrerer user abfragt)
                  |_ 'time' // -> und hier nun schlussendlich das letzte subarray für unsere (bis zu 7) zeiten die zu diesem projekt in dieser woche gehören.
                        |
                        |_ (timestamp) = zeit // -> schlussendlich wird die eigentliche zeit mit dem timestamp des tages noch im array abgelegt
so erkennt mans wohl am ehesten, was ich da für eine datenstruktur aufgebaut hab ^^

kleine randbemerkung: sollte man mehrere wochen anzeigen wollen, müsste man bei 'time' ansetzen und die struktur hier weiter verfeinern. statt time dann ein week und gespeichert werden dann nicht die einzelnen zeiten, sondern weitere subarrays, die per kw als key gespeichert werden (die kw bekommt man ja easy aus dem timestamp des tages). innerhalb des kw-key-array-elements würde dann wieder das row datum = row zeit kommen. auf 'time' als zwischenkey kann man hier dann getrost verzichten. aber wie gesagt, das ist nur eine randbemerkung für zukünftige ausbau maßnahmen ^^


so, was wird innerhalb der while-schleife nun gemacht? es wird IMMER die zeit gespeichert. und zwar nach $row_collector[$row['tID']]['data'][$row['pID']]['time'][$row['Datum']] = $row['Zeit']; was für probleme treten da höchstwarscheinlich auf? nuja, index-fehler noch und nöcher :fresse: wir müssen also VORHER dafür sorgen, dass die ganzen indexe auch existieren. dazu sind die if's da. wenn der erste schritt garnich existiert, also die tätigkeit noch garnich angelegt ist, dann tu eben dies -> leg die tätigkeit an. wir erinnern uns an mein (projekt) (zeiten) konstrukt da. wobei projekt ja wie gesagt aus tätigkeit und id besteht. es kann also durchaus sein, dass bei einem weiteren durchlauf die selbe tätigkeit kommt, dann wäre dieser erste schritt schon gesetzt und diese erste if würde geskipped werden. ändert sich die tätigkeit aber, wird sie ggf wieder neu angelegt (also ein row_collector[2] angehängt meinetwegen). zeitgleich werden noch die grunddaten gespeichert - hier eben der klartext-name.
in der 2. if wird dann eben auf das produkt geprüft. mehrere zeiten können zum selben produkt der selben tätigkeit gehören. gibts dieses produkt für diese tätigkeit noch nicht, wird es hiermit angelegt und gleichzeitig wieder mit den anderen daten gefüttert. da haben wir dann also ein row_collector[2]['data'][1] (also tätigkeit mit id 2 und produkt mit id 1).

genau JETZT ist sichergestellt, dass die benötigte struktur für den letzten befehl auch wirklich vorhanden ist. row-tID ist vorhanden, data wurde da gleich mit angelegt. row-pID gibts auch und auch hier wurde time gleich mit angelegt. und genau an dieses ...time-(sub)array hängen wir nun unser timestamp = zeit an.


weitere randnotiz: für den ausbau auf mehrere wochen müsste eine 3. if angefügt werden. nach der 2. if erstellt man aus dem aktuellen datum (row[datum]) per date('W', datum); die KW und fragt in besagter 3. if dann einfach ab, ob es ...[week][KW] schon gibt. wenn nicht, wird es angelegt und als weiteres subarray gebastelt. man bedenke: week ersetzt in diesem falle time ^^ die letzte zeile müsste dann nur noch wie folgt abgeändert werden. aus ...[time][timestamp] = zeit; wird dann eben ein ...[week][KW][timestamp] = zeit;

zum abschließenden verständnis: du hast insofern recht, dass es nicht eindimensional ist. tatsächlich hast du am ende ein *zähl* 5-dimensionales array (mit der optionalen week erweiterung sogar 6 ^^).
 
^^ Man lernt nie aus, vielen Dank!

3) Ich wusste nicht, dass das, was du im SQL String angibst, für den gesamten Code gilt. Ich dachte, das wäre exklusiv für dieses query.

2) Ist es also ne Matrix, hm. Alles andere hätte mich auch gewundert. ;)
 
Ich bastle gerade aus Interesse an unserer Website weiter und zwar versuche ich gerade, vorhandene DB-Einträge auswähl- und editierterbar zu machen (wie wir's ja vor ein paar Wochen noch vorgehabt hatten) ...

Jedenfalls hier mein Ansatz (blau = neu von mir hinzugefügter Code):

auswerten.php
Code:
?php
    $db_erg = mysqli_query($mysqli, "SELECT t.taetigkeit AS Taetigkeit, p.produkt AS Produkt, t.id AS tID, p.id AS pID, pr.beschreibung AS Beschreibung, u.name AS User, z.zeit AS Zeit, z.datum AS Datum FROM zeiten AS z, projekte AS pr, user AS u, taetigkeiten AS t, produkte AS p WHERE z.datum >= '".$wochenanfang."' AND z.datum <= '".$wochenende."' AND u.name = '".$user."' AND u.id = z.userid AND pr.id = z.taetprodid AND pr.taetigkeit = t.id AND pr.produkt = p.id ORDER BY z.datum ASC;");
	if (!$db_erg) {
        die ('Ungültige Abfrage: '.$mysqli->error);
    }

    echo '<table>';
    echo '  <tr>';
    echo '    <td colspan="10" class="head_cap">';
    echo '      <table style="width:100%; border:none; background-color:#A9F5BC;"><tr>';
    echo '        <td style="border:none" align="left"><input type="submit" value="<<" name="prevWeek" class="switch"></td>';
    echo '        <td style="width:90%; border:none; text-align:center">';
    if (date('Y', $wochenanfang) <> date('Y', $wochenende)) {
        echo '            Kalenderwoche '.$kw.': '.date('j.m.', $wochenanfang).' - '.date('j.m.Y', $wochenende);
    } else {
        echo '            Kalenderwoche '.$kw.': '.date('j.m.Y', $wochenanfang).' - '.date('j.m.Y', $wochenende);
    }
    echo '            <input type="hidden" value="'.$wochenanfang.'" name="wa">';  
    echo '            <input type="hidden" value="'.$wochenende.'" name="we">';  
    echo '          </td>';
    echo '        <td style="border:none" align="right"><input type="submit" value=">>" name="nextWeek" class="switch"></td>';
    echo '      </tr></table>';
    echo '    </td>';
    echo '  </tr>';
    echo '    <tr>
    			<th></th>
                <th>Tätigkeit</th>
                <th>Produkt</th>
                <th>Beschreibung</th>
                <th width="150">MO</th>
                <th width="150">DI</th>
                <th width="150">MI</th>
                <th width="150">DO</th>
                <th width="150">FR</th>
                <th width="150">SA</th>
                <th width="150">SO</th>
            </tr>';
    $row_collector = array();
    if (mysqli_num_rows($db_erg)) {
        while ($row = mysqli_fetch_assoc($db_erg)) {
            if (!isset($row_collector[$row['tID']])) {
                $row_collector[$row['tID']] = array();
                $row_collector[$row['tID']]['taet'] = $row['Taetigkeit'];
                $row_collector[$row['tID']]['data'] = array();
        }
        if (!isset($row_collector[$row['tID']]['data'][$row['pID']])) {
            $row_collector[$row['tID']]['data'][$row['pID']] = array();
            $row_collector[$row['tID']]['data'][$row['pID']]['prod'] = $row['Produkt'];
            $row_collector[$row['tID']]['data'][$row['pID']]['desc'] = $row['Beschreibung'];
            $row_collector[$row['tID']]['data'][$row['pID']]['user'] = $row['User'];
            $row_collector[$row['tID']]['data'][$row['pID']]['time'] = array();
        }
        $row_collector[$row['tID']]['data'][$row['pID']]['time'][$row['Datum']] = $row['Zeit'];
        }
        foreach ($row_collector as $taet_id => $teat) {
            $td = array();
            $td[0] = $row_collector[$taet_id]['taet'];
            foreach ($row_collector[$taet_id]['data'] as $prod_id => $prod) {
                $td[1] = $row_collector[$taet_id]['data'][$prod_id]['prod'];
                $td[2] = $row_collector[$taet_id]['data'][$prod_id]['desc'];
                for ($i = 0; $i < 7; $i++) {
                    $ts = $wochenanfang + ($i * 60 * 60 * 24);
                    if (isset($row_collector[$taet_id]['data'][$prod_id]['time'][$ts])) {
                        $td[$i+3] = $row_collector[$taet_id]['data'][$prod_id]['time'][$ts];
                    } else {
                        $td[$i+3] = ' ';
                    }
                }
                echo '  <tr>';
                [COLOR="#4169e1"]$pID = mysql_insert_id();
                echo '  <td><input type="checkbox" name="edit" value="$pID"></td>';                for ($i = 0; $i < count($td); $i++) {
                    echo '    <td>'.$td[$i].'</td>';
                }
                echo '  </tr>';
            }
        }
    } else {
        echo '  <tr><td colspan="10" style="text-align:center">Keine Einträge gefunden.</td></tr>';
    }  
    echo '</table>';
	
	echo '<br><input type="submit" value="Zurück zur Eingabe" name="btnOutputCancel">';
	[COLOR="#4169e1"]echo '<input type="submit" name="editieren" value="Editieren"><br><br>';    echo '<input type="submit" name="export" value="Exportiere MySQL Daten zu Excel File">';
forumlar.php
Code:
<?php     	
    $erstellt = date('Y-m-d H:i:s'); 
	
    if (isset($_GET['section'])) {
        $section = $_GET['section'];
    }
	
    // seiten-titel bestimmen
    if (isset($_POST['btnRegForm']) or $section == "register") {
        $site_title = "Registrieren";
        $section = "register";
    }
    if (isset($_POST['auswerten']) or $section == "output") {
        $site_title = "Ausgabe";
        $section = "output";
    }
    if (isset($_POST['auswertenadmin']) or $section == "output_admin") {
        $site_title = "Ausgabe (Admin)";
        $section = "output_admin";
    }
	if (isset($_POST['btnRegCancel'])) {
        $site_title = "Login";
        $section = "login";
    }
    if (isset($_POST['btnOutputCancel'])) {
        $site_title = "Projektzeiterfassung";
        $section = "pze";
    }

    // hiddenfields-daten speichern
    if (isset($_POST['add'])) {
		$add = $_POST['add'];
	}
    if (isset($_POST['wa'])) {
		$wochenanfang = $_POST['wa'];
	}
    if (isset($_POST['we'])) {
		$wochenende = $_POST['we'];
	}

    if (isset($_POST['prevWeek'])) {
        $wochenanfang -= 60 * 60 * 24 * 7;
        $wochenende   -= 60 * 60 * 24 * 7;
    }
    if (isset($_POST['nextWeek'])) {
        $wochenanfang += 60 * 60 * 24 * 7;
        $wochenende   += 60 * 60 * 24 * 7;
    }

    $kw = date('W', $wochenanfang);
    $jahr = date('Y', $wochenanfang);
    $monat = date('n', $wochenanfang);
    $tag = date('j', $wochenanfang);

    if (isset($_POST['addLine'])) {
		$add++;
	}
    if (isset($_POST['remLine'])) {
		$add--;
	}
    if ($add < 1) {
		$add = 1;
	}
	
    if (isset($_POST['btnLog'])) {
        $username = $_POST['username'];
        $erg = mysqli_query($mysqli, "SELECT * FROM user WHERE name='".$username."'");
        $row = mysqli_fetch_object($erg);
        $password = hash('sha512', ($_POST['password']).$salt);
        if ($row->passwort == $password) {
            $_SESSION['name'] = $username;
            $_SESSION['id'] = $row->id;
            $_SESSION['rechte'] = $row->rechte;
            $_SESSION['ip'] = $ipadresse;
            $_SESSION['last_on'] = $now[0];
            
            $user = $username;
            $userid = $row->id;
            $rechte = $row->rechte;

            $site_title = 'Projektzeiterfassung';
			$section = 'pze';
        } else {
            $protokoll .= '- Benutzername und/oder Passwort waren falsch oder nicht registriert.<br>';
        }
    }
	
    if (isset($_POST['logout'])) {
		$site_title = "Login";
        logout();
    }
	
    if (isset($_POST['btnReg'])) {
        if (isset($_POST['username'], $_POST["password"], $_POST["password2"]) and trim($_POST["username"]) != "" and trim($_POST["password"]) != "" and trim($_POST["password2"]) != "") {
            $username = $_POST['username'];
            $passwort = $_POST['password'];
            $passwort2 = $_POST['password2'];
            if ($passwort != $passwort2) {
				$protokoll .= '- die Best�tigung des Passworts stimmt nicht.<br>';
				$_POST['btnRegForm'] = true;
				unset($_POST['btnReg']);
				$site_title = "Registrieren";
            } else {
                $passwort = hash('sha512', ($passwort).$salt);
                if ($username == "M.Eggertsberger" || $username == "M. Eggertsberger") {
					$rechte = 0;
				} else {
					$rechte = 1;
				}

                $check = mysqli_query($mysqli, "SELECT * FROM user WHERE name='".$username."';");
                if (mysqli_num_rows($check)) {
					$protokoll .= '- Benutzername schon vorhanden.<br>';
					$_POST['btnRegForm'] = true;
					unset($_POST['btnReg']);
					$site_title = "Registrieren";
                } else {
                    $eintragen = mysqli_query($mysqli, "INSERT INTO user (name,  passwort, rechte) VALUES ('$username', '$passwort', '$rechte')");
                    if ($eintragen) {
                        $protokoll .= '- Benutzer <b>'.$username.'</b> wurde  erstellt.';
                    } else {
						$protokoll .= '- Fehler: Speicherung des Benutzernamens und/oder Passworts fehlgeschlagen.';
						$_POST['btnRegForm'] = true;
						unset($_POST['btnReg']);
						$site_title = "Registrieren";
                    }
                }
            }
        } else {
            $protokoll .= '- Eingabefehler. Bitte alle Felder korrekt ausfüllen.<br>';
            $_POST['btnRegForm'] = true;
            unset($_POST['btnReg']);
            $site_title = "Registrieren";
        }
    }
    
 [COLOR="#4169e1"]   if (isset($_POST['editieren'])) { // wenn Editieren-Button gedrückt wurde
    	if (isset($_POST['edit'])) { // wenn checkbox ausgewählt wurde
    		
    	}
    }	
    if (isset($_POST['confirm'])) {
        for ($a = 1; $a <= $add; $a++) {
            $stunden = array("montag".$a."", "dienstag".$a."", "mittwoch".$a."", "donnerstag".$a."", "freitag".$a."", "samstag".$a."", "sonntag".$a."");
    
            $eintragen1 = mysqli_query($mysqli, "INSERT INTO projekte (taetigkeit,  produkt, userid, beschreibung, erstellt) VALUES ('".$_POST['taetigkeit'.$a]."', '".$_POST['product'.$a]."', '$userid', '".$_POST['beschreibung'.$a]."', '$erstellt')");  
            $taetprodid = mysqli_insert_id($mysqli);
		
			for ($b = 0; $b < 7; $b++) {
				$ts = $wochenanfang + ($b * 60 * 60 * 24);
				if (isset($_POST[$ts.'_'.$a]) and $_POST[$ts.'_'.$a] != "") {
					$dauer = $_POST[$ts.'_'.$a];                              
					$eintragen2 = mysqli_query($mysqli, "INSERT INTO zeiten (userid, taetprodid, zeit, datum) VALUES ('$userid', '$taetprodid', '$dauer', '$ts')");
				}
			}
        }
	}
Meine Idee wäre, in formular.php zu überprüfen, welche Zeilen durch ihre jeweiligen checkboxen ausgewählt wurden, und dann auswerten.php mit eben diesen Zeilen neu aufzubauen, wobei der jeweilige bisherige Datensatz zum Vorbelegen der Zeilenfelder benutzt werden soll. Sofern das alles irgendwie möglich ist.

Das derzeitige Problem auf dem Weg dahin ist, dass ich für die checkboxen eine Unterscheidung bzw. Identifikation brauche, weil ja nicht zwangsläufig alle ausgewählt werden müssen. Dafür will ich jeder checkbox als value die (auto-increment) Projekt-ID aus der DB geben. Nur, ich kriege die ums Verrecken nicht ausgelesen. :huh:

Wie soll ich zu dieser ID (und die ist nach meinem Verständnis auch das absolut einzige in unserem System, das einen Datensatz eindeutig identifiziert) kommen?
Zuerst dachte ich, die müsste doch im Feld $row_collector drinnenstecken und habe sie da rauszulesen versucht, erfolglos. Meine nächste Idee wäre dann mysqli_insert_id() gewesen, wie's noch im Code zu sehen ist, liefert aber nur 0er ...
 
Das hier geht schonmal nicht:
echo ' <td><input type="checkbox" name="edit" value="$pID"></td>';

Grund: in Einfachen Anführungszeichen (') kannst du nicht einfach Variablen verwenden, das geht nur in Doppelten. Alternativ mit Concat-Operator (.) arbeiten:
PHP:
echo '  <td><input type="checkbox" name="edit" value="'.$pID.'"></td>';

Sofern das alles irgendwie möglich ist.
Ist alles möglich.

mysql_insert_id() tut NICHT, was du denkst, dass es täte. Lies nochmal die Dokumentation dazu.

Steckt die Produkt-ID nicht einfach in $prod_id?

 
a) Darf als Schlammpigkeitsfehler eingestuft werden. Hätte ich gewusst, aber eben übersehen.

b) Es geht um die Projekt-ID, nicht die Produkt-ID. Wobei ich mir ja immer noch einbilde, dass die in $row_collector drinnensteckt?! Was hätte denn dort sonst den Feldindex "pID" (im Gegensatz zu "prod_id")? Nur, wie komme ich dazu?
 
b) Hoppla, sorry. Da war ich wirr. Der row_collector ist Teufelswerk. Ein vierdimensionaler Array ist (wenn man nicht Raum-Zeit-Koordinaten erfasst ;-) ) eine verwirrende und nicht-empfehlenswerte Sache. Sinnvoll wäre gewesen, dass mit PDOs und objektorientiert zu machen. Hilft dir momentan natürlich nicht weiter. Für mich ist es heute zu spät, noch sinnvolle Aussagen dazu zu treffen, ich schaus mir morgen mal an. :-D
 
Zurück