Beiträge von tk1234

    okay und warum empfiehlst du dies so zu tun?


    Ich sehe da aktuell noch keinen Grund dies so zu tun. Selbst große Shopsysteme haben all ihre Scripte innerhalb des Root-Verzeichnisses.

    Wenn Dateien nicht per http erreichbar sind, können sich auch nicht durch einen Konfigurationsfehler ausgeliefert werden. Dass der PHP-Interpreter mal nicht funktioniert (und damit PHP-Dateien im Klartext ausgeliefert werden) ist natürlich extrem unwahrscheinlich aber bei anderen Dateien kann es schon mal vorkommen dass man mal vergisst ein Verzeichnis zu sperren. Bei größeren Systemen schauen idR viele Leute drüber und Fehlkonfigurationen fallen da normal auf - bei selbst geschriebenen Scripten ist das nicht so. Zudem sind die großen Systeme meist über lange Zeit gewachsen und können nicht mal eben einfach komplett umgekrempelt werden außerdem funktioniert das auch nur wenn die Systeme im obersten Verzeichnis einer Domain installiert werden müssen, sobald eine Installation auch in tieferen Verzeichnissen möglich sein soll (z.B. example.com/shop/), ist das mit fertigen Scripten nicht mehr möglich. Bei Eigenenwicklungen ist es imho aber nicht verkehrt nur die Dateien direkt erreichbar zu machen die auch erreichbar sein müssen.

    Wie meinst du das?

    Wenn du http://localhost aufrufst, wird vmtl. der Inhalt des Verzeichnisses C:/xampp/htdocs aufgerufen. Damit Scripte und auch z.B. Cache-Dateien o.ä. nicht über den Browser erreichbar sind, gehören die in C:/xampp/scripte (oder so, wie genau ist eigentlich völlig egal, nur halt nicht unterhalb von htdocs).

    Wobei ich eher ganz außerhalb von C:/xampp arbeiten würde aber zum Glück muss überhaupt nicht mit Windows arbeiten und habe damit hier überhaupt kein c:/ (geschweige denn XAMPP) :)

    Vorweg: wenn du ein Posting einmal abgeschickt hast, änder es doch bitte nicht mehr. Es ist sehr verwirrend wenn man den Code zum testen kopieren will und auf einmal ist der weg.

    Ich habe einfach den PSR4-Autoloader von php-fig.org kopiert: https://www.php-fig.org/psr/psr-4/examples/.

    Ok, jetzt verstehe ich was der Code macht - das kann aber natürlich nicht funktionieren wenn der Namespace fehlt (wie in #1, dort wird in der index.php kein Namespace verwendet!).

    Dies ist die Ordnerstruktur zur Klasse Router die ich mit dem Autoloader laden möchte: app/core/Router.php

    Nun steht in der Router.php dieser Namespace: namespace App\Core;


    Wenn ich im Autoloader mir die $class direkt zu Beginn ausgeben lasse, wird einfach nur den Klassenname ausgegeben. In diesem Fall also Router.

    Dann machst du irgendwas falsch, bei mir funktioniert der Code von der angegebenen Quelle. Auch passt die Ordnerstruktur nicht zum Namespace bzw. dem $prefix im Autoloader. Bleib doch bitte mal bei einer Klasse und einem Namespace und ändere den nicht ständig - das ist sehr verwirrend und macht es quasi unmöglich den Fehler zu finden. Poste bitte auch mal den Code mit dem sich das Problem nachvollziehen lässt (einschließlich der Pfade wo was liegt).


    Wenn ich den Namespace nun in der index.php bei der Instanziierung der Klasse nochmal explizit angebe ändert sich auch nichts daran.

    Den Namespace musst du in der index.php natürlich auf jeden Fall angeben, woher soll PHP sonst wissen welchen Namespace du meinst? Ob du da am Anfang der Datei namespace …; verwendest, beim Aufruf der Klasse mit new … den Namespace voranstellst oder mit use …; arbeitest ist dabei egal.


    Zitat

    Wenn ich vom Autoloader folgenden Codeblock entferne kann ich mir zumindest den Pfad zur Datei ausgeben lassen, welche eingebunden wird, wenn diese existiert:

    Das kommt daher dass im Autoloader der Namespace nicht ankommt - der Autoloader ist nur für den angegebenen Namespace zuständig, ohne diesen bricht er natürlich ab.

    Dann habe ich mir gedacht, dass es an dem direkten Aufruf über C:\ liegt und habe direkt http://localhost/project anstelle von __DIR__ bei $base_dir genommen

    Das ist natürlich Käse. Du brauchst auf jeden Fall lokale, absolute Pfade - mit einer URL kommst du nicht weit: probier mal das PHP-Script per URL aufzurufen, was siehst du? Richtig, nichts - genau das gleiche sieht PHP wenn es die Datei per require einbindet. Ganz schlechte Idee, am besten sofort wieder vergessen.


    Aber: warum liegen die Klassen überhaupt in einem Verzeichnis das per HTTP erreichbar ist? Das einzige was in dem per http erreichbaren Verzeichnis liegt ist die index.php (sowie Bilder/JS/CSS), alle weiteren Scripte liegen in einem Verzeichnis weiter oben.

    Also nur mit HTML und CSS ist ein Slide wie ich ihn möchte nicht möglich außer mit diese checkbox Hack?

    Nein. Der Checkbox-Hack *ist* nur HTML und CSS und nur damit alleine geht das nicht barrierefrei.


    Zitat

    Hab eine Abneigung gegen diese Fonds und mit Java bin ich noch lange nicht so weit

    Was meinst du mit "Fonds"? Und Java brauchst du auch nicht, ohne Javascript geht es allerdings nicht.

    Wenn ich diesen in der index.php über App\Controller\Authentification(); aufrufen möchte wird es immer noch nicht gefunden.

    Klar, der ist ja unter App\Controller\Authentification\Authentification zu finden. Und irgendwie sieht das auch jetzt alles ganz anders aus als oben, da war noch davon die Rede dass in $class nur Authentification stehen würde. Was du mit dem $prefix und dem strncmp genau vorhast erschließt sich mir auch nicht so ganz …

    Code
    $file = preg_replace("/[^0-9a-z.\-_ ]/i", "", $_GET['file']);

    Damit machst du dir deinen Dateinamen kaputt - lass dir $file an der Stelle mal ausgeben.


    Außerdem: beschäftige dich dringend mit dem Thema Behandlung von Kontextwechseln, entweder ignorierst du sie (beim Ausgeben der Dateinamen in den Link hast du sogar zwei Kontextwechsel die beide nicht behandelt werden!) oder du machst es falsch (das htmlspecialchars() in der auf das preg_replace folgende Zeile ist Käse, du hast hier keinen Kontextwechsel nach HTML).

    Leider greift das PHP script nicht weiss jemand grad vielleicht warum

    Wie franky77 schon richtig bemerkt hat: das Problem ist deine Bedingung: es gibt kein Formularelement mit name="submitted", weswegen die Bedingung niemals wahr und der Code damit niemals ausgeführt wird. Verpasse dem Button ein name-Attribut oder frage ab ob Name oder Passwort in $_POST enthalten sind.


    Du wirst dann allerdings gleich auf das nächste Problem stoßen: die Abfrage auf korrekte Zugangsdaten wird immer true ergeben - du weist den Variablen nämlich nur einen Wert zu, zum Vergleichen musst du == verwenden. btw: das Umkopieren der Werte aus $_POST (oder auch $_GET) war schon immer sinnlos, du kannst auch direkt mit den Werten in $_POST vergleichen, $name und $PW sind überflüssig.

    Und wie willst du eigentlich verhindern dass der Besucher die Zielseite (sites/logged_in.html) einfach direkt aufruft? Beschäftige dich mit dem Thema Sessions (wobei die Zielseiten dann keine reinen HTML-Seiten sein können).


    Ach, noch was: deine header-Aufrufe werden nicht funktionieren: vorher darf nämlich *nichts* ausgegeben worden sein. Du gibst vorher das Formular aus womit die header von PHP bereits verschickt wurden und jeder Aufruf von header() nur eine Fehlermeldung ergibt. Beschäftige dich mit dem EVA-Prinzip.


    Dein HTML-Code enthält leider auch noch Fehler:

    - deine Eingabefelder haben keine Beschriftung (ein label-Element fehlt); und nein, das placeholder-Attribut ersetzt diese nicht

    - </input> gibt es nicht

    - das button-Element hat kein placeholder-Attribut

    (- HTML-Grundgerüst fehlt (vor, nach und in <html> fehlt noch was, aber evtl./hoffentlich ist <html> hier nur als Platzhalter zu sehen))

    Besser so?

    Sicherheitstechnisch, ja. Wirklich gut/richtig ist es aber nicht: zum einen hast du meinen Pseudocode nicht genau gelesen, das prepare gehört *vor* die Schleife, das muss nicht bei jedem Durchlauf erneut aufgerufen werden. Zum Anderen greifst du auf $_POST["Belag"] und überprüfst dann erst ob das Element überhaupt existiert … Lass das unsinnige Umkopieren der Werte in die Variablen einfach ganz weg und weis in $para direkt die Werte aus $_POST zu.

    Bekomme ich fiat mit Komma neben volvo?

    Sicher (implode hilft), aber wie du schon bemerkt hast: das macht man nicht. Bau das Datenbankdesign so um dass jeder Eintrag eine Zeile (in einer extra Tabelle) bekommt. Dir wird ein kaputtes Datenbankdesign sonst früher oder später auf die Füße fallen und du musst es unter großem Aufwand dann doch korrigieren, mach es also besser gleich richtig.

    Genau was ich befürchtet hatte: Die Schleife läuft leer durch, anschließend haben $key und $val jeweils den letzten Wert. Du musst das Eintragen in die DB innerhalb der Schleife erledigen:

    Und prepared Statements dabei natürlich richtig verwenden - so wie du das machst ist es falsch: im Query dürfen nur Platzhalter stehen, die Werte werden mit execute (bzw. eine bind-Methode) übergeben (Pseudocode):

    PHP
    $query = "INSERT INTO tabelle (spalte) VALUES (:value)"
    $stm = $db->prepare($query)
    foreach($_POST[…] as …){
      $stm->execute(['value' => $value])
    }

    Zudem fehlt beim Aufbau der Datenbankverbindung noch ein »;charset=utf8mb4« am Ende des DSN (bei dir die Variable $server) damit definiert ist in welcher Form du Daten bekommst bzw. in welcher Form sie die Datenbank erwartet - wenn du das weglässt bist du auf die Standardeinstellung angewiesen und die kann sich ändern.

    Ich hatte es einfacherhalber mit Komma in die Datenbank schreiben lassen um im Nachgang die Werte nicht wieder in Komma umwandeln lassen muss.

    Die Datenbank brauch einen Punkt, sonst kann sie nicht damit rechnen. Andersrum wird eher ein Schuh daraus: verwende intern immer den Punkt als Dezimaltrenner - nur dann wenn du die Werte als Text (in einem Eingabefeld bleibt der Punkt) ausgibst, bekommt der Benutzer den Wert ordentlich mit Komma formatiert angezeigt.

    Wie meinst Du das mit dem output-Element? Stehe da gerade etwas auf dem Schlauch?

    Die Felder die ein readonly-Attribut haben sind doch dazu da um die Ergebnisse von Javascript-Berechnungen auszugeben, oder? Das sind also keine Eingabe- sondern Ausgabefelder - und dafür gibt es output (die natürlich nur sichtbar sein sollten wenn Javascript auch aktiviert ist, ohne JS sind die ja relativ sinnlos)

    Zu SELECT *...was spricht in dem konkreten Fall gegen ein *?

    Siehe z.B. https://www.pg-forum.de/t/waru…rom-verwenden-sollte/5062 (ja, der Eintrag ist schon älter, er ist aber immer noch aktuell)


    Der Wert nach dem gesucht wird, ist quasi unveränderbar vorgegeben und kann durch den Benutzer nicht geändert werden.

    Das ist ein Irrtum: der Wert wird per POST-Request übertragen und kann damit vom Benutzer manipuliert werden (schon klar, vielleicht nicht von jedem Laien grundsätzlich ist es aber möglich). Kontextwechsel müssen *immer* behandelt werden ohne Ausnahme! (das gilt übrigens nicht nur für die zu SQL sondern z.B. auch für die nach HTML, d.h. wenn du irgendwas im HTML-Code an den Browser ausgibst)


    Es gibt 20 Posten-Möglichkeiten bei einem Angebot die einzeln hinterlegt werden.

    Da lag ich ja richtig, das Datenbankdesign ist tatsächlich kaputt: was ist wenn z.B. nur ein Posten hinterlegt wird, oder was ist wenn es mal 21 Posten sein sollen? Die Posten gehören in eine zweite Tabelle in der jeder Datensatz einen Posten zu einem Angebot enthält - beschäftige dich mit dem Thema Normalisierung.


    Bist du bei deinem eigentlichen Problem weitergekommen? Liegt es an dem Komma als Feldtrenner an dem Javascript wieder aufgetrennt wird?

    Ich lasse mittel Ajax ein Formular (Kostenangebot) aus einer Datenbank füllen, darunter auch reichlich Input-Felder mit Preisen. Diese haben bekannter Weise das Format 12,34, sprich 2 Nachkommastellen. In der Datenbank selbst ist das richtige Format hinterlegt (mit Komma, nicht mit Punkt).

    Wie kommst du darauf dass es mit Komma richtig wäre? Richtig ist mit Punkt, alle Programmiersprachen (und auch HTML, siehe unten) und Datenbanken erwarten einen Punkt als Dezimaltrenner.

    Zitat

    Auszug aus dem Formular was mittels Ajax gefüllt wird:

    Das Formular ist kaputt:

    • die Felder haben keine Beschriftung (label-Element) und nein, placeholder ersetzt diese nicht!
    • die Felder für Anzahl und Preis wären gerne vom Typ »number«, damit erleichterst du dem Benutzer die Eingabe und kannst auch Grenzen (min-/max-Attribute) und Schritte (step-Attribut) definieren. Wichtig: bei Preisen müssen die Werte einen Punkt als Dezimaltrenner haben, dargestellt werden sie dann mit Komma (wobei das von den Einstellungen des Browsers/Betriebssystems abhängig ist)
    • das readonly-input wäre gerne ein output-Element.
    Zitat

    Die stmmactionangebot.php:

    Der Code hat gleich mehrere Problem (eines davon ist gefährlich!):

    • du übernimmst ohne den Kontextwechsel zu beachten/behandeln Werte von außen in den SQL-Query - das ist gefährlich! Unbedingt den im Query eingebauten wert behandeln, ich empfehle prepared Statements (geht auch mit mysqli, ich empfehle aber PDO)
    • das Umkopieren von Werten aus $_POST ist unnötig
    • niemals »SELECT *« verwenden, immer alle Spalten angeben die benötigt werden. Ja, auch wenn es (aktuell) alle sind
    • der Query liefert nur einen Datensatz, oder? Wofür dann das while?
    • die durchnummerierten Spalten deuten auf ein defektes Datenbankdesign hin
    • lass ?> weg wenn nicht anschließend HTML kommt, damit vermeidest du potentielle Problem mit versehentlich ausgegebenem Whitespace

    Dein eigentliches Problem dürfte aber das unpassende Datenformat sein in dem du die Werte an Javascript schickst: du klebst einfach alles mit Komma zusammen und trennst es im Javascript wieder auf - allerdings ohne Rücksicht darauf ob der Wert selbst auch ein Komma enthält … Verwende besser ein Format wie JSON, damit solltest du das Problem nicht haben (PHP und Javascript können beide standardmäßig mit JSON umgehen).

    Gibt es da eine Möglichkeit?

    Nein. Wie der Funktionsname schon sagt verschlüsselt die Funktion nicht, sie erstellt ein Hash des Passworts - und dieser Vorgang ist nicht umkehrbar. Wenn ein Benutzer sein Passwort vergessen hat bleibt nur ein neues zu setzen - wobei dass ein Benutzer normalerweise ohne Hilfe des Admins machen können sollte.

    Geht es noch kürzer ?

    Klar: Zeilenumbrüche entfernen, </form> weglassen, name-Attribut weg, Anführungszeichen um Attributwerte weglassen, das Bild im gleichen Verzeichnis speichern und nur "b" nennen; zudem noch den PHP-Teil nach hinten (spart das »?>«), dort das if weglassen und die Kurzform des php-Tag verwenden (»<?=var_dump($_GET);«). var_dump() ist zum einen gefordert und zum anderen gibt print_r immer was zurück was - auf Kosten zusätzlicher Zeichen - unterdrückt werden müsste wenn man <?= verwenden will.