Beiträge von cottton

    Kann nicht genau folgen.

    Zitat

    00:00 – 00:30 123

    Soll das angeben, wie viele User zu der Zeit angemeldet waren?

    Also 123 User in der halben Stunde?

    ---

    Du kannst GROUP BY nutzen. Zwar nicht mit halben Stunden (evtl mit nem "Trick"),

    aber ganz einfach über das Format:

    SQL
    1. GROUP BY DATE_FORMAT(`created_at`, '%Y-%m-%d %H')


    Example:

    SQL
    1. -- SET @date_format := '%Y-%m-%d'; -- Get grouped counts by hour.
    2. SET @date_format := '%Y-%m-%d %H'; -- Get grouped counts by hour.
    3. -- SET @date_format := '%Y-%m-%d %H:%i'; -- Get grouped counts by min.
    4. SELECT
    5. -- select the datetime by format
    6. DATE_FORMAT(`created_at`, @date_format) AS `created_at`,
    7. -- count the amount for that formatted datetime group
    8. COUNT(`user_id`) AS `count`
    9. FROM `user_login_log`
    10. GROUP BY DATE_FORMAT(`created_at`, @date_format);


    Test: http://sqlfiddle.com/#!9/aac84a/4

    Nein, "sollte" ist auf jeden Fall falsch und die Benennung nach Einzahl oder Mehrzahl entweder

    a) eine Glaubensfrage, oder

    b) ein firmeninterner Regelungsgegenstand , oder

    c) eine Geschmacksfrage.

    Ja klar, kann man sich streiten, muss man aber nicht.

    Das gibts im Netz genug.

    Bei mir z. B. werden Tabellen grundsaetzlich nach der Mehrzahl benannt, sofern dies moeglich ist. Die Begründung ist für mich auch logisch: Eine Tabelle, die viele XYZ verwalten soll, heisst dann eben xyzs (Mehrzahl) und nicht xyz (Einzahl). So kann man auch leicht zwischen einer Gruppe - z. B. Array $xyzs - und einem einzelnen Objekt - z. B. String $xyz - unterscheiden.

    Naja, das machst Du so lange, wie Du darfst. Also bis Dir dein Chef, oder Kunde was anderes sagt.


    Ich werd mich hier bestimmt nicht deswegen streiten :)

    Aber Dein Argument, dass es immer mehrere (rows) in einer Tabelle gibt, ist mMn keins. Alle Tabellen haben mehrere (rows). Und jetzt kannst Du das wieder gegen mich verwenden :D


    Dein Argument, dass mann zwischen einer Gruppe und einem Object unterscheiden kann, ist auch komisch (nur meine Meinung).

    Denn Das entscheidet doch dann der Code - also die Variablenbenennung.


    BTW: Code und Objects -

    wenn Du mit Models zu tun hast, dann wird es schnell seltsam:

    manche Models sind clever geschrieben, und erwarten, dass der Tabellenname strtolower(classname) heißt.

    Also Class UserLogin {} dann als user_login.

    Die musst Du dann immer explizit angeben.


    Du musst das Naming dann auch durch alle Ebenen durchziehen (oder ständig ändern, aber dann ist user mal user und auf einmal users oO?).

    Bsp:


    Auch ja - zwecks "user_login" - Thema Detailtabellen (oder halt Tabellen in Bezug auf andere):

    Code
    1. Meiner Meinung nach "positiv" Bsp:
    2. tbl user
    3. tbl user_login
    4. tbl user_login_attempt
    5. Meiner Meinung nach "negativ" Bsp:
    6. tbl users
    7. tbl users_log_ins
    8. tbl users_log_ins_attempts

    Ich will Dich nicht unbedingt Überzeugen. Aber ich finde, das sind schon gute Argumente =)

    Hat sich erledigt.

    Ok.


    vs_rooms

    Warum? Ich meine, warum kann man denn nicht einfach richtige Namen vergeben :)


    BTW: Mehrzahl ist ungünstig.

    Beispiel:

    SQL
    1. SELECT *
    2. FROM rooms
    3. JOIN floors on rooms.id = floors.rooms_id
    4. WHERE rooms.name = '...'
    5. ;

    Liest sich falsch, oder?

    Eine Tabelle sollte in der Einzahl benannt werden:

    SQL
    1. SELECT *
    2. FROM room
    3. JOIN floor on room.id = floor.room_id
    4. WHERE room.name = '...'
    5. ;

    Also zB "user" statt "users", "car" statt "cars", ... .


    Bei Spalten ist das was anderes.

    In deinem Beispiel hast Du seats. Ich gehe davon aus, dass hier die Anzahl stehen wird. Oder doch nur, ob es Sitze gibt? :D

    Würde eher seat_count empfehlen.

    Du siehst sofort, worum es geht.



    Und ... rooms.room - was ist das? :D

    Code
    1. [
    2. 'id' => 1,
    3. 'room' => '', // ?
    4. 'name' => 'Living Room',
    5. 'seats' => 'Yes', // :D
    6. ]


    :)

    Es ist ja offensichtlich, dass mit $x++ irgendetwas mit dieser Variable passiert. Da hätte man mit einem simplen


    Code
    echo $x;

    in der Schleife die Sache heraus finden können.

    Dann hätte er gewusst, dass sich die Zahl erhöht.

    Aber warum?

    Ich finde es besser, wenn man wei, wie etwas funktioniert. (In dem Fall ++$i, $i++)

    Aber wie gesagt - der ein Link zur offiziellen docu reciht da ja.

    Bitte Grundlagen lernen, denn hier hat niemand Lust dir die Doku "vorzulesen"

    Naja, ich erinnere mich, als ich angefangen hab.

    Wie sucht man denn als Anfänger dannach?

    Du kennst die Begriffe und die (für inzwischen uns logische) Web-Suche nicht.


    Ich weiß noch, wie ich nach "!" (not) suchen wollte :D

    Dann lieber gleich im Forum fragen :)


    EDIT: aber klar, ein Link zur PHP Beschreibung raicht dann als Antwort.

    Manmal machen Fehler aber keinen Sinn. Als ob 1 + 1 nicht mehr 2 ist.

    Dann ist es wirklich besser Pause oder Feierabend zu machen.


    Manchmal hift es auch schon im Forum eine Frage zu stellen.

    Schon beim Schreiben und Überlegen, wie man das Problem erklärt, fällt einem manchmal der Fehler auf :)


    dsaZeus Warum erstellst Du denn für jeden Benutzer eine eigene Datei (1.php, 2.php, ...)?

    Nur als Hinweis:

    Column als TIMESTAMP.

    see DATE, DATETIME oder TIMESTAMP?


    Die database timezone beachten.

    see mysql timezone ändern

    sehr ausführlich (muss man nicht alles wissen): https://stackoverflow.com/a/19075291/3411766


    Format immer: Y-m-d H:i:s (Bsp: 2020-05-18 03:14:59)


    PHP Datetime:

    $datetime = new \Datetime('2020-05-18 03:14:59', new \DateTimeZone('UTC'));


    PHP relative datetime: https://www.php.net/manual/de/datetime.formats.relative.php

    $datetime = new \Datetime('now', new \DateTimeZone('UTC'));

    $datetime = new \Datetime('this day noon', new \DateTimeZone('UTC'));

    $datetime = new \Datetime('first day of this month', new \DateTimeZone('UTC'));


    PHP modify:

    $datetime->modify('+1 day');


    Wenn Du die timezone in der db in UTC hast, kannst Du die dann per PHP in zB "Europe/Berlin" ändern

    PHP datetime timezone ändern: https://www.php.net/manual/de/datetime.settimezone.php


    oder per MySQL direkt in der query:

    MySQL: SELECT id, name, ... , CONVERT_TZ(my_datetime_column,'UTC','Europe/Berlin') FROM .... WHERE ...;

    Also sollte ich lieber immer htmlspecialchars benutzen?

    Immer dann, wenn Du etwas im Browser ausgibst.

    Selbst, wenn die Daten aus Deiner eigenen db, config, file, ... kommt.

    Wenn Du ein script in CLI (command line interface aka console) ausgibts, dann nicht, denn in der CLI with kein Javascript ausgeführt.


    Selbst ausprobieren macht Spass und man lern es besser: spiel einfach bisschen mit (zB) den username rum. Lass htmlspecialchars weg, und nutze irgendwelche Zeichen, die Dir einfallen. zB <, >, ", ', ....

    Schon ein username >hans< würde HTML "brechen".

    Verstehe das Problem nicht (bin gerade erst aufgewacht)

    aber bitte alle Werte mit htmlspecialchars maskieren.

    Bsp:

    Statt <?php echo $value['username'] ?>

    Bitte <?php echo htmlspecialchars($value['username']) ?>


    Warum: XSS (einfach mal im Netz suchen).

    Kannst Du selbst testen. Speichere mal einen username mit <script>alert(1)</script>Hans

    und lass Dir den User ausgeben.

    Ich fang jetzt nicht wieder mit Prepared Statements an. Das solltest Du nun kennen.

    Aber

    SELECT * FROM login WHERE username = '$username'

    Wenn im Moment, und|order in der Zukunft ein Fehler passiert,

    bei dem der username nicht (mehr) unique ist,

    dann kannst Du mehr als 1 user laden.


    Der code lässt dann auch noch zu, dass Du solange läufst, bis Du den letzten möglichen user eingeloggt hast.


    Pseudo code Vorschlag:

    Code
    1. result = SELECT * FROM login WHERE username = :username LIMIT 1;
    2. if result.count === 1
    3. row = result->fetchOne() // you expect one, so get one
    4. if password_verify(password, row.password)
    5. // all fine
    6. elseif result.count > 1
    7. // error handling for unexpected multiple users on same username
    8. else
    9. // error handling for user not found by username

    Vieleicht sollte man solche Antworten das ( ich falsch liege ) dann anders Formulieren weil falsch scheint meine ausage ja nicht gewesen zu sein.

    Ja, ich geb zu, dass war wohl too much von mir, sorry.

    Werde das in dem Post editieren|markieren|notieren.


    timtim

    Ich hätte mir gedacht dass ich Password_verify() im Anschluss an die SQL-Abfrage (hier Zeile-Nr. 20) schreiben müsste?

    "WHERE username=? AND password=?"

    ^ das funktioniert nicht.


    Du bekommst das plain text (klartext) Passwort.

    Du hast (in Deiner db) den hash des Passwortes.


    Du lädsts den User bei username oder email.

    Findest Du ihn, dann nimmst Du den zugehörigen hash und nutzt password_verify() um den das Passwort mit dem Hash zu vergleichen.

    Du bekommst:

    username

    password


    Du suchst in der db nach dem username, der unique sein muss. Oder Du geht nach email, die ja auch unique sein muss.

    Findest Du den User, dann prüfst Du das password gegeb den hash.


    Pseudo code:

    Code
    1. user = "select ... from user where username = :username"
    2. if ! user
    3. // fehler - user nicht gefunden
    4. else
    5. // check input vs db users hashed pw
    6. if password_verify(password, user.hash)
    7. // ok
    8. else
    9. // nicht ok

    Siehe auch Loginpasswort richtig hashen - password_hash() & password_verify()

    Dein Beispiel ist mir schon bewusst, aber da sind wieder injections möglich, weil das Prepare das nicht abfängt, deswegen brauchst du ja eine WhiteList und da kommt das escapen bzw. anderweitige validieren ins spiel, was du ja machst. *_real_escape_string wäre zum prüfen ebenfalls möglicht.

    Könnte man sich streiten. Ich vertraue da einer whitelist (viel) mehr.



    mein "da draußen" läuft über skalierbare Cloud Anwendungen,

    Naja, das wird dann wohl doch ein bissl zu viel für das Forum, oder?



    Hier nur der bezug auf deine Aussage Sicherheit > "speed" Ja, aber nicht über PreparedStatements weil der Sicherheitsaspekt zu den Prepared Statements kleiner ist als der Overhead.

    Für Anfänger, die hier im Forum lernen? Ach komm.

    Das bischen overhead ... wenn überhaupt.

    Ich hab das nicht getestet, aber die real escape Funktion nutzt das db handle,

    also wird die auch beim MySQL Server anfragen. Und das per call (value).


    Prepared Statements schützen nur vor first-order injections nicht second-order

    Bin mir fast ganz sicher, das die Aussage falsch ist.

    Wenn ich second order injection richtig verstanden habe, dann kann*1 beim Verwenden der Daten aus der db

    in einer Query die (2nd order) injection möglich werden.

    *1 Aber dann eben nicht. Denn da nutzten wir doch auch wieder Prepared Statements. :)

    Wer sowas schreibt ... WHERE foo = {$row['foo']} ... gehört ... belehrt :D


    Und genau das is es btw, was ich immer sage: alle Daten sind böse. Selbst die in der eigenen db.

    Und daher gilt doch, was ich am Anfang sagte: die Daten gehen so wie sie sind in die db.


    Lange muss nicht richtig heißen. Pauschal aussagen bekommen pauschal antworten.

    Hehe, you got me there. Naja, Wochen, Momante. Weiß nicht mehr.

    Aber ich bin keiner, der code kopiert. Ich will (so weit möglich) wissen wie und warum etwas funktioniert.

    Gehört auch bissl Glück dazu. Einfach weiter machen!

    Achtung - Lebensgeschichte :D

    Ich komme vom Bau. Hatte dort keine Zukunft. Langzeitarbeitsloser ... .

    Wollte was anderes machen.

    Hab PHP als Hobby gelernt (kein OOP).

    Hab mich beworben. Keine Antwort.

    Auf Nachfrage: OOP muss schon sein.

    OOP gelernt.

    Immernoch kein Glück.

    Jeden "Mist" mitgemacht:

    - Fernstudium bei ILS (ich halte mich mit meiner Meinung dazu mal zurück)

    - Selbststudium

    - ...

    - bis hin zum Bewerbungstraining, wo die mich gefragt haben, was ich eigtl. hier will :D

    aber die waren echt nett =)


    Aber jetzt kommts: beim Bewerbungstraining sollten wir uns um ein Praktikum bemühen.

    Und ich hab Nummern angrufen, bei denen ich dachte "da kommt eh nichts".

    Und BAM - Rückruf von meinem (seit 2016) neuen Boss =)


    Und ab dann, wenn Du drin bist, lernst Du erst richtig.


    Also einfach alles mitnehmen. Auch wenn es total sinnlos scheint.

    Man weiß nie ... :)

    wie ich z.B. vom User sowohl die abzufragenden Felder + dynamische wehre Bedingungen in ein Prepaid Statement setze

    Perfekt: hab das gerade geposted.

    Prepared Statements (PDO) copy|paste Beispiele.



    der overhead von PreparedStatements zu Verschwendung von Ressourcen führt

    Glaub mit - da draußen ist das das geringste Problem.

    Sicherheit > "speed".


    wirkt auf mich auch eher als wolle man sich nicht mit der sache beschäftigen.

    Ich hab mich lange damit beschäftigt.

    Das Problem ist, dass man das nicht so einfach runterschreiben kann.

    Es würde einfach so lang werden, dass es keiner liest.

    Aber es gibt vieles im Netz dazu. Was ich hier versucht ist, den Leuten klar zu machen, dass es "da was gibt" - Problem und Lösung.

    Generell: auf SQL-Injections hinweisen. Alle Daten sind böse.

    Im Detai: in Richtung Prepared Statements lenken, damit die Leute sich damit beschäftigen.


    Und ebenfalls verschleiert es für Anfänger die eigentliche Problematik: die Wichtigkeit der Validierung der eingaben

    Du prüftst, ob die email zu lang ist.

    Du prüfst, ob der nickname legal, nicht leer, und nicht schon vergeben ist.

    ...

    Aber Du kannst nicht alle Injections der Welt kennen.

    Das, also das Thema Sicherheit, überlassen wir dem MySQL Server (bei richtiger Bediehnung).

    Warum Prepared Statements und was ist das: Sichere Programmierung mit PHP


    Beispiele, die (hoffentlich) für sich selbst sprechen,

    und eigtl. auf jedem System laufen sollten:


    Kommentare nur in englisch.

    Naja, ist doch richtig, was er da sagt.

    basically mysqli_real_escape_string will take out the junk in the user input according to a defined character set while prepared statements will make sure if there be any junk in the user input it will be only interpreted as you want it to be interpreted which is usually as user junk :)

    Grob gesagt: mysqli_real_escape_string den "Müll" zu entfernen (maskieren).

    Prepared statements ist der "Müll" egal, da eh nichts passieren kann, da (by default) als string in das Template eingefügt.


    Ich sehe da jetzt kein Gegenargument oder irgandwas, da meine Aussage jetzt als falsch dastehen lässt.