Variablen innerhalb for-Schleife berechnen

Boah.... ich stehe gerade echt auf dem Schlauch...!
Erklärst du bitte für die ganz doofen, was du damit meinst? Rückgabewert von dbquery: damit meinst du nicht das Ergebnis aus der DB-Abfrage, oder?
Läuft da im Hintergurnd PDO? Oder MYSLQi? Oder eine Oracle-Zugriff? Auch hier... wo finde ich diese Information?
 
Also. Du hast da 2 Funktionen die ich nicht kenne. dbquery() und dbarray().
Diese Funktionen haben irgendwelche Rückgabewerte. Objekte, Arrays, ev. einfach eine Zahl.
Und diese Funktionen arbeiten mit irgend einer Library. über die auf die Daten zugegriffen wird. Ev. gibt dbQuery ein PDO-Statement-Objekt zurück?
Ich weiss es nicht. Es ist für mich eine Blackbox, da ich nicht weiss, wie das Programmiert ist.

Jetzt soll ich dir sagen, wie du den Rückgabewert, von dem ich absolut keine Ahnung habe ob es ein Auto - eine Telefonnummer oder ein ganzes Universum ist, durchblättern sollst?

Sorry, für Ratespiele bin ich zu alt.
 
Das du für Ratespiele keine Lust hast, kann ich gut verstehen. Ich habe mal die Maincore-Datei durchwühlt und folgende Funktionen gefunden, die- so hoffe ich - etwas Licht ins Dunkel bringen

PHP:
// MySQL database functions
function dbarray($query) {
        $result = @mysql_fetch_assoc($query);
        if (!$result) {
                echo mysql_error();
                return false;
        } else {
                return $result;
        }
}
function dbquery($query) {
        $result = @mysql_query($query);
        if (!$result) {
                echo mysql_error();
                return false;
        } else {
                return $result;
        }
}
 
Jepp das tun sie.
Als erstes! Diese Funktionen sofort ersetzen. mysql_* Funktionen sind seit mehreren Jahren veraltet. In den neueren PHP-Verion gibt es sie auch nicht mehr. Zudem sind das Sicherheitslücken.
Google mal nach mysql ersetzen durch mysqli.

dbarray() kannst du nur verwenden.
Dann könnte die Schleife etwa so aussehen
PHP:
$ccp_result =  dbquery($sql);
while($ccp_row = dbarray($ccp_result){
    echo $ccp_row['valuta'];
}


PHP:
$numbers = array_extract_sub_item($vehicles , 'nummer');
Sollte stimmen, sofern du die Funktion array_extract_sub_item() von meiner Seite in dein Code kopiert hast.

Lass dir mal mittels var_dum() den Inhalt von $numbers zeigen. Ebenfalls die 2 generierten SQL-Statements
 
@Yaslaw müsste dies
PHP:
$sqlSum = <<<SQL
    SELECT
        SUM(rechnung) AS total
    FROM
        %sccp_buchungen
    WHERE
        rechnung IN (%s)
SQL;
$sql = sprintf($sqlDetail, $db_prefix, implode(',', $numbers));
nicht so lauten?
PHP:
$sqlSum = <<<SQL
    SELECT
        SUM(rechnung) AS total
    FROM
        %sccp_buchungen
    WHERE
        rechnung IN (%s)
SQL;


$sql = sprintf($sqlSum, $db_prefix, implode(',', $numbers));
Habe nun sonst nicht weiter drauf geschaut, sondern nur mal auf die schnelle?
Also $sqlSum in die $sql drinne rein?
 
Der Inhalt von $numbers scheint OK zu sein:
PHP:
array(10) { [0]=> string(8) "20151125" [1]=> string(9) "EB7789429" [2]=> string(10) "1299420563" [3]=> string(10) "9083219627" [4]=> string(10) "4764586925" [5]=> string(10) "0979641143" [6]=> NULL [7]=> NULL [8]=> NULL [9]=> NULL } Query was emptyQuery was emptyQuery was emptyQuery was emptyQuery was empty

Seltsamerweise klappt es nun mit den 2 generierten SQL-Statements nicht mehr. Ohne sie auszukommentieren, lädt die Seite nicht mehr.
 
Mir ist klar, dass das fürs eigentliche Thema nichts bringt, aber um das nochmal zu betonen:
  • Dass so ziemlich alle Softwareversionen, die ich finden kann, veraltet sind und bekannte Sicherheitsprobleme haben (PHP, jQuery, ...)
  • dass es die mysql_ - Funktionen nicht mehr gibt, dass Latin1 verwendet wird, ...
  • dass @ im Code, einfach zu findende XSS-Lücken usw.
  • eine CMS-Software von der im Internet nicht (mehr?) viel zu finden ist
  • die Menge an PHP-hältigen Links auf der Startseite
  • ... usw.
sind alles Indikatoren dafür, dass
  • die Seite im Gesamten einerseits dringend verbessert werden müsste, und das aber keine kleine Aufgabe wird. Vielleicht ist sogar ein kompletter Neubau angebracht
  • Bitte nicht als Beleidigung auffassen: dass niemand der beteiligten Programmierer von diesem CMS (und/oder du?) eine Seite dieser Größe online stellen sollte, ohne zuerst noch einiges zu lernen. (Und das betrifft auch den Serveradmin, ich glaub das bist auch du)

...
Warum?
Wenn "Sicherheit", "eine Reihe von Funktionsproblemen", "schlechtes Google-Ranking", usw. noch keine ausreichende Motivation sind:
Bald kommt der Punkt, an dem die Seite sonst einfach nicht mehr verwendbar ist. Weil sie gehackt wurde (falls das nicht sowieso schon passiert ist), oder weil JQuery keine 1.7-Version mehr ausliefert, oder weil Browser immer mehr HTTPS forcieren, oder weil man Server wechseln muss und kein altes PHP mehr bekommt, ... und auf neue Versionen updaten usw. geht ja nicht, ohne dass der vorhandene PHP-Code nicht mehr funktioniert.
 
Zuletzt bearbeitet:
@sheel
  • Dass so ziemlich alle Softwareversionen, die ich finden kann, veraltet sind und bekannte Sicherheitsprobleme haben (PHP, jQuery, ...)
  • dass es die mysql_ - Funktionen nicht mehr gibt, dass Latin1 verwendet wird, ...
  • dass @ im Code, einfach zu findende XSS-Lücken usw.
  • eine CMS-Software von der im Internet nicht (mehr?) viel zu finden ist
  • die Menge an PHP-hältigen Links auf der Startseite
  • ... usw.

Ich danke dir für die konstruktive Kritik. Könntest du die oben angeführten Beispiele etwas dezidierter Erläutern und ggf. Änderungsvorschläge dazu unterbreiten? Sicherheit ist mir natürlich wichtig, scheue allerdings auch ein wenig den kompletten Neuaufbau.

Vorab besten Dank,
Ingo
 
scheue allerdings auch ein wenig den kompletten Neuaufbau.
Natürlich verständlich ...

Zuerst einmal ist (für dich) die Frage, ob es von den verwendeten Softwares nicht doch noch wo neue Versionen gibt (speziell dieses CMS). Und falls nicht, ob du bereit bist das selber zu warten, oder doch lieber die Seite mit einer anderen (nicht aufgegebenen) Software machst.

Zweiter Punkt für die Arbeitsmenge: Wie sehr objektorientiert ist der ganze Ansatz? Dh., egal ob mit class oder nur function oder so, ist Code für ein bestimmtes Thema (wie zB. Userlogin/logout/registrieren/löschen/...) an einer bestimmten Stelle gesammelt, in Funktionen die dann in den passenden PHP-Dateien verwendet werden; oder ist alles irgendwie verteilt und evt. auch an verschiedenen Stellen das Selbe mehrfach programmiert? Letzteres erhöht den Aufwand sehr ... und das umzustrukturieren wäre das Erste, was ich machen würde.
...
Zu den bisher erwähnten Probleme (aber beachten, dass das nur die bisher bekannten sind, es kann noch viel mehr geben):

Die mysql_ - Funktionen gibt es nicht mehr (die Datenbank Mysql schon, aber die gleichnamigen Funktionen in PHP nicht). Ersatz sind entweder Funktionen namens mysqli_... die relativ ähnlich zu verwenden sind (aber nicht ganz gleich, weil zumindest ein großes Problem der alten Funktionen ohne weitere Parameter nicht lösbar gewesen wäre), oder die PDO-Klasse. Wie das verwendet wird ist leicht findbar, bei Bedarf gern mehr Details.

In beiden Fällen auch aufpassen, möglichst nie PHP-Variablen direkt in den SQL-String einzufügen. Das ist als SQL-Injection bekannt und eins der zwei häufigsten Sicherheitsprobleme in PHP. Kurzbeschreibung:
Code:
query('SELECT * FROM benutzer WHERE name="$dername" ');

Ein paar mögliche Werte für $dername, und die daraus resultierende Abfrage:

Hans
query('SELECT * FROM benutzer WHERE name="Hans" ');

Kurt
query('SELECT * FROM benutzer WHERE name="Kurt" ');

" OR "1"="1
query('SELECT * FROM benutzer WHERE name="" OR "1"="1" ');
Die letzte Abfrage findet alle Benutzer, bei denen entweder der Name leer oder 1 gleich 1 ist, und das sind alle Benutzer. Also, mit einem gezielt seltsamen Variablenwert hat man plötzlich die Art der Abfrage verändert. Wenn dieser Variablenwert zB. aus einer Formulareingabe kommt, oder aus einem Cookie, oder zig andere Möglichkeiten außerhalb vom Server, kann damit jeder beliebig SQL-Anweisungen verändern. Logins umgehen, die ganze Datenbank leeren, möglich ist damit viel.
Abhilfe: prepare: Platzhalter und dann die Werte extra getrennt vom SQL-String übergeben. Siehe zB. https://stackoverflow.com/questions...a-pdo-object-for-a-parameterized-select-query

Das zweite der zwei häufigsten PHP-Sicherheitsprobleme: XSS. In der einfachsten Form: Ein Benutzer liefert irgendwelche Daten, die anderen Benutzern später auch angezeigt werden können. Egal ob ein Beitrag im Forum, der eigene Benutzername, oder andere Sachen.
Am Beispiel Benutzername beim Registrieren:
Vorwissen 1: Fett geschrieber Text in HTML geht zB. so, nur als Erinnerung:
Code:
<span style="font-weight:bold;">Hier der Fette Text</span>
Vorwissen 2: Die Zeichen < und > (und auch weitere) haben in HTML ja eine spezielle Bedeutung. Wenn man aber zB. <> einfach als Text anzeigen will, und es nicht als HTML-Steuerding verstanden werden soll, muss man solche Platzhalter verwenden:
Code:
&lt; &gt;
So, Benutzername beim Registrieren: Wenn ich Hans eingebe, wird das eben in der DB abgespeichert, und wenn sich dann jemand die Benutzerliste oder so anschaut sendet der Server das Wort Hans zu diesem anderen Benutzer. Bisher kein Problem. Wenn ich aber
Code:
<span style="font-weight:bold;">Hans</span>
als Benutzernamen eingebe? ... Sobald sich das ein anderer Benutzer anschaut interpretiert der Browser das als fett geschriebenes Hans, statt nur Hans, und damit habe ich beeinflusst wie die Seite für andere Benutzer aufgebaut ist. Das echte Problem ist dann zB. der Einbau von Links auf Seiten mit Malware oder illegalem Zeug, und noch viel schlimmer der Einbau von Javascript das dann bei allen Benutzern, die meinen Benutzernamen sehen, viel Schaden anrichten kann.
Prinzipielle Lösung: Bei Eingaben mit < und > stattdessen &lt; und &gt; ausgeben (und auch für die anderen wichtigen Zeichen so). Da gibts auch schon eine nette Funktion: htmlspecialchars. Also beim Registrieren kann es ruhig mit <> in die DB, aber beim Auslesen und echo'n zuerst mit dieser Funktion behandeln.

Und zu dieser Funktion:
Code:
function dbarray($query) {
        $result = @mysql_fetch_assoc($query);
        if (!$result) {
                echo mysql_error();
                return false;
        } else {
                return $result;
        }
}
Also eine Abfrage. Die kann evt. Warnungen oder Fehler echo'n, aber das wird hier mit @ unterdrückt (genau das macht @: Verhindern, dass Warnungen/Fehler ausgegeben werden). Dann, falls die Abfrage nicht funktioniert hat, wird der Fehler erst wieder selber ausgegeben.
Drei Probleme damit:
  • Warum werden Fehler zuerst unterdrückt und dann doch wieder ausgegeben? Allerdings: Warnungen, die separat von Fehlern sind, werden damit noch immer unterdrückt, und nirgends ausgegeben. Warum? Mir fällt nur ein möglicher Grund ein: PHP hat, als es die mysql_-Funktionen noch gab, schon einige Jahre Warnungen ausgegeben, wenn sie verwendet wurden (Warnungen, dass es sie bald nicht mehr gibt und man endlich umsteigen soll). ... Es gibt leider Leute, die wider besseren Wissens einfach so weitergemacht haben, denen es egal ist dass ein PHP-Update alles kaputtmacht (zB. "noch schnell möglichst oft das CMS verkaufen, bevor die Funktionen entfernt werden, und dann das CMS aufgeben"), oder die irgendwie Angst haben sich umzugewöhnen und sich auch nicht helfen lassen wollen, oder die die Warnungen einfach nicht ernst genommen haben...
    Daraus schließen kann man wie gesagt entweder, dass es nur irgendwie möglichst schnell hingefetzt wurde und es genug ist dass es auf den ersten Blick funktioniert hat (solcher Code hat meistens viele andere Probleme), oder dass Mysqli dem Ersteller zu kompliziert ist (obwohl es viel schwierigere Sachen auch gibt, solcher Code hat üblicherweise auch noch viel mehr Probleme)
  • Für einen Entwickler, der ordentlichen Code machen will, ist es auch selbst schädlich. Man übersieht evt. Fehler weil man nie eine Meldung bekommt. Außerdem würde es ohne das @ eine einfache Möglichkeit geben, Fehler/Warnmeldungen generell ein- und auszuschalten; das verbaut man sich damit auch (zB. wieder deswegen, weil man diese Möglichkeit nicht kennt, und generell nicht so toll in PHP ist. Stichwort error_reporting E_ALL und ini_set display_errors).
  • Der Code zeigt im Fehlerfall Fehler immer an, auch ggf. normalen Webseitenbenutzern. Das ist nicht nur verwirrend und hässlich, sondern auch ein Sicherheitsproblem. zB. kann im Extremfall das Passwort zur DB in der Meldung enthalten sein. Oder man sieht dadurch, wie ein paar Tabellen und Spalten heißen, und kann sich damit noch einfacher SQL-Injections zusammenbauen. (Speziell mit den SQL-Injections kann man auch Meldungen provozieren, mit denen man dann noch mehr gesuchte Infos bekommt).

Sobald man denkt dass die Seite PHP7-tauglich ist: Updates! PHP, Apache, das Betriebssystem, jQuery, ...
Dann a) alles kurz durchtesten, ob es noch vergessene PHP7-Probleme gibt, oder etwas mit der neuen jQuery-Version nicht mehr funktioniert (da hat sich seit 1.7 auch viel geändert) ... und wenn das passt, im Idealfall täglich automatische Sicherheitsupdates einrichten (nur kleine, keine großen Versionssprünge) (zumindest, wenn man sich halbwegs drauf verlassen kann dass durch die kleinen Updates nichts kaputt wird. Kommt aufs Betriebssystem an, ob das so ist. Btw., läuft deine Seite auf OpenBSD, oder hab ich mich verschaut?)
Und Backups...

Latin1: Kein harter "Fehler", aber: Dadurch ist es nicht möglich, auf einer Seite Buchstaben aus anderen Sprachen zu verwenden, die es im Deutschen nicht gibt. (und auch andere nicht so wichtige Zeichen). Egal ob französische á, spanische Buchstaben, oder Griechisch, Russisch, Japanisch, irgendwas... außerdem wirkt es sich aufs Google-Ranking aus. Wenn man das untersützen will: Alles auf UTF8 umstellen. Unter anderem die relevanten DB-Spalten, den Text in den PHP-Dateien selber (im Codeeditor einstellbar), und die Ausgabe an den Browser (Befehl header() am Anfang jeder Seite)
(wenn in der DB serialize-Daten sind, die solche Sonderzeichen enthalten, wirds leider viel umständlicher. Weils grad zum Thema passt, serialize-Daten besser nie langfristig speichern).

HTTPS. Weil sicherer, und nebenbei auch besser fürs Google-Ranking. Ist etwas umständlicher, kurz beschrieben: Zertifikat besorgen (zB. LetsEncrypt, OpenSSL-CSR, acme_tiny-Client, Cron), Apacheeinstellungen (VHost, Zertifikat und Ciphersuites, und HTTP->HTTPS-Umleitung mit mod_rewrite), bei Bedarf Links/Bilder/... in der Seite bei denen http:// vorne steht anpassen (wenn man einfach mit // anfangt wird je nach Bedarf automatisch https oder http genommen).

...

Zu jedem Punkt könnte man noch mehr schreiben, Details gern wenn nötig.

Und wenn man mehr für die Sicherheit tun will: Dieser Post https://www.tutorials.de/threads/ei...sicherheit-in-php-mysqli.405447/#post-2098032 (und der gesamte Thread) sprechen eine Reihen weiterer Themen an.
 
Zuletzt bearbeitet:
Zurück