====== 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!