====== PHP ====== automatisch die aktuellste Version runterladen: > for i in $(links -dump http://php.net/downloads.php | fgrep 'Current Stable' | head -n1 | sed 's/ /\n/g' | grep -P '[0-9]+.[0-9]+.[0-9]+');do wget -nc -O php-${i}.tar.gz http://de1.php.net/get/php-${i}.tar.gz/from/this/mirror ; done ===== Bücher ===== * ISBN-13: ''978-3839154090'' (PHP für dich: So einfach war PHP-lernen noch nie! von Claudia Unkelbach) ===== Links ===== * [[http://reeg.junetz.de/DSP/node13.html]] * [[http://mikiwiki.org/wiki/PHP]] * [[http://www.php.net/manual/de/index.php]] * [[http://www.teialehrbuch.de/Kostenlose-Kurse/PHP/22349-Vorwort.html]] * [[http://www.dynamic-webpages.de/php/]] ===== Syntax ===== ==== allgemeines zur Ausgabe ==== zeigt alle für die CLI aktivierten Module an > php -m zeigt alle für FPM (nginx) aktivierten Module an > php-fpm8.1 -m zeigt alle aktiven nginx-Module an > ls -lha /etc/nginx/modules-enabled/ === Array anzeigen === > echo var_export($result); mysqli_stmt::__set_state(array( 'affected_rows' => NULL, 'insert_id' => NULL, 'num_rows' => NULL, 'param_count' => NULL, 'field_count' => NULL, 'errno' => NULL, 'error' => NULL, 'error_list' => NULL, 'sqlstate' => NULL, 'id' => NULL, )) > print var_export($result); mysqli_stmt::__set_state(array( 'affected_rows' => NULL, 'insert_id' => NULL, 'num_rows' => NULL, 'param_count' => NULL, 'field_count' => NULL, 'errno' => NULL, 'error' => NULL, 'error_list' => NULL, 'sqlstate' => NULL, 'id' => NULL, )) > print_r($result); mysqli_stmt Object ( [affected_rows] => 4 [insert_id] => 0 [num_rows] => 4 [param_count] => 0 [field_count] => 1 [errno] => 0 [error] => [error_list] => Array ( ) [sqlstate] => 00000 [id] => 1 ) ==== PHP-Fehler anzeigen ==== diese zwei Zeilen an den Anfang des fehlerhaften Skriptes setzen: ==== OS-Info ==== ==== uname -a ==== ==== if not ==== ==== alle variablen ausgeben ==== * [[http://forum.de.selfhtml.org/archiv/2005/9/t115273/]] * [[http://de3.php.net/manual/de/function.print-r.php]] ==== Array in Variable speichern ==== * [[http://www.php-einfach.de/php-tutorial/php-array.php]] $value) { $string .= $key . " = " . $value . "\n"; } // hier werden aus dem Array nur die Werte von "key=artikel" in der Variablen gespeichert: foreach ($_REQUEST as $key => $value) { if (strncmp($key, "artikel") == 0) { $string .= $value; } } ?> ==== Arrays ausgeben ==== foreach($allResults as $key=>$val){ print ($val["name"] . "\n"); } foreach($allResults as $value) { $string = $value["name"]; print ($string . "\n"); } foreach($allResults as $value) { print ($value["name"] . "\n"); } foreach($allResults as $key => $value) { print ($key . "=" . $value["name"] . "\n"); print ($value["name"] . "\n"); } foreach($allResults as $key => $value) { $string = $key . "=" . $value["name"]; print ($string . "\n"); } ==== Das global Schlüsselwort ==== Um die Variablen innerhalb und außerhalb der Funktion zugänglich zu machen, bietet PHP das Schlüsselwort global. Dieses Schlüsselwort ermöglicht es, außerhalb einer Funktion liegende Variablen "in die Funktion hinein" zu holen. Nur dadurch können sie auch innerhalb der Funktion ihre Gültigkeit besitzen und z.B. ausgegeben werden. Beachten Sie, dass eine Änderung der Variable, die Sie mittels global für die Funktion sichtbar gemacht haben, nicht nur für die Verwendung innerhalb der Funktion gilt, sondern auch außerhalb. ?> ==== Die Verwendung von GLOBALS ==== ==== statische Variablen ==== Normalerweise würde diese Funktion sinnlos sein, da die Variable "$a" immer wieder auf "0" gesetzt wird und nach der Ausgabe erst um "1" erhöht wird. Da die Variable "$a" aber als //static// deklariert wurde, verliert sie ihren Wert nicht und die Funktion gibt bei jedem Aufruf einen neuen Wert aus, der um "1" höher ist als der vorhergehende Wert. Static-Variablen ermöglichen auch einen Weg zum Umgang mit rekursiven Funktionen. Das sind Funktionen, die sich selbst aufrufen. Hierbei besteht die Gefahr, so genannte Endlos- Schleifen zu programmieren. Sie müssen also einen Weg vorsehen, diese Rekursion zu beenden. Die folgende einfache Funktion zählt rekursiv bis 10. Die statische Variable "$zaehler" wird benutzt, um die Rekursion zu beenden: Statische Variablen werden wie in oben stehenden Beispielen deklariert. Das Zuweisen eines Wertes, welcher das Ergebnis eines Ausdrucks ist, wird mit einem //parse error quittiert//. ==== Dateioperationen ==== siehe [[http://php.net/manual/de/function.fopen.php]] ^ mode ^ Beschreibung ^ | 'r' | Nur zum Lesen geöffnet; platziere Dateizeiger auf Dateianfang. | | 'r+' | Zum Lesen und Schreiben geöffnet; platziere Dateizeiger auf Dateianfang. | | 'w' | Nur zum Schreiben geöffnet; platziere Dateizeiger auf Dateianfang und kürze die Datei auf eine Länge von 0. Existiert die Datei nicht, versuche, diese zu erzeugen. | | 'w+' | Zum Schreiben und Lesen geöffnet; platziere Dateizeiger auf Dateianfang und kürze die Datei auf eine Länge von 0. Existiert die Datei nicht, versuche, diese zu erzeugen. | | 'a' | Nur zum Schreiben geöffnet; platziere Dateizeiger auf Dateiende. Existiert die Datei nicht, versuche, diese zu erzeugen. In diesem Modus ist ''fseek()'' wirkungslos; beim Schreiben wird immer angehängt. | | 'a+' | Zum Schreiben und Lesen geöffnet; platziere Dateizeiger auf Dateiende. Existiert die Datei nicht, versuche, diese zu erzeugen. In diesem Modus wirkt sich ''fseek()'' nur auf die Leseposition aus; beim Schreiben wird immer angehängt. | | 'x' | Erzeuge und Öffne nur zum Schreiben; platziere Dateizeiger auf Dateianfang. Falls die Datei schon existiert, wird der **fopen()** Aufruf fehlschlagen durch Rückgabe von **FALSE** und dem Auslösen eines Fehlers der Stufe **E_WARNING**. Existiert die Datei nicht, versuche, diese zu erzeugen. Dies ist zur Angabe der ''O_EXCL''/''O_CREAT'' Flags für den darunterliegenden ''open(2)'' System Aufruf äquivalent. | | 'x+' | Erzeuge und Öffne zum Schreiben und Lesen; ansonsten ist das Verhalten gleich wie bei 'x'. | | 'c' | Öffne Datei nur zum Schreiben. Wenn die Datei nicht existiert, wird diese erzeugt. Wenn sie existiert, wird sie weder gekürzt (im Gegensatz zu 'w'), noch schlägt der Aufruf dieser Funktion fehl (wie dies mit 'x' der Fall ist). Der Dateizeiger wird auf den Dateianfang platziert. Dies kann nützlich sein, wenn man eine "beratende" (kooperative) Sperre erhalten möchte (siehe flock()) bevor man versucht, die Datei zu ändern, da die Nutzung von 'w' die Datei kürzen könnte, bevor die Sperre erhalten wurde (falls Kürzen gewünscht ist, kann ftruncate() genutzt werden, nachdem die Sperre angefragt wurde). | | 'c+' | Öffne Datei zum Lesen und Schreiben; ansonsten ist das Verhalten gleich wie bei 'c'. | | 'e' | Setzt das close-on-exec Flag für den geöffneten Datei-Descriptor. Nur verfügbar, wenn PHP auf POSIX.1-2008 konformen System kompiliert wurde. | ==== Variablen und Dateien ==== ==== Variable-Inhalt in eine Datei schreiben ==== Inhalt der Variablen "$test" wird in die Datei "/tmp/test.txt" geschrieben: hiermit kann man nachsehen, welche Daten z.Z. in den Variablen stehen, alle Variableninhalte werden in die Datei "/tmp/GLOBALS.txt" geschrieben: alle Inhalte des HTTP_REFERER in die Datei "/tmp/HTTP_REFERER.txt" schreiben: aus dem HTTP_REFERER soll nur die Info über die Variable "release" in die Datei "/tmp/release.txt" geschrieben werden: [[http://www.php-kurs.info/tutorial-google_referer_auslesen.html]] ==== Inhalt aus einer Datei auslesen ==== [[http://php.net/manual/de/function.file-get-contents.php]] ==== Wert aus einer Datei auslesen ==== Beispiel-Configurationsdatei vorbereiten: # echo 'RELEASE="1.2.3"' >> /etc/datei.conf $zeile) { if(strncmp($zeile,"RELEASE",7)==0) { $release_wert=substr($line,9,strlen($zeile)-11); } } echo $release_wert; ?> - "RELEASE" ist die zu suchende Zeichenfolge und sie sie ist "7" Zeichen lang; - die "9" gibt die Anzahl der zu überspringenden Zeichen an ('RELEASE="' -> 7+2=9); - "strlen($zeile)" ist eine interne Funktion, die die Gesamtlänge der Zeile angibt; - es sollen "Gesamtlänge" minus "11" Zeichen gelesen werden; - auf "11" kommt man, in dem die "7" zu überspringenden Zeichen mit dem abschließenden doppelten Hochkommata (") und dem Zeilenumbruch addiert werden (die ja jeweils ein weiteres Zeichen dar stellen) => ('RELEASE="'+'"\n' -> 7+2+2=11); - damit ist die ZEILENLÄNGE minus 11 genau die Zeichenanzahl, die zwischen den doppelten Anführungszeichen stehen; ==== warten bis eine Datei da ist ==== Hier ist diese nützliche Funktion: function auf_datei_warten($wartedatei) { $loop_max=100; $loop_zahl=0; while (!file_exists($wartedatei)) { sleep(1); $loop_zahl++; flush(); if ($loop_zahl > $loop_max) { return false; } } return true; } und so setzt man sie beispielsweise ein: if (auf_datei_warten($dateiname)) { // Datei ist da, kann los gehen... // wir geben der Datei noch eine Sekunde extra sleep(1); } else { // Datei ist in der vorgegebenen Zeitspanne nicht eingetroffen. ABBRUCH! exit(1); } ==== Datenbankzugriff ==== mit Ubuntu werden die im folgenden benötigten Pakete so installiert: > apt install php5 php5-mysql php5-sybase === mysql_connect (veraltet) === === mysqli_connect (alt) === * [[http://www.php-kurs.com/mysql-datenbank-auslesen.htm]] * [[http://www.html-info.eu/mysql-und-php/basiswissen-sql/item/tipps-fuer-effiziente-datenbankabfragen.html]] set_charset('utf8'); if ($link -> connect_errno) { printf("Verbindung fehlgeschlagen: %s\n", $mysqli->connect_error); exit(); } $sql = "SHOW DATABASES;"; //$sql = "SHOW TABLES FROM $datenbank"; //print_r($link -> prepare($sql)); $result = $link -> prepare($sql); $result -> execute(); $result -> store_result(); $result = mysqli_query($link,$sql); //echo var_export($result); //print var_export($result); //print_r($result); $ausgabe = ""; while ($row=mysqli_fetch_row($result)) { $ausgabe .= "{$row[0]}\n"; } echo $ausgabe; $result -> close(); $link -> close(); ?> === PDO === Die Option ''PDO::MYSQL_ATTR_SSL_VERIFY_SERVER_CERT'' darf nicht verwendet werden! Ihr ist es scheißegal ob sie auf "true" oder "false" gesetzt wird, sie schaltet die Verifikation **IMMER** ab!!! * [[http://php.net/manual/de/ref.pdo-mysql.connection.php]] * [[https://www.ibm.com/docs/en/db2/11.5?topic=pdo-commit-modes|Commit modes in PHP (PDO)]] * [[::Datenbankverbindungen zu einer MySQL mit SSL-Verschlüsselung#Mit dem PDO-Client von PHP]] Ubuntu > apt install php-cli php-mysql #!/usr/bin/php query($sql) as $row) { echo $row['Host']."\t\t".$row['User']."\t\t".$row['authentication_string']."\n"; } // und nach der Nutzung, die Verbindung beenden $dbh = null; ?> zeigt alle hinterlegten Benutzer an: > php show_users.php query($sql) as $row) { echo $row['Tables_in_mysql']."\n"; } $dbh = null; ?> zeigt alle Tabellen, aus der Datenbank "mysql" an: > php show_tables.php zeigt alle hinterlegten Benutzer an: > php show_users.php #!/usr/bin/php query($sql) as $row) { echo $row['Database'] . "\n"; } // und nach der Nutzung, die Verbindung beenden $dbh = null; ?> > /usr/local/bin/mysqlshow.php [User] [Passwort] [Host] [Port] > /usr/local/bin/mysqlshow.php root geheim 192.168.1.14 3306 #!/usr/bin/php '/path/to/client-key.pem', // PDO::MYSQL_ATTR_SSL_CERT => '/path/to/client-cert.pem', // PDO::MYSQL_ATTR_SSL_CA => '/path/to/ca-cert.pem' //); $ssl_optionen=array( PDO::MYSQL_ATTR_SSL_KEY => $db_key, PDO::MYSQL_ATTR_SSL_CERT => $db_crt, PDO::MYSQL_ATTR_SSL_CA => $db_ca, PDO::ATTR_PERSISTENT => false ); // Abfrage definieren $sql = "SHOW DATABASES"; // Verbindung zur Datenbank aufbauen //$dbh = new pdo('mysql:host=' . $dbhost . ';port=' . $dbport . ';dbname=mysql', $dbuser , $dbpass); try { $dbh = new PDO( // 'mysql:host=' . $dbhost . ';port=' . $dbport , $dbuser , $dbpass 'mysql:host=' . $dbhost . ';port=' . $dbport , $dbuser , $dbpass, $ssl_optionen ); } catch (PDOException $e) { print "Error!: " . $e->getMessage() . "\n"; die(); } // Verbindung nutzen // Verbindung nutzen foreach ($dbh->query($sql) as $row) { echo $row['Database'] . "\n"; } // und nach der Nutzung, die Verbindung beenden $dbh = null; ?> #!/usr/bin/php prepare($sql); $sql->execute(); // Verbindung nutzen $total = $sql->fetchColumn(); print "total='" . $total ."'\n"; print "\n"; // und nach der Nutzung, die Verbindung beenden $dbh = null; ?> > php datenbankzugriff_arg1.php root geheim 192.168.10.1 3306 testdb testtab #!/usr/bin/php prepare($sql); $sql->execute(); while ($row = $sql->fetch(PDO::FETCH_ASSOC)) { echo $row['id']."\n"; } print "\n"; // und nach der Nutzung, die Verbindung beenden $dbh = null; ?> > php datenbankzugriff_arg2.php root geheim 192.168.10.1 3306 testdb testtab prepare($sql); $sql->execute(); // Datei öffnen $dateiname = "/tmp/test.txt"; //$dateiname = "/dev/null"; //$handler = fOpen($dateiname , "a+"); $handler = fOpen($dateiname , "w"); while ($row = $sql->fetch(PDO::FETCH_ASSOC)) { //echo $row['id']."\n"; //print_r($row)."\n"; //fWrite($handler , $row['id']."\n"); fWrite($handler , print_r($row,1) . "\n"); } //print "\n"; // Datei wieder schließen fClose($handler); // und nach der Nutzung, die Verbindung beenden $dbh = null; ?> > php datenbankzugriff_arg3.php root geheim 192.168.10.1 3306 testdb testtab Der Inhalt der Datei ''/tmp/test.txt'' ist ein Array, keine von Menschen lesbare Tabelle, wie man es von der Ausgabe durch "''mysql -t''" her kennt. In der foldenden wird bei einem Verbindungsfehler, die Fehlerausgabe in eine separate Datei geschrieben: setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); $sql = $dbh->prepare($sql); $sql->execute(); } catch(Exception $e) { fWrite($fehlerhandler , date(date("Y-m-d H:i:s",time())) . " Exception -> " . print_r($e->getMessage(),1) . "\n"); } // Datei öffnen $infodatei = "/tmp/test"; $infohandler = fOpen($infodatei , "a+"); // Daten aus der DB abrufen while ($row = $sql->fetch(PDO::FETCH_ASSOC)) { //echo $row['id']."\n"; //print_r($row)."\n"; //fWrite($handler , $row['id']."\n"); fWrite($infohandler , print_r($row,1) . "\n"); } //print "\n"; // Datei wieder schließen fClose($fehlerhandler); fClose($infohandler); // und nach der Nutzung, die Verbindung beenden $dbh = null; ?> setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); //echo "Connected successfully\n"; } catch(PDOException $e) { echo "Connection failed: " . $e->getMessage(); } // Abfrage definieren $sql = "SHOW DATABASES;"; $stmt = $link->query($sql); $row_count = $stmt->rowCount(); //echo $row_count.' rows selected'; $results = $stmt->fetchAll(PDO::FETCH_ASSOC); //echo var_export($results); $ausgabe = ""; foreach ($results as $a) { foreach ($a as $key => $value) { //echo $key . " = " . $value . "\n"; //echo $value[$key] . "\n"; $ausgabe .= $key . " = " . $value . "\n"; //$ausgabe .= $value[$key] . "\n"; } } //echo "--------------------------------------------------------------------------------\n"; echo $ausgabe; ?> > php db-test_pdo.php 192.168.0.10 3306 root geheim Database = information_schema Database = meinedb Database = mysql Database = performance_schema setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); //echo "Connected successfully\n"; } catch(PDOException $e) { echo "Connection failed: " . $e->getMessage(); } // Abfrage definieren $sql = "SHOW TABLES;"; $stmt = $link->query($sql); $row_count = $stmt->rowCount(); //echo $row_count.' rows selected'; $results = $stmt->fetchAll(PDO::FETCH_ASSOC); //echo var_export($results); $ausgabe = ""; foreach ($results as $a) { foreach ($a as $key => $value) { //echo $key . " = " . $value . "\n"; //echo $value[$key] . "\n"; $ausgabe .= $key . " = " . $value . "\n"; //$ausgabe .= $value[$key] . "\n"; } } //echo "--------------------------------------------------------------------------------\n"; echo $ausgabe; ?> > php db-test_pdo.php 192.168.0.10 3306 root geheim meinedb Tables_in_meinedb = name Tables_in_meinedb = vorname Tables_in_meinedb = geburtstag === PHP-Script um auf eine MS-SQL-Datenbank zuzugreifen === Damit der DB-Zugriff per ''PHP 7.2'' funktioniert, müssen die verwendeten Benutzer mit "''mysql_native_password''" angelegt worden sein: > echo "CREATE USER dbbenutzer IDENTIFIED WITH mysql_native_password BY 'geheim' ; GRANT SELECT ON *.* TO 'dbbenutzer'@'%'; FLUSH PRIVILEGES;" | mysql **Die Funktion ''mssql_connect'' wurde mit PHP Version 7 entfernt!** getMessage()); } // die Tabellen anzeigen lassen $stmt = $connection->prepare('SELECT * FROM sys.Tables;'); $stmt->execute(); // alles anzeigen $allResults = $stmt->fetchAll(); //print_r($allResults); foreach($allResults as $key=>$val){ print ($val["name"] . "\n"); } // alles wieder zu machen mssql_free_result($stmt); mssql_free_result($allResults); mssql_close($connection); ?> Beispiel: > php mssql_show.php dblib Benutzer geheimesPasswort 192.168.0.33 49411 DatenbankName query($sql) as $row) { echo "| " . $row['database_id'] . " | " . $row['create_date'] . " | " . $row['name'] . " |" . "\n"; } // und nach der Nutzung, die Verbindung beenden $dbh = null; exit(); ?> === MySQL-Datenbankzugriff über eine per SSL/TLS verschlüsselte Verbindung === [[::Datenbankverbindungen zu einer MySQL mit SSL-Verschlüsselung]] ===== PHP-Script um Spammer zu finden ===== Um einen Spammer zu finden, der per PHP-Befehl Mails versendet, gibt es einen einfachen Trick - man verwendet ein Handlerscript. Man lässt die Mails von PHP nicht direkt an sendmail senden, sondern an ein Script, welches zuerst einen Syslog-Eintrag vornimmt und dann die Mail an sendmail weitergibt. Dabei setzt das Script vor die Mail (also als erste Headerzeile) eine Zeile, die den Web-User enthält. So kann man sowohl im Syslog-Logfile zählen, wer wie viele Mails verschickt wie auch im Header der Mail bei Abuse-Beschwerden sehen, wer die Nachrichten versendet hat. Folgendes Script kann hier eingesetzt werden: --------------------------------------------- #!/bin/bash logger -t sendmail-php -- Message sent from $1 &> /dev/null ( echo "X-ConfixxWeb: $1" cat ) | /usr/sbin/sendmail -t -i Das Script wird unter /usr/sbin/sendmail-php gespeichert und mit chmod 755 /usr/sbin/sendmail-php ausführbar gemacht. Nun muss man noch dafür sorgen, dass PHP nicht mehr sendmail nutzt, sondern sendmail-php. Dies lässt sich bei Systemen ohne Confixx in den VirtualHost Einstellungen von Apache machen: ... php_admin_value sendmail_path "/usr/sbin/sendmail-php www1" Auf Rechnern mit Confixx lässt sich das für mehrere User gleichzeitig setzen, wenn man folgende Zeile bei httpd-specials für den User setzt: php_admin_value sendmail_path "/usr/sbin/sendmail-php ##user##" Die Funktion kann man testen, indem man folgendes PHP-Script in ein Webverzeichnis setzt und per http aufruft: Die Nachricht wurde versendet."; ?> Dies sollte folgenden Eintrag im Syslog (/var/log/syslog oder bei Suse /var/log/messages) ergeben: Jun 30 18:00:00 hostname sendmail-php: Message sent from www1 Einen Ueberblick erhä man schnell durch folgendes Kommando: cat /var/log/syslog | grep sendmail-php Weiterhin sollte die Nachricht direkt unter den Received Zeilen folgenden Header enthalten: X-ConfixxWeb: www1 Spamnachrichten lassen sich damit schnell einem User zuordnen. Mit folgendem Kommando lä sich herausfinden, welcher User laut aktuellem Syslog wie viele Nachrichten versendet hat: grep sendmail-php /var/log/syslog | awk '{print $9}' | sort | uniq -c | sort -n ===== PHP-Script um das Format von Bildern zu ermitteln ===== * [[dateinamen_und_verzeichnisnamen_automatisiert_aendern#home_bin_bildformatphp|/home/bin/bildformat.php]] ==== /home/bin/bildformat.php ==== #!/bin/php ==== Beispiel ==== Damit dieses Script unter FreeBSD genauso funktioniert, wie unter Linux, muss ein symbolischer Link angelegt werden: # ln -s /usr/local/bin/php /bin/ So benutzt man das Script: # /home/bin/bildformat.php fotos/Bild_0001.jpg 2272x1704 ===== Array in einen String umwandeln und dann mit SED und GREP bearbeiten ===== ==== Aufgabenstellung ==== Im Array "$_SERVER" findet sich die folgende Zeichenkette: ["QUERY_STRING"]=> string(743) "ceph_storage_id=1&pool_name=erster-pool&lunsmax=8&lunssort=pool_lun_name&lunsorder=ASC&lunsoffset=0&lunslimit=20&pool_lun_snap_name=test1_lun.20180813125125&ceph_storage_id=1&pool_name=erster-pool&pool_lun_name=test1_lun&pool_lun_snap_name=test1_lun.20180813125125&action=takesnap&identifier%5B%5D=test1_lun&pool_lun_snap_name=test2_lun.20180813125125&identifier%5B%5D=test2_lun&pool_lun_snap_name=test3_lun.20180813125125&pool_lun_snap_name=test4_lun.20180813125125&pool_lun_snap_name=test5_lun.20180813125125&pool_lun_snap_name=test6_lun.20180813125125&pool_lun_snap_name=test7_lun.20180813125125&pool_lun_snap_name=test8_lun.20180813125125" In dieser Zeichenkette gibt es die beiden Schlüsselwörter "pool_lun_name" und "pool_lun_snap_name". Leider ist das Schlüsselwort "pool_lun_snap_name" mehrfach vorhanden, so das dieser Schlüssel immer den letzten Wert haben würde, wenn man dieses String in ein Array umwandeln würde. Um den richtigen Wert von den 5 "pool_lun_snap_name"-Schlüsseln zu ermitteln, brauchen wir erst den Wert des Schlüssels "pool_lun_name". Der richtige Wert bzw. der gesuchte Wert von "pool_lun_snap_name" beinhaltet im ersten Teil den kompletten Wert von "pool_lun_name". Zum Beispiel pool_lun_name=test1_lun pool_lun_snap_name=test1_lun.20180813125125 Also wird der "pool_lun_snap_name"-Wert gesucht, der mit "test1_lun" (Wert vom "pool_lun_name"-Schlüssel) gefolgt von einem "." anfängt. ==== Lösung ==== _SERVER: array(60) { ["HTTPS"]=> string(2) "on" ["SSL_SERVER_S_DN_CN"]=> string(9) "hostname" ["SSL_SERVER_I_DN_CN"]=> string(20) "Puppet CA: hostname" ["SSL_VERSION_INTERFACE"]=> string(13) "mod_ssl/2.4.7" ["SSL_VERSION_LIBRARY"]=> string(14) "OpenSSL/1.0.1f" ["SSL_PROTOCOL"]=> string(7) "TLSv1.2" ["SSL_SECURE_RENEG"]=> string(4) "true" ["SSL_COMPRESS_METHOD"]=> string(4) "NULL" ["SSL_CIPHER"]=> string(27) "ECDHE-RSA-AES128-GCM-SHA256" ["SSL_CIPHER_EXPORT"]=> string(5) "false" ["SSL_CIPHER_USEKEYSIZE"]=> string(3) "128" ["SSL_CIPHER_ALGKEYSIZE"]=> string(3) "128" ["SSL_CLIENT_VERIFY"]=> string(4) "NONE" ["SSL_SERVER_M_VERSION"]=> string(1) "3" ["SSL_SERVER_M_SERIAL"]=> string(2) "02" ["SSL_SERVER_V_START"]=> string(24) "Jun 1 09:00:00 2015 GMT" ["SSL_SERVER_V_END"]=> string(24) "Jun 2 09:00:00 2020 GMT" ["SSL_SERVER_S_DN"]=> string(12) "CN=hostname" ["SSL_SERVER_I_DN"]=> string(23) "CN=Puppet CA: hostname" ["SSL_SERVER_A_KEY"]=> string(13) "rsaEncryption" ["SSL_SERVER_A_SIG"]=> string(23) "sha256WithRSAEncryption" ["SSL_SESSION_ID"]=> string(64) "e7lb7l4938558ld33da984ldl42c99f56286ffb25lef95298496f770lb6a7959" ["SSL_SESSION_RESUMED"]=> string(7) "Resumed" ["HTTP_HOST"]=> string(10) "10.10.10.100" ["HTTP_USER_AGENT"]=> string(76) "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:61.0) Gecko/20100101 Firefox/61.0" ["HTTP_ACCEPT"]=> string(63) "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" ["HTTP_ACCEPT_LANGUAGE"]=> string(35) "de-DE,de;q=0.8,en-US;q=0.5,en;q=0.3" ["HTTP_ACCEPT_ENCODING"]=> string(17) "gzip, deflate, br" ["HTTP_REFERER"]=> string(349) "https://10.10.10.100/der/pfad/zum/skript.php?strMsg=Liste+der+Luns+auf+erster-pool+im+Ceph-Pool+1%3Cbr%3E%3Cpre%3E%3Cb%3EEs+gibt+keine+Snapshots.%0A%3C%2Fb%3E%3C%2Fpre%3E%2Ftmp%2Fceph-storage-manager%2F3961498%2F0.ceph.lun.listsnap¤ttab=tab0&redirect=yes&action=listsnap&ceph_storage_id=1&pool_name=erster-pool" ["HTTP_COOKIE"]=> string(48) "phplm_expand=menu2_30|menu2_31|; phplm_collapse=" ["HTTP_DNT"]=> string(1) "1" ["HTTP_CONNECTION"]=> string(10) "keep-alive" ["HTTP_UPGRADE_INSECURE_REQUESTS"]=> string(1) "1" ["PATH"]=> string(60) "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" ["SERVER_SIGNATURE"]=> string(71) " Apache/2.4.7 (Ubuntu) Server at 10.10.10.100 Port 443 " ["SERVER_SOFTWARE"]=> string(21) "Apache/2.4.7 (Ubuntu)" ["SERVER_NAME"]=> string(10) "10.10.10.100" ["SERVER_ADDR"]=> string(10) "10.10.10.100" ["SERVER_PORT"]=> string(3) "443" ["REMOTE_ADDR"]=> string(9) "10.10.10.17" ["DOCUMENT_ROOT"]=> string(8) "/var/www" ["REQUEST_SCHEME"]=> string(5) "https" ["CONTEXT_PREFIX"]=> string(0) "" ["CONTEXT_DOCUMENT_ROOT"]=> string(8) "/var/www" ["SERVER_ADMIN"]=> string(19) "webmaster@localhost" ["SCRIPT_FILENAME"]=> string(67) "/var/www/der/pfad/zum/skript.php" ["REMOTE_PORT"]=> string(5) "33266" ["REMOTE_USER"]=> string(7) "benutzer" ["AUTH_TYPE"]=> string(5) "Basic" ["GATEWAY_INTERFACE"]=> string(7) "CGI/1.1" ["SERVER_PROTOCOL"]=> string(8) "HTTP/1.1" ["REQUEST_METHOD"]=> string(3) "GET" ["QUERY_STRING"]=> string(743) "ceph_storage_id=1&pool_name=erster-pool&lunsmax=8&lunssort=pool_lun_name&lunsorder=ASC&lunsoffset=0&lunslimit=20&pool_lun_snap_name=test1_lun.20180813125125&ceph_storage_id=1&pool_name=erster-pool&pool_lun_name=test1_lun&pool_lun_snap_name=test1_lun.20180813125125&action=takesnap&identifier%5B%5D=test1_lun&pool_lun_snap_name=test2_lun.20180813125125&identifier%5B%5D=test2_lun&pool_lun_snap_name=test3_lun.20180813125125&pool_lun_snap_name=test4_lun.20180813125125&pool_lun_snap_name=test5_lun.20180813125125&pool_lun_snap_name=test6_lun.20180813125125&pool_lun_snap_name=test7_lun.20180813125125&pool_lun_snap_name=test8_lun.20180813125125" ["REQUEST_URI"]=> string(803) "/der/pfad/zum/skript.php?ceph_storage_id=1&pool_name=erster-pool&lunsmax=8&lunssort=pool_lun_name&lunsorder=ASC&lunsoffset=0&lunslimit=20&pool_lun_snap_name=test1_lun.20180813125125&ceph_storage_id=1&pool_name=erster-pool&pool_lun_name=test1_lun&pool_lun_snap_name=test1_lun.20180813125125&action=takesnap&identifier%5B%5D=test1_lun&pool_lun_snap_name=test2_lun.20180813125125&identifier%5B%5D=test2_lun&pool_lun_snap_name=test3_lun.20180813125125&pool_lun_snap_name=test4_lun.20180813125125&pool_lun_snap_name=test5_lun.20180813125125&pool_lun_snap_name=test6_lun.20180813125125&pool_lun_snap_name=test7_lun.20180813125125&pool_lun_snap_name=test8_lun.20180813125125" ["SCRIPT_NAME"]=> string(59) "/der/pfad/zum/skript.php" ["PHP_SELF"]=> string(59) "/der/pfad/zum/skript.php" ["PHP_AUTH_USER"]=> string(7) "benutzer" ["PHP_AUTH_PW"]=> string(10) "geheim" ["REQUEST_TIME_FLOAT"]=> float(1534158435.146) ["REQUEST_TIME"]=> int(1534158435) } aus dem Array "$_SERVER" wird der String von "QUERY_STRING" in ein Array umgewandelt, in dem die Werte für //Key// und //Value// zusammen als //Value// eingetragen werden: $server_query_array = explode('&', $_SERVER['QUERY_STRING']); das eben erzeugte Array wird in einen String umgewandelt: $server_query_string = implode('&', $server_query_array); in dem String werden die "&" gegen " " (Leerzeichen) ausgetauscht: $neuer_string = preg_replace("/[&]/", " ", $server_query_string); hier definieren wir eine Zeichenfolge, nach der wir suchen werden: $pattern = 'pool_lun_name'; hier ermitteln wir die Position, an der das Suchmuster beginnt: $pool_lun_name_pos = strpos($neuer_string, "$pattern="); hier ermitteln wir, an welcher stelle der Wert nach dem Suchmuster zuende ist: $pool_lun_name_end = strpos($neuer_string, " ", $offset = $pool_lun_name_pos); hier wird das gesuchte Schlüsselwort (Suchmuster) mit seinem Wert ermittelt: $pool_lun = trim(substr($neuer_string, $pool_lun_name_pos, $pool_lun_name_end - $pool_lun_name_pos)); hier wird aus der gefundenen Zeichenfolge nur der Wert gespeichert: $pool_lun_name = preg_replace("/pool_lun_name[=]/", "", $pool_lun); jetzt können wir endlich nach dem richtigen Wert der 5 gleichen Schlüsselwörter suchen, hier wird die Startposition davon abgespeichert: $pool_lun_snap_name_pos = strpos($neuer_string, "=$pool_lun_name."); hier wird die Endposition des gesuchten Wertes abgespeichert: $pool_lun_snap_name_end = strpos($neuer_string, " ", $offset = $pool_lun_snap_name_pos); hier schneiden wir uns aus der gespeicherten Zeichenkette den Wert aus, den wir letztendlich gesucht haben: $pool_lun_snap_name = trim(substr($neuer_string, $pool_lun_snap_name_pos + "1", $pool_lun_snap_name_end - $pool_lun_snap_name_pos)); echo $pool_lun_snap_name; wir wollen die 3 Zeichen "xyz" haben, die unmittelbar vor einer bekannten Zeichenkette ":abc defg:" im "$datensatz" stehen $string_pos = strpos($datensatz, ':abc defg:'); $gesuchter_string = trim(substr($datensatz, $string_pos - 3, 3)); bei "... xyz:abc defg: ..." ist die Zeichenkette "xyz" gesucht aber nur ":abc defg:" ist bekannt. ===== ein kleines Beispiel ===== [[https://192.168.1.80/openqrm/base/server/konfig_mgmt/konfigurations-management.php?konfig_mgmt=ja]] #!/bin/bash #------------------------------------------------------------------------------# # # Status melden # #------------------------------------------------------------------------------# if [ "x${1}" != "x" ] ; then echo "$(date +'%F %T'): Status = '${1}'" >> /tmp/konfigurations_management.log fi $value) { if (strncmp($key, "konfig_mgmt") == 0) { $status .= $value; } } //echo "1: " . $status . "
"; //print "2: " . $status . "
"; //print_r("3: " . $status . "
"); //print "/usr/lib/cgi-bin/konfigurations_management.sh " . $status . "
"; // // Variablen-Inhalt einem SHELL-Script übergeben // $KOMMANDO1 = "/usr/lib/cgi-bin/konfigurations_management.sh " . $status; // // SHELL-Kommando ausführen // echo shell_exec("$KOMMANDO1;"); ?> openQRM Konfigurations-Management Status
> cat /tmp/konfigurations_management.log ===== Zeichenketten mit PHP verschlüsseln ===== Vorher muß das Paket ''php-cli'' (z.B.: ''apt install php7.4-cli'') installiert werden. ==== Vorbereitung für das Beispiel ==== als erstes benötigen wir ein RSA-Schlüsselpaar: > openssl genrsa -out openssl_private_key.pem 4096 > openssl rsa -in openssl_private_key.pem -out openssl_public_key.pem -outform PEM -pubout ==== ein einfaches Beispiel ==== > php /tmp/php_openssl_verschl.php > ls -lha verschluesselt.txt -rw-rw-r-- 1 fritz fritz 684 Jun 9 17:03 verschluesselt.txt > php /tmp/php_openssl_entschl.php Hallo Welt! //In diesem Beispiel wird, mit dem ersten Aufruf, die Zeichenkette "''Hallo Welt!''", verschlüsselt, in eine Datei geschrieben. Und mit dem zweiten Aufruf wird der Inhalt der Datei wieder entschlüsselt und ausgegeben.// ==== Ein- und Ausgabe soll über jeweils eine Datei laufen ==== > echo "Hallo Welt!" > entschluesselt.txt > php /tmp/php_openssl_verschl.php > ls -lha verschluesselt.txt -rw-rw-r-- 1 fritz fritz 684 Jun 9 17:24 verschluesselt.txt > rm entschluesselt.txt > php /tmp/php_openssl_entschl.php > cat entschluesselt.txt ; echo Hallo Welt!