Beiträge von cottton

    Da fehlen " und '.

    $neu[melden] sollte sicherlich $neu['melden'] sein.

    Teste mal deine Scripte mit allen Errorausgaben:

    PHP
    // an den anfang des scripts oder am besten in das eingangsscript (index.php)
    error_reporting(E_ALL);
    ini_set('display_errors', 1);

    Da werden einige Warnings und Notices fliegen.

    Und sowas hier:

    PHP
    "UPDATE `bilderdatenbank` SET $code WHERE `id` = $neu[id]"

    kann böse enden (SQL injection).

    Ich weiß, dass Du die Daten hier selbst setzt.

    Aber bei einem Update, oder wenn Du mal einen Codeblock zum wiederverwenden kopierst, ...

    kann es schnell passieren, dass Du auf einmal Unsichere Daten in die Query schreibst.

    Wie dann:

    Die id per platzhalter dürfte keine große Sache sein. (Empfehle btw :platzhalter statt ? )

    Die Column $code allerdings musst Du in die Query schreiben (Platzhalter sind nur bei Values erlaubt)

    aber in solchen Fällen nutzt man Whitelists

    PHP
    $whiteListCode = ['abc', 'def', '...'];
    if (in_array($code, $whiteListCode, true)) {
        $sql = "UPDATE `bilderdatenbank` SET `{$code}` WHERE `id` = :id";
        // ...
    } else {
        // ERROR, unerlaubter wert
        // die oder exit oder throw new Exception ...
        die("nope");
    }

    oder du rennst mit nem Regex drüber und lässt nur bestimmte Zeichen zu:

    PHP
    // bad input:
    $code  = "id` = `id`; DROP TABLE admin; -- .";
    
    // letter number underscore only
    $cleanColumnName = preg_replace("/[^\w]/", '', (string)$code);
    
    $sql = "UPDATE `bilderdatenbank` SET `{$cleanColumnName}` WHERE `id` = :id";
    
    var_dump($sql);
    // UPDATE `bilderdatenbank` SET `ididDROPTABLEadmin` WHERE `id` = :id

    Das letzte Script: die Datei Test2.php

    Du nutzt FETCH_OBJ, bekommst also ein Object (per $object->property angesprochen).

    Du sprichst es allerdings als Array an: echo $row['image'];

    Außerdem fehlt ein ; in Zeile 8 :)

    Probier mal das hier:

    Bitte immer Daten (egal aus welcher Quelle - selbst, wenn es aus der eigenen db kommt) per PLatzhalter in die SQL query schreiben.

    Und die anderen Scripte nicht vergessen zu updaten, um Platzhalter zu verwenden.


    EDIT: btw - was ist in der db.images das Feld `image` für ein Typ?

    -- hab den Artikel gefunden - hat sich erledig. Sicherlich Type BLOB.

    Nur noch zur Ergänzung der Prepared Statements -Geschichte:

    wie gesagt alle anderen Scripte updaten, und immer Platzhalter zu nutzen.

    Ab dann kannst Du nämlich auch addslashes weglassen.

    PHP
    Aus// Vorbereiten für den Upload in DB
    $data = addslashes(file_get_contents($image));

    wird dann

    PHP
    // Bilddaten lesen
    $data = file_get_contents($image);

    Nix zu korrigieren.

    Evtl was hinzuzufügen:

    echo "Dies ist ein {$foo}"; // Ausgabe: Dies ist ein Test

    Hier sind die Klammern kein muss. Beim nächsten Bsp aber doch:

    PHP
    $array = [
        'foo' => 'Test'
    ];
    echo "Dies ist ein {$array['foo']}"; // Ausgabe: Dies ist ein Test

    Manchmal kann es übersichtlicher sein, wenn man "" benutzt, statt viele Verkettungen.

    Oder man nutzt sprintf()

    PHP
    $var = 'Test';
    $format 'Dies ist ein %s'; // %s ist platzhalter für einen string (s)
    echo sprintf($format, $var); // Ausgabe: Dies ist ein Test

    Zeilenumbruch

    "\r\n" bzw \n (new line - neue Zeile; reset - auf der momentanen zeile an den Anfang)

    oder PHP_EOL(EOL ^= End Of Line - neue Zeile)

    PHP
    echo 'Hier kann ich kein \r\n nutzen. Also verkette ich den Zeilenumbruch: ' . "\r\n";
    echo 'Hier kann ich kein \r\n nutzen. Also verkette ich den Zeilenumbruch: ' . PHP_EOL;
    echo "Hier kann ich \r\n nutzen. PHP_EOL Muss ich aber weiterhin verketten, da es als Konstante nicht inline genutzt werden kann" . PHP_EOL;

    Ziel: eine MySql Datenbanktabelle erweitern, um zu sehen, wann eine Zeile erstellt wurde, oder geändert wurde.

    Verwendete Techniken: MySql

    Schwierigkeitsgrad: für Anfänger geeignet, Grundkenntnisse über die Funktionsweisen von SQL vorausgesetzt

    Wichtig: IMMER Daten sichern, bevor man an Produktivdaten rangeht!

    Angenommen, Du hast eine Tabelle `user` erstellt, und Du möchest abfragen können, wann ein Benutzer erstellt bzw geändert wurde.

    Dann ist der einfachste weg das hinzufügen zweier Felder:

    `created_at` und `updated_at`.

    Das Ganze wird ein "Einmalaufwand". Die beiden Felder werden hinzugefügt, und Auslöser (Trigger) erledigen den Rest.

    SQL
    ALTER TABLE `user`
    ADD COLUMN `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'datetime row inserted',
    ADD COLUMN `updated_at` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP COMMENT 'datetime row updated';

    Wichtig: bei einem INSERT INTO oder UPDATE sollten keine Werte für die Felder `created_at` und `updated_at` mitgegeben werden.

    Das sollte komplett dem MySql-Server überlassen werden.

    Was passiert hier:

    Bei einer neuen Zeile (INSERT INTO) wird der Wert für das Feld `created_at` mit dem momentanen Zeitstempel versehen.

    Dieser Zeitstempel wird nie wieder geändert. Somit ist klar, wann genau diese Zeile eingefügt wurde.

    Beim ändern einer Zeile (UPDATE) wird der Wert für das Feld `updated_at` mit dem momentanen Zeitstempel versehen.

    Das passiert immer nur dann, wenn sich auch wirklich Daten geändert haben.


    Am Beispiel: Testtabelle erstellen und Beispieldaten einfügen

    (Die Tabelle wird hier `user_test` genannt, um nicht evtl vorhandene Tabellen zu "versauen")

    Erstellen der Tabelle

    SQL
    CREATE TABLE `user_test` (
        `id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
        `name` VARCHAR(32) NOT NULL,
        `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
        `updated_at` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP
    );

    Testdaten einfügen

    SQL
    INSERT INTO `user_test` SET `name` = 'hans';
    INSERT INTO `user_test` SET `name` = 'wurst';

    Testausgabe

    SQL
    SELECT * FROM `user_test`;

    +----+-------+---------------------+---------------------+

    | id | name  | created_at          | updated_at          |

    +----+-------+---------------------+---------------------+

    |  1 | hans  | 2017-06-06 17:03:22 | 0000-00-00 00:00:00 |

    |  2 | wurst | 2017-06-06 17:03:25 | 0000-00-00 00:00:00 |

    +----+-------+---------------------+---------------------+

    Der MySql-Server hat sich hier also wie gewollt um die Werte der Spalten `created_at` und `updated_at` gekümmert.

    Jetzt wollen wir wissen, was passiert, wenn eine Zeile geändert wird:

    SQL
    UPDATE `user_test` SET `name` = 'peter' where `id` = 2;

    Testausgabe

    SQL
    SELECT * FROM `user_test`;

    +----+-------+---------------------+---------------------+

    | id | name  | created_at          | updated_at          |

    +----+-------+---------------------+---------------------+

    |  1 | hans  | 2017-06-06 17:03:22 | 0000-00-00 00:00:00 |

    |  2 | peter | 2017-06-06 17:03:25 | 2017-06-06 17:09:50 |

    +----+-------+---------------------+---------------------+

    Wir sehen also, dass sich ser MySql-Server um das Feld `updated_at` gekümmert hat.

    Jetzt noch ein Bsp, bei dem wir eigtl gar keine Änderungen verursachen

    SQL
    UPDATE `user_test` SET `name` = 'peter' where `id` = 2;

    Info: hier sollte sich nichts ändern, da wir ja den Namen zuvor auf genau diesen Wert ('peter') gesetzt haben.

    Testausgabe

    SQL
    SELECT * FROM `user_test`;

    +----+-------+---------------------+---------------------+

    | id | name  | created_at          | updated_at          |

    +----+-------+---------------------+---------------------+

    |  1 | hans  | 2017-06-06 17:03:22 | 0000-00-00 00:00:00 |

    |  2 | peter | 2017-06-06 17:03:25 | 2017-06-06 17:09:50 |

    +----+-------+---------------------+---------------------+

    Keine Änderung. Das Feld `updated_at` behält seinen Wert von '2017-06-06 17:09:50' beim Benutzer mit `id` 2.


    Das wars.

    Wäre nur noch zu erwähnen, dass man den DEFAULT Wert bei `updated_at` statt '0000-00-00 00:00:00'

    auf CURRENT_TIMESTAMP setzen kann.

    Warum:

    '0000-00-00 00:00:00' ist eigtl kein gültiger Zeitstempel. Manche stört es, manche nicht.

    Ändert man den DEFALUT Wert von

    `updated_at` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00' ON UPDATE CURRENT_TIMESTAMP

    auf

    `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

    dann bekommt man bei einem INSERT INTO z.B.

    +----+-------+---------------------+---------------------+

    | id | name  | created_at          | updated_at          |

    +----+-------+---------------------+---------------------+

    |  1 | hans  | 2017-06-06 17:19:19 | 2017-06-06 17:19:19 |

    |  2 | wurst | 2017-06-06 17:19:22 | 2017-06-06 17:19:22 |

    +----+-------+---------------------+---------------------+

    Die Felder `created_at` und `updated_at` sind genau gleich.

    Möchte man also wissen, ob eine Zeile nie geändert wurde, dann fragt man ab, ob `created_at` und `updated_at` gleich sind:

    SELECT * FROM `user_test` WHERE `created_at` = `updated_at`;


    Hier noch einmal die CREATE TABLE Variante ohne '0000-00-00 00:00:00':

    Code
    CREATE TABLE `user_test` (
        `id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
        `name` VARCHAR(32) NOT NULL,
        `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
        `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
    );

    Falls eine schon bestehende Tabelle erweitert werden soll:

    Code
    ALTER TABLE `table_name` -- add your table name
    ADD COLUMN `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    ADD COLUMN `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;

    Bei bereits bestehenden Daten fehlen nun natürlich die richtigen Zeitwerte.

    Das könnte man hinnehmen - alle bereits vorhandenen Zeilen bekämen den jetzigen Zeitstempel.

    Oder man lässt deren `created_at` und `updated_at` Felder auf den Wert '0000-00-00 00:00:00' setzen.

    Dazu benötigen wir mehrere Schritte:

    Ausgangs Tabelle

    Code
    CREATE TABLE `user_test` (
        `id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
        `name` VARCHAR(32) NOT NULL
    );

    Testausgabe

    SQL
    SELECT * FROM `user_test`;

    +----+-------+

    | id | name  |

    +----+-------+

    |  1 | hans  |

    |  2 | wurst |

    +----+-------+

    Upgrade - dabei setzen wir auf allen vorhandenen Zeilen den (vorübergehenden) DEFAULT Wert auf NULL 

    Code
    ALTER TABLE `user_test`
    ADD COLUMN `created_at` DATETIME DEFAULT NULL,
    ADD COLUMN `updated_at` DATETIME DEFAULT NULL;

    Testausgabe

    SQL
    SELECT * FROM `user_test`;

    +----+-------+------------+------------+

    | id | name  | created_at | updated_at |

    +----+-------+------------+------------+

    |  1 | hans  | NULL       | NULL       |

    |  2 | wurst | NULL       | NULL       |

    +----+-------+------------+------------+

    Jetzt ändern wir die neuen Felder, um die Werte vom MySql-Server befüllen zu lassen

    Code
    ALTER TABLE `user_test`
    MODIFY COLUMN `created_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    MODIFY COLUMN `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;

    Testausgabe

    SQL
    SELECT * FROM `user_test`;

    +----+-------+---------------------+---------------------+

    | id | name  | created_at          | updated_at          |

    +----+-------+---------------------+---------------------+

    |  1 | hans  | 0000-00-00 00:00:00 | 0000-00-00 00:00:00 |

    |  2 | wurst | 0000-00-00 00:00:00 | 0000-00-00 00:00:00 |

    +----+-------+---------------------+---------------------+

    Alle zuvor vorhandenen Zeilen bekommen nun also den Wert '0000-00-00 00:00:00'.

    Es gitb also keinen `created_at` Wert für diese Einträge (woher auch - da gab es die Erweiterung ja noch nicht).

    Aber alle jetzt eingefügten bzw geänderten Zeilen bekommen ihre korrekten Zeitstempel:

    SQL
    UPDATE `user_test` SET `name` = 'Hans' where `id` = 1; -- 'Hans' instead of 'hans'

    Testausgabe

    SELECT * FROM `user_test`;

    +----+-------+---------------------+---------------------+

    | id | name  | created_at          | updated_at          |

    +----+-------+---------------------+---------------------+

    |  1 | Hans  | 0000-00-00 00:00:00 | 2017-06-06 17:46:39 |

    |  2 | wurst | 0000-00-00 00:00:00 | 0000-00-00 00:00:00 |

    +----+-------+---------------------+---------------------+

    Möchte man hier wissen, ob eine Zeile geändert wurde, dann fragt man ab,

    ob `created_at` und `updated_at` gleich sind und `updated_at` größer als '0000-00-00 00:00:00':

    SELECT * FROM `user_test` WHERE `created_at` = `updated_at` and `updated_at` > 0;

    Es gibt sicherlich noch andere Möglichkeiten, um bereits vorhandene Daten zu "kennzeichen". Ideen einfach mal posten.

    Zitat

    Sicherheit ist in dieser Uebung kein Thema

    Bitte nicht. Auch wenn Du nur in einer Testumgebung schreibst - gewöhne Dir keine Sicherheitslücken an.

    SQL-injection möglich! Keine Daten direkt in die SQL-Query schreiben.

    Du nutzt mysqli_, daher ist das hier für Dich interessant: http://php.net/manual/de/mysqli.prepare.php

    (bei Fragen einfach fragen)

    Auch keine Daten direkt in die Ausgabe aufnehmen/anhängen.

    Bsp böse

    echo "Dein Name ist " . $_POST['name'];

    Auch keine db-Daten:

    echo "Dein Name ist " . $dbResult'name'];

    Warum: in der Variable könnte zB Javascribt stecken. Teste mal einen Namen - ändere ihn in

    <script>alert(1)</script>

    Der browser wird eine Alertbox ausgeben (Bei einem Angriff würde da natürlich viel schlimmeres passieren).

    Wie verhinderst Du das:

    echo "Dein Name ist " . htmlspecialchars($_POST['name']);

    bzw

    echo "Dein Name ist " . htmlspecialchars($dbResult'name']);

    Info: kurze Namen sind schnell geschrieben (zB "nn"), aber schlecht für die Lesbarkeit. Es ist für alle einfacher, wenn Du namen ausschreibst.

    zB statt "nn" "nach_name" (oder noch besser gleich alles in Englisch "last_name").

    Keine Ahnung woher der Code stammt, aber ich würde ihn nicht online nutzen.

    Von undefined index bis hin zur garantierten SQL-injection alles dabei.

    (Den Fehler, den Du beschrieben hast, kann ich nicht finden. Aber das sollte die geringste Sorge sein.)

    Siehe Kommentare:

    Empfehle auch PHP password_hash, password_verify, ... (wenn PHP denn verwendet wird).
    Aber zum Fehler:

    PASSWORD ist eine Mysql Funktion.
    Und die erstellt einen Hash.
    Beim SELECT musst Du also den Hash vergleichen.

    Bsp:

    BTW: immer ` verwenden. Warum? Weil zB ein Feld names order in einer Query als Sclüsselwort für zB ORDER BY gewertet wird.

    EDIT:
    Wenn Du zB PHP nutzt, dann nutze PHP um die Hashes zu erstellen.
    Sonst sendest Du dauernd das Klartextpasswort (per Query) an den Mysql Server. Das muss nicht sein. Je mehr das unterwegs ist, desto mehr Chancen gibt es, dass es irgendwo "auftaucht" (error logs ect !).

    var lflaeche = $a_lagerflaeche;
    Kann ja nicht gehen.

    probier mal das:

    Das kommt daher, dass die JS (jQuery) Funktion nicht gestarted/angestoßen wird.
    Die wird ja nur per "onchange" gestartet.

    Was Du machen kannst:
    beim Laden der Seite weißt Du ja, ob ein Artikel angelegt, oder bearbeitet wird.
    Wenn bearbeiten (EDIT), dann startes Du die JS (jQuery) Funktion manuell 1 mal.

    Bsp:

    Vorweg: image resize ist tricky. Wenn Du was fertiges wilst, dann guck mal hier: http://stackoverflow.com/a/23772147/3411766
    Das Bild wird auf die $maxsize zugeschnitten, wobei es egal ist, ob Breite oder Höhe.
    Wenn das Bild Hochkannt ist, dann ist die max Höhe eben $maxsize. Sonst die max Breite.

    Es wird immer ein png (imagepng) erstellt. Denke aber, wenn man statt imagepng() zB imagejpeg() nutzt, sollte es auch funktionieren.

    Das Bild wird durch imagepng() in den ielordner gepseichert.
    Das Original (zB PHP tmp) bleibt wo es ist. Nach Scriptende wird der tmp Ordner automatisch geleert (wenn nicht in php.ini oder ini_set() geändert).

    Lief bei mir ohne Probleme.

    Kann bei Dir auf Anhieb nix falsches sehen. Hab aber leider auch gerade keine Zeit es zu testen.
    Bekommst Du denn Fehlermeldungen?
    nutze mal:

    PHP
    ini_set('display_errors', -1);
    error_reporting(E_ALL | E_STRICT);

    Das einfachste wäre meiner Meinung nach eine $_SESSION, in der Du eine optionale URL hinterlegst.

    In dienstplan.php:

    PHP
    if(isUserLoggedIn($mysqli) === FALSE) {
        // ich gehe davon aus, dass session_start() schon aufgerufen wurde
        $_SESSION['page_after_login'] = 'login.php'; // order "page_to_redirect" oder was immer du möchstest
    
    
    
    
        header('Location: login.php');
        exit;
    }

    in login, bei erfolgreichem Login:

    Naja, kommt drauf an, in wie weit Du Dich mit Klassen (OOP - Objekt orientierte Programmierung) auskennst.
    Um Exceptions zu verstehen, brauchst Du Grundwisen in OOP.
    Um Exceptions gut einsetzen zu können, brauchst Du fundiertes OOP Wissen.

    Hier mal ein Bsp:


    Eine Exception ist ein Objekt. Es ist throwable.
    Mit throw wird die new Exception geworfen.
    Das heißt, dass der Ablauf des Scripts an der Stelle abgebrochen wird.


    Hier ein Bsp über 2 Dateien:

    Um den Ablauf dennoch steuern zu können nutzt man try/catch

    Man kann (und später wird) auch eigene Exceptions nutzen.
    Dabei erweitert man einfach die Exception: