seeseekey.net - Invictus Deus Ex Machina

Wenn man frü­her unter PHP eine MySQL-Datenbank anspre­chen wollte, so bediente man sich der Befehle mysql_connect, mysql_select_db, mysql_query und Co. Das Pro­blem an die­ser API ist, das sie depre­ca­ted also ver­al­tet ist und damit nicht mehr genutzt wer­den sollte:

$db = mysql_connect ($host, $user, $password) or die ("Es konnte keine Verbindung zum Datenbankserver hergestellt werden");
mysql_query("SET NAMES 'UTF8'");
mysql_select_db ($name, $db) or die("Die Datenbank \"$name\" konnte nicht ausgewählt werden");

Statt­des­sen soll man die MySQL Impro­ved Exten­sion kurz Mys­qli nut­zen. Dabei han­delt es sich um eine moderne objekt­ori­en­tierte API für den Zugriff auf MySQL in PHP. Eine ein­fa­che Abfrage mit­tels Mys­qli sieht dabei wie folgt aus:

$mysqli = new mysqli($databaseHost, $databaseUsername, $databasePassword, $databaseName);
$sql = "SELECT * FROM token";
$result = $mysqli->query($sql);

for ($row_no=$result->num_rows-1; $row_no>=0; $row_no--) 
{
    $result->data_seek($row_no);
    $row=$result->fetch_assoc();
    echo " id = " . $row['id'] . "\n";
}

Die API unter­schei­det sich dabei nicht groß von der alten API, so das Umstieg hier rela­tiv ein­fach fal­len sollte. Auf der ent­spre­chen­den Doku­men­ta­ti­ons­seite auf php.net fin­den sich noch viele wei­tere Beispiele.

Bei einer ownCloud-Instanz wel­che schon einige Betriebs­stun­den auf dem Buckel hat, kann es zu einem unschö­nen Effekt kom­men. Beim Ver­such den Papier­korb über die Funk­tion „Gelöschte Dateien“ zu lee­ren, ver­sucht own­Cloud alle Dateien auf­zu­lis­ten, was aller­dings nicht gelingt. Der Brow­ser friert ein und das Lee­ren des Papier­kor­bes ist nicht möglich.

Der But­ton um die gelösch­ten Dateien aufzurufen

Auch wenn das Lee­ren des Papier­kor­ber nach Mei­nung der ownCloud-Entwickler nicht not­wen­dig ist, da die Dateien nach einer Weile weg­ge­wor­fen wer­den, sollte es trotz­dem eine Lösung geben um den Papier­korb manu­ell zu lee­ren. Ein Work­ar­round ist es den Papier­korb direkt zu löschen in dem man das Ver­zeich­nis „owncloud/data/username/files_trashbin/ löscht. Anschlie­ßend müs­sen noch zwei Tabel­len in der Daten­bank berei­nigt werden:

TRUNCATE TABLE oc_files_trashsize;
TRUNCATE TABLE oc_files_trash;

Eine wei­tere Mög­lich­keit diese Pro­ble­ma­tik zu ent­schär­fen, ist es die Vor­hal­te­zeit von gelösch­ten Dateien von 180 Tagen auf 30 Tage zu redu­zie­ren. Dazu öff­net man die config.php Datei wel­che im config-Ordner zu fin­den ist und trägt fol­gen­den Wert ein:

'trashbin_retention_obligation' => 30,

Damit wird ver­hin­dert das sich zu viele Dateien im Papier­korb ansam­meln und das Pro­blem deut­lich entschärft.

Wenn man sich die Media­Wiki „user“-Tabelle anschaut, so wird man fest­stel­len das die Nut­zer­na­men mitt­ler­weile als „var­bi­nary“ gespei­chert wer­den. Im Gegen­satz zur frü­he­ren Vari­ante las­sen sich die Namen damit nicht mehr im Klar­text lesen.

Ein Aus­zug aus der „user“-Tabelle

Möchte man die Namen im Klar­text anzei­gen, so ist dies mit fol­gen­dem SQL Befehl möglich:

SELECT CAST(user_name AS CHAR) from user

Die Aus­gabe besteht dabei aus allen Nut­zer­na­men in ihrer Klartextform.

In den letz­ten Jah­ren sind sie aus dem Boden geschos­sen, soge­nannte „Read it later“-Dienste. Diese Dienste spei­chern dabei Arti­kel wel­che man erst spä­ter lesen möchte. Mög­lich wird dies durch Book­marklets, Add-Ons und Apps wel­che die jewei­li­gen Arti­kel zum ent­spre­chen­den „Read it later“-Dienst schie­ben. Mit der freien Soft­ware walla­bag, wel­che frü­her unter dem Namen poche bekannt war, kann man einen sol­chen Dienst sel­ber hosten.

Die Login-Seite von wallabag

walla­bag setzt auf PHP auf und ist unter der „DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE“ lizen­siert, und damit freie Soft­ware, wie man dem Lizenz­text ent­neh­men kann:

            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
                    Version 2, December 2004

 Copyright (C) 2004 Sam Hocevar 

 Everyone is permitted to copy and distribute verbatim or modified
 copies of this license document, and changing it is allowed as long
 as the name is changed.

            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

  0. You just DO WHAT THE FUCK YOU WANT TO.

Wich­tig ist nur das der Name der Appli­ka­tion geän­dert wird, wenn man diese for­ken möchte. walla­bag kann auf der offi­zi­el­len Seite des Pro­jek­tes unter www.wallabag.org bezo­gen werden.

Möchte man unter Win­dows eine ent­fernte MySQL-Datenbank anspre­chen, so kann man hier­für Hei­diSQL nut­zen. Mit der Soft­ware Sequel Pro gibt es so etwas ähn­li­ches für Mac OS X. Die Soft­ware kann dabei auf der offi­zi­el­len Seite bezo­gen wer­den.

Sequel Pro

Sequel Pro ist unter der MIT-Lizenz ver­füg­bar und somit freie Soft­ware. Der Quell­text ist auf Google Code zu fin­den. Er kann mit­tels eines SVN Cli­ent aus­ge­checkt werden:

svn checkout http://sequel-pro.googlecode.com/svn/trunk/ sequel-pro

Eine Alter­na­tive zu Sequel Pro ist das platt­form­über­grei­fende MySQL Work­bench, bei wel­chem es sich eben­falls um freie Soft­ware handelt.

Wenn man das ownCloud-Passwort ändern möchte, so kann man dies über die „Pass­wort vergessen?“-Funktion zurück­set­zen. Wenn dies nicht mehr mög­lich ist, so kann das ganze auch in der Daten­bank erle­digt werden:

UPDATE `oc_users` SET `password`=SHA1('geheim') WHERE `uid`='nutzername'

Da die Pass­wör­ter mit einem Salt und mit­tels SHA1 gehasht gespei­chert wer­den, muss das neue Pass­wort auch gehasht wer­den. Dies erle­digt die Datenbank-Funktion „SHA1“ für uns. Nach­dem das Pass­wort zurück­ge­setzt wurde, sollte das Pass­wort nach dem Login über die „Persönlich“-Seite erneut geän­dert wer­den, damit wie­der ein Salt für sel­bi­ges gene­riert wird.

Möchte man mit­tels „mys­qldump“ die ein­zel­nen Daten­ban­ken einer MySQL-Installation siche­ren, so sähe das so für eine Daten­bank in etwa so aus:

mysqldump -u root -p<passwort> --result-file=example.sql --databases example

Packt man das nun ein Skript, muss jede Tabelle von Hand in die­ses Skript ein­tra­gen wer­den. Aller­dings könnte man das ganze auch über den SQL Befehl „SHOW DATABASES“ lösen und das ganze in ein auto­ma­ti­sches Skript gie­ßen. Auf der Web­seite dev.mensfeld.pl fin­det man ein sol­ches Skript. Ich habe das ganze klei­ne­ren Modi­fi­ka­tio­nen unter­zo­gen (so wird z.B. die „performance_schema“ Tabelle nicht mit­ge­si­chert) und auf Git­Hub zur Ver­fü­gung gestellt.

Unter Linux kann man mittels

mysqldump -u root -p<Passwort> --all-databases --result-file=dump.sql

alle MySQL Daten­ban­ken in eine SQL Datei sichern. Aller­dings kann es unter Umstän­den pas­sie­ren, das man fol­gende Mel­dung bekommt:

mysqldump: Got error: 1449: The user specified as a definer ('u123456789'@'%') does not exist when using LOCK TABLES

Ein Work­ar­round wäre es das ganze mit dem Para­me­ter „–lock-tables=false“ aufzurufen:

mysqldump -u root -p<Passwort> --all-databases --result-file=dump.sql

Aller­dings behan­delt dies nur die Sym­ptome. Um das Pro­blem zu lösen wird im ers­ten Schritt der feh­lende Nut­zer angelegt.

GRANT ALL ON *.* TO 'u123456789'@'%' IDENTIFIED BY 'passwort';

Meist ist ein View oder eine Sto­ra­ged Pro­ce­dure in wel­cher der nicht exis­tie­rende Nut­zer defi­niert wurde, wie in die­sem Beispiel:

ALTER ALGORITHM=UNDEFINED DEFINER=`u123456789`@`%` SQL SECURITY DEFINER VIEW `mana_v_online_chars` AS select `l`.`char_id` AS `char_id`,`l`.`login_date` AS `login_date`,`c`.`user_id` AS `user_id`,`c`.`name` AS `name`,`c`.`gender` AS `gender`,`c`.`level` AS `level`,`c`.`map_id` AS `map_id` from (`mana_online_list` `l` join `mana_characters` `c` on((`l`.`char_id` = `c`.`id`)))

Nach­dem der View kor­ri­giert wurde, in dem dort ein gül­ti­ger Nut­zer ange­ge­ben wurde, kann der tem­po­rär ange­legte Nut­zer ent­fernt werden.

Mit­tels Nginx ist ein Web­ser­ver mit PHP und MySQL in ein paar Minu­ten ein­ge­rich­tet. Dazu instal­liert man unter Ubuntu fol­gende Pakete:

sudo apt-get install mysql-server nginx php5-fpm php5-curl php5-gd php5-imap php5-mysql

Nach der Instal­la­tion der nöti­gen Pakete geht es an die grund­le­gende Kon­fi­gu­ra­tion des Webserver:

mkdir -p /var/www/example.org/root
mkdir -p /var/www/example.org/test
cd /var/www
chown -R www-data:www-data . 
usermod -a -G www-data nutzername

In die­sem Bei­spiel soll die Domain „example.org“ sowie die Sub­do­main „test.example.org“ ein­ge­rich­tet wer­den. Des­halb legen wir zwei Ord­ner an. Anschlie­ßend tei­len wir Nginx mit, wel­che Domains und Sub­do­mains der Web­ser­ver ver­wal­ten soll. Dazu legen wir die Datei „/etc/nginx/sites-available/example“ an und fül­len diese mit fol­gen­dem Inhalt:

server {
        listen   80;
        listen [::]:80;

        root /var/www/example.org/root;
        index index.php index.html index.htm;
 
        server_name .example.org;

        location ~ \.php$ {
                fastcgi_pass unix:/var/run/php5-fpm.sock;
                fastcgi_index index.php;
                include fastcgi_params;
        }
}

server {
        listen   80;
        listen [::]:80;

        root /var/www/example.org/test;
        index index.php index.html index.htm index.php; 

        server_name test.example.org;

        location / {
            auth_basic "Access denied";
            auth_basic_user_file /var/www/example.org/root/.htpasswd;

            autoindex on;
        }

        location ~ \.php$ {
                fastcgi_pass unix:/var/run/php5-fpm.sock;
                fastcgi_index index.php;
                include fastcgi_params;
        }
}

Im ers­ten Block wird die Domain „example.org“ defi­niert und kon­fi­gu­riert. Durch die Nota­tion „.example.org“ wird Nginx ange­wie­sen, jede Sub­do­main wel­che nicht defi­niert ist, auf die Haupt­seite umzu­lei­ten. Für die Domain „test.example.org“ wurde außer­dem ein Pass­wort­schutz ange­legt und die Ver­zeich­nis­an­sicht akti­viert. Damit die Kon­fi­gu­ra­tion auch aktiv wer­den kann, muss eine sym­bo­li­sche Ver­knüp­fung in das Ver­zeich­nis „/etc/nginx/sites-enabled“ ange­legt werden:

ln -s /etc/nginx/sites-available/example /etc/nginx/sites-enabled/example

Die beste­hende „default“-Datei im „sites-enabled“ Ord­ner ent­hält eine Bei­spiel­kon­fi­gu­ra­tion. Diese kann ent­wer­der ent­fernt wer­den oder kon­fi­gu­riert werden:

server {
        listen   80 default_server;
        listen [::]:80 default_server ipv6only=on;

        root /var/www/default/root;
        index index.php index.html index.htm;
 
        server_name _;
}

Mit die­ser Kon­fi­gu­ra­tion wird jede Seite auf Default umge­lei­tet, wel­che nicht in ande­ren Kon­fi­gu­ra­tio­nen auf­taucht. Nun muss nur noch der Web­ser­ver (und des PHPs Moduls) neu­ge­star­tet werden:

service nginx restart
service php5-fpm restart

Ist der Ser­ver bereits online, reicht es auch die Kon­fi­gu­ra­tion neuzuladen:

service nginx reload

Soll­ten wäh­rend der Kon­fi­gu­ra­tion Feh­ler auf­tre­ten, so hilft ein Blick in das ent­spre­chende Log:

cat /var/log/nginx/error.log

Benö­tigt man eine Daten­bank für die gewünschte Web­an­wen­dung, so muss diese in die SQL Daten­bank ein­ge­spielt wer­den. Ist alles rich­tig kon­fi­gu­riert wor­den, läuft der Web­ser­ver auf Port 80 und war­tet auf erste Anfragen.