Skip to content

freiesMagazin für 09/2015 erschienen

Gestern ist die September Ausgabe (09/2015) vom freiesMagazin erschienen,
hier mal ein kurzer Überblick über die Themen, die Ausgabe könnt ihr über den oberen Link in verschiedenen Versionen downloaden.

Inhalt der Ausgabe
* Fedora 22
* OpenBSD – Einmal Kugelfisch, bitte.
* Projektvorstellung: Distrochooser
* Der August im Kernelrückblick
* Spiele-Kurzvorstellung aus dem Humble PC & Android Bundle 13
* Review: bq Aquaris E5 – Ubuntu Edition
* Rezension: Python GE-PACKT
* Rezension: Das Sketchnote-Handbuch
* Rezension: PHP 5.6 und MySQL
* Rezension: Meteor
* Rezension: NFC mit Android und Arduino
* Leserbriefe und Veranstaltungen

simpler Counter mit mySQL

Dieses Tutorial beschreibt, wie ihr einen simplen Counter mit mySQL realisieren könnt.
Wenn ich simpel meine, meine ich auch simpel.
Erzählt nur die täglichen Aufrufe und hat eine IP Sperre mehr nicht ;-)

Das Skript besteht aus 2 Dateien die benötigt werden und 1 Installationsdatei,
die nach das Ausführung gelöscht werden muss !!

counter-config.php
In dieser nehmen wir die Einstellungen für die Datenbankverbindung vor,
sowie das Präfix für die Tabellen und die Reloadsperre

<?php
  $myCounter['dbhost'] = 'localhost'; // Datenbank Host (meist localhost)
  $myCounter['dbuser'] = 'tutorials'; // Datenbank Benutzer
  $myCounter['dbpass'] = 'foobar'; // Datenbank Passwort
  $myCounter['dbname'] = 'tutorials'; // Datenbank Name
  $myCounter['prefix'] = 'counter_'; // Vorsilbe fuer die Tabellen
  $myCounter['reload'] = 86400; // Reloadsperre bevor die IP erneut gezaehlt wird
?>


counter-call.php
Dieses Skript wird in die Anwendung einfach eingebaut, damit werden die Aufrufe gezählt.
So als erstes wird eine Variable $myMainPath erzeugt, diese enthält den absoluten Pfad
zur counter-call.php daraus extrahieren wird den Verzeichnisnamen mit dirname ( )
dadurch kann von überall aus die Datei eingebunden werden, ohne das ein Pfad übergeben werden muss
zur Konfigurationsdatei.

Als nächsten Schritt verbinden wir uns mit der Datenbank.
Jetzt folgt der eigentliche Counter:
Mittels des SELECT Statements ermitteln wir, ob die IP bereits innerhalb von $myCounter['reload'] gezählt wurde.
Wer sich nun über die Angabe INET_ATON wundert, damit wird die IP-Adresse von einem String ( z.B.: 127.0.0.1 )
in einen Integer ( z.B. 2130706433 ) umgewandelt.

Dies hat den Vorteil eventuelle Indizes werden kompakter und effektiver,
da mit Zahlen effektiver gearbeitet werden kann als mit Strings,
außerdem ist der Speicherverbrauch von int ( 10 ) gerade mal 7 Bytes
während varchar ( 15 ) (mit utf8 Zeichensatz) ganze 20 Bytes benötigt.
Klingt jetzt nicht weiter viel, aber macht sich bei gewissen Mengen durchaus bemerkbar.

So nun folgen 2 INSERT und 1 DELETE-Befehl:
Nun müssen wir den aktuellen Tag anlegen bzw. wenn dieser bereits existiert, den Wert um 1 erhöhen.
Da die Spalte `date` einmalig sein muss, setzen wir einen PRIMARY KEY oder UNIQUE KEY darauf,
nun können wir über ON DUPLICATE KEY UPDATE einen UPDATE Befehl ausführen lassen
und sparen uns damit 1 zusätzliches Statement und einige Codezeilen für die Überprüfung, ob der aktuelle Tag bereits angelegt ist.

Das zweite INSERT Statement hat keine besonderen Merkmale.
So nun zum DELETE Statement, es könnten sich einige Fragen was dieses soll :), nun ganz einfach wir wollen doch keine riesigen IP Tabellen erzeugen,
daher löschen wir einfach alle alten IP Einträge aus der Datenbank, auf die die Reloadsperre nicht mehr zutrifft.

<?php
 $myMainPath = dirname ( <u>_FILE_</u> ) . '/';
 require_once ( $myMainPath . 'counter-config.php' );

 if ( $myCounterConn = @mysql_connect ( $myCounter['dbhost'] , $myCounter['dbuser'] , $myCounter['dbpass'] ) )
 {
  if ( @mysql_select_db ( $myCounter['dbname'] , $myCounterConn ) )
  {
   $reload_query = "SELECT ip FROM `" . $myCounter['prefix'] . "ip`
                     WHERE `ip` = INET_ATON('"
. $_SERVER['REMOTE_ADDR'] . "')
                     AND `time` > '"
. ( time ( ) - $myCounter['reload'] ) . "'";
   $reload_query = mysql_query ( $reload_query );
   if ( mysql_num_rows ( $reload_query ) == 0 )
   {

    mysql_query ( "INSERT INTO `" . $myCounter['prefix'] . "visitor`
                   ( `date` , `visitor` ) VALUES ( '"
. date("ymd") . "', '1' )
                    ON DUPLICATE KEY UPDATE `visitor` = `visitor` + 1"
);

    mysql_query ( "INSERT INTO `" . $myCounter['prefix'] . "ip`
                   ( `ip` , `time` ) VALUES ( INET_ATON('"
. $_SERVER['REMOTE_ADDR'] . "') , '" . time ( ) . "')" );

    mysql_query ( "DELETE FROM `" . $myCounter['prefix'] . "ip` WHERE `time` < '" . ( time ( ) - $myCounter['reload'] ) . "'" );
   }
  }
 }
?>


counter-install.php
Dieses Skript installiert die notwendigen Tabellen, nach der Ausführung muss es auf jedenfall wieder gelöscht werden, da dadurch die Tabellen verworfen werden würden.

<?php
 $myMainPath = dirname ( <u>_FILE_</u> ) . '/';
 require_once ( $myMainPath . 'counter-config.php' );

 if ( $myCounterConn = mysql_connect ( $myCounter['dbhost'] , $myCounter['dbuser'] , $myCounter['dbpass'] ) )
 {
  if ( mysql_select_db ( $myCounter['dbname'] , $myCounterConn ) )
  {

   mysql_query ( "DROP TABLE IF EXISTS `" . $myCounter['prefix'] . "ip`" );
   mysql_query ( "CREATE TABLE IF NOT EXISTS `" . $myCounter['prefix'] . "ip` (
           `ip` int(10) unsigned NOT NULL DEFAULT '0',
           `time` int(10) unsigned NOT NULL DEFAULT '0'
          ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci"
);

   mysql_query ( "DROP TABLE IF EXISTS `" . $myCounter['prefix'] . "visitor`" );

   mysql_query ( "CREATE TABLE IF NOT EXISTS `" . $myCounter['prefix'] . "visitor` (
           `date` mediumint(6) NOT NULL,
           `visitor` smallint(5) unsigned NOT NULL DEFAULT '0',
           PRIMARY KEY (`date`)
          ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci"
);

   echo 'Die Tabellen wurden installiert';

  }
  else
  {

   echo 'Konnte die Datenbank nicht finden';

  }
 }
 else
 {
  echo 'Keine Verbindung zum Server moeglich';
 }
?>


Wie immer übernehme ich keinerlei Haftung für eventuelle Schäden !!

Solltet ihr Verbesserungsvorschläge haben oder Fehler finden, bitte ich um einen kurzen Kommentar, Danke :-)

mySQL Backup mit Hilfe von PHP

Dieses kleine Skript sichert eure Datenbank in eine Datei entweder als normale SQL-Datei oder mit GZip komprimiert.

Ihr müsst lediglich die notwendigen Daten im $myBackup-Array eintragen.

<?php
// mySQL Backup mit Hilfe von PHP
// Licensed under GNU LGPL v3 or later
// Author: Stefan Moosmann
// Homepage: http://www.stefanmoosmann.de/s9y/archives/34-mySQL-Backup-mit-Hilfe-von-PHP.html

$myBackup = array
(
        // Adresse des Datenbankservers (meist localhost)
        'hostname' => 'localhost',

        // Benutzername fuer den Datenbankserver
        'username' => '',

        // Passwort fuer den Datenbankzugang
        'password' => '',

        // Datenbankname
        'database' => '',

        // Tabellen von der Sicherung ausschliessen (nur Struktur wird immer gesichert !!)
        // beim Tabellennamen auf Gross-/Kleinschreibung achten !!
        'notsave' => array ( ),

        // Backup in Datei speichern (bei Komprimierung wird .gz automatisch angehaengt)
        // Sollte den absoluten bzw. relativen Pfad + Dateinamen beinhalten
        'backupfile' => 'backup.sql',

        // Backup Datei mit GZip komprimieren?
        'backupcompress' => true,

        // Daten mit UTF-8 schreiben?
        'backuputf8' => true,
);

mysql_connect ( $myBackup['hostname'] , $myBackup['username'] , $myBackup['password'] );
mysql_select_db ( $myBackup['database'] );

$BackupData  = "-- mySQL Dump\n";
$BackupData .= "-- Host: ".$myBackup['username']."@" . $myBackup['hostname'] . "\n";
$BackupData .= "-- Datenbank: ".$myBackup['database']."\n";
$BackupData .= "-- Erstellungszeit: " . date('d.m.Y H:i:s') . "\n";
$BackupData .= "-- Server Version: " . mysql_get_server_info() . "\n";
$BackupData .= "-- PHP-Version: " . phpversion ( ) . "\n\n";

        $result = mysql_query ( 'SHOW TABLES FROM '.$myBackup['database'] );
        while ( $table = mysql_fetch_row ( $result ) )
        {
                $result_str = mysql_query ( 'SHOW CREATE TABLE `'.$table[0].'`' );
                $structure = mysql_fetch_row ( $result_str );

                $BackupData .= "#\n";
                $BackupData .= "# Struktur von `" . $table[0] . "`\n";
                $BackupData .= "#\n";
                $BackupData .= "DROP TABLE IF EXISTS `" . $table[0] . "`;\n";
                $BackupData .= $structure[1] . ";";
                $BackupData .= "\n\n";

                $BackupData .= "#\n";
                $BackupData .= "# Daten von `" . $table[0] . "`\n";
                $BackupData .= "#\n";

        if ( !in_array ( $table[0] , $myBackup['notsave'] ) )
        {
                $result_data = mysql_query ( 'SELECT * FROM `'.$table[0].'`' );
                while ( $data = mysql_fetch_assoc ( $result_data ) )
                {
                                $insertfull = '';
                                $datastring = '';

                        foreach ( $data as $key => $value )
                        {
                                $insertfull .= '`' . $key . '`,';
                                $datastring .= "'" . addslashes ( $value ) . "',";
                        }
                                $insertfull = '(' . substr ( $insertfull , 0 , -1 ) .')';
                                $datastring = '(' . substr ( $datastring , 0 , -1 ) .')';

                                unset ( $key, $value );

$BackupData .= "INSERT INTO `".$table[0]."` " . $insertfull . " VALUES " . $datastring . ";\n";

                }
        }
        }

if ( $myBackup['backuputf8'] === true ) $BackupData = utf8_encode ( $BackupData );
if ( $myBackup['backupcompress'] === true )
{
        $FileBackup = $myBackup['backupfile'] . '.gz';
        $WriteBackup = gzopen ( $FileBackup , 'w9' );
        gzwrite ( $WriteBackup , $BackupData );
        gzclose ( $WriteBackup );
}
else
{
        $FileBackup = $myBackup['backupfile'];
        $WriteBackup = fopen ( $FileBackup , 'w' );
        fwrite ( $WriteBackup , $BackupData );
        fclose ( $WriteBackup );
}

mysql_close ( );


Das ganze gibt es noch zum Download

Wie immer übernehme ich keinerlei Haftung für eventuelle Schäden !!

Solltet ihr Verbesserungsvorschläge haben oder Fehler finden, bitte ich um einen kurzen Kommentar, Danke :-)

Arbeiten mit mySQL

So nun fangen wir mit mySQL an, die anderen Datenbank-Systeme, wie MSSQL, PostgreSQL, Oracle und wie sie alle heißen, dürften Ähnlichkeiten besitzen, allerdings müssten die Befehle eventuell anders aufgebaut werden.
Naja, wir werden uns nur mit der weitverbreitesten Datenbank mySQL beschäftigen, da diese auf auf fast jedem Webserver mit Linux zu finden ist.

Als erstes müssen wir eine Verbindung zum Datenbank-Server aufbauen, dafür werden 2 Befehle benötigt:

$db=mysql_connect("localhost","user","pass");
mysql_select_db("Datenbank");


Mit mysql_connect wird eine Verbindung zum Datenbank-Server aufgebaut und mit mysql_select_db wird eine Datenbank geöffnet.

mysql_connect erfordert 3 Argumente:
Datenbank-Host meinst localhost
Datenbank-User, wobei der Aufbau beim Confixx immer gleich ist usr_webxx_y
Datenbank-Passwort sollte immer eins vergeben werden, außer wenn man mit XAMPP arbeitet und nur local testet.

mysql_select_db erfordert 1 Argument:
Der Datenbank-Name, man kann nicht auf jede Datenbank zugreifen, da der User die Rechte vorgibt und nur mit diesen Rechten auf eine Datenbank zugegriffen werden kann. Also keine Berechtigung bedeutet in diesem Fall eine Fehlermeldung

So greifen wir mal auf einen Datensatz in der Datenbank zu, dies geschied mit mysql_query und dem mySQL-Befehl Select

Damit es verständlicher wird, bauen wir das ganze nun so auf, die Tabelle (Tabellenname: tabelle) sieht wie folgt aus und beinhaltet 2 Datensätze:
TabellenID | Name | Vorname | Ort
1 | Moosmann | Stefan | Schramberg
2 | Muster | Max | Maxhausen

$db=mysql_connect("localhost","user","pass");
mysql_select_db("Datenbank");
$ergebnis = mysql_query("Select Name,Vorname,Ort from `tabelle` where `TabellenID` = '2' LIMIT 1");


So nun hätten wir eine Abfrage, aber ohne Ausgabe ;-)
mysql_query führt nur den mySQL-Befehl aus und liefert das Ergebnis zurück. So nun zum Befehl:

SELECT Name,Vorname,Ort FROM `tabelle` WHERE `TabellenID` = '2' LIMIT 1


Select liefert die Daten zurück, die Werte zwischen Select und From sind die Spaltennamen man kann diese explizit wählen oder auch mit * alle auswählen, was bei Tabellen mit 4 Spalten nicht viel ausmacht, aber Tabellen mit mehr als 30 Spalten enorme Serverlast erzeugt.
Nach from kommt der Tabellenname, hinter dem Tabellennamen kann entweder ein Limit kommen oder davor noch eine Bedingung mit where gesetzt werden, hier wird eine Bedingung gesetzt das die TabellenID gleich 2 sein muss, dabei wird eigentlich limit nicht benötigt, aber man sollte es vorsichtshalber setzen ;-)
Also erst WHERE, dann LIMIT

So $ergebnis ist ein Array um dieses abzufragen könnte man nun eine for()-Schleife verwenden oder direkt abfragen z.B. $ergebnis[0] (liefert den Namen)

Aber wir machen es anders :-)
$db=mysql_connect("localhost","user","pass");
mysql_select_db("Datenbank");

$ergebnis = mysql_query("Select Name,Vorname,Ort from `tabelle` where `TabellenID` = '2' LIMIT 1;");
if(mysql_num_rows($ergebnis)){
        $ausgabe = mysql_fetch_assoc($ergebnis);
        echo $ausgabe['Vorname']." ".$ausgabe['Name']." ".$ausgabe['Ort'];
} else {
        echo "Kein Datensatz vorhanden";
}


So wir haben nun die Abfrage von oben um 2 neue mySQL-Befehle erweitert:
mysql_num_rows liefert die Anzahl der Zeilen in Verbindung mit einer if-Anweisung kann man eine Meldung erzeugen lassen, wenn kein Datensatz vorhanden ist. if wird nur ausgeführt wenn das Ergebnis true ist, also wenn kein Datensatz vorhanden ist, ist das Ergebnis false und der else-Zweig wird ausgeführt.
So mit mysql_fetch_assoc kann man sich die Daten ausgeben lassen.
$ausgabe[Spaltenname], man kann natürlich den Spaltennamen auch ändern z.B. wenn man bei select Name as Nachname setzt, somit müsste man die Spalte mit dem Namen Nachname aufrufen.
Wenn man mehrere Datensätze nacheinander abrufen möchte, z.B. um Gästebuch-Einträge abzurufen muss man eine Schleife verwenden, hierfür bietet sich die Schleife while mit einem Limit in der Abfrage an.

$db=mysql_connect("localhost","user","pass");
mysql_select_db("Datenbank");

$ergebnis = mysql_query("Select Name,Vorname,Ort from `tabelle` LIMIT 2");
if(mysql_num_rows($ergebnis)){
        while($ausgabe = mysql_fetch_assoc($ergebnis)){
                echo $ausgabe['Vorname']." ".$ausgabe['Name']." ".$ausgabe['Ort']."<br>";
        }
} else {
        echo "Kein Datensatz vorhanden";
}


while läuft solange bis das Array aus der Abfrage fertig ist oder eben, die maximale Ausführzeit von php überschritten wurde (diese liegt meist bei 30 Sekunden).

$db=mysql_connect("localhost","user","pass");
mysql_select_db("Datenbank");

$ergebnis = mysql_query("Select Name,Vorname,Ort from `tabelle` LIMIT 2;");
if(mysql_num_rows($ergebnis)){
        while($ausgabe = mysql_fetch_assoc($ergebnis)){
                echo $ausgabe['Vorname']." ".$ausgabe['Name']." ".$ausgabe['Ort']."<br>";
        }
} else {
        echo "Kein Datensatz vorhanden";
}
mysql_close($db);


So als letztes kommt mysql_close, damit schließen wir nicht nur die offene Datenbank, sondern auch diese Lektion :-D

Nachdem die Grundlagen besprochen wurden, gilt es den wichtigsten Befehlssatz zu erlernen.

SELECT * FROM `tabelle` WHERE `Bedingung` = 'test' LIMIT 1


Mit SELECT startet eine Abfrage von Datensätzen, gefolgt von den Spaltennamen bzw. * für alle Spalten,
durch FROM legen wir fest aus welcher Tabelle gelesen wird.

Die WHERE Bedingung ist optional, es können mehrere Bedingungen mit AND oder OR verbunden werden (AND bindet stärker als OR) und die Bedingungen können nicht nur = (gleich) sein, sondern auch != (nicht gleich), like oder not like.
Bei den letzten zwei Arten sollte mit dem Platzhalter % gearbeitet werden um ein richtiges Ergebnis zu erhalten.

Mit Hilfe von LIMIT werden die Suchergebnisse eingeschränkt oder z.B. bei UPDATE oder DELETE Befehlen die betroffenen Datensätze eingeschränkt.
LIMIT 1 = 1 Datensatz, vom allerersten Datensatz an
LIMIT 1,1 = 1 Datensatz, vom 1 Datensatz (0 wäre der erste Datensatz)

INSERT `tabelle` (`Bedingung`) VALUES ('test')


INSERT fügt einen neuen Datensatz in die Tabelle tabelle ein und belegt die Zelle Bedingungen mit dem Wert test

UPDATE `tabelle` SET `Bedingung` = 'kein Test'


UPDATE ändert den Datensatz, in diesem Beispiel wären alle Daten aus der Tabelle betroffen, es sollte auf jedenfall mit WHERE und LIMIT gearbeitet werden.

DELETE FROM `tabelle`


DELETE löscht einen Datensatz, in diesem Fall wird die gesamte Tabelle geleert, auch hier sollte mit WHERE und LIMIT gearbeitet werden. Wichtig, wegen der Performance sollte DELETE nicht für das Löschen einer ganzen Tabelle genutzt werden.

Hierfür gibt es den folgenden Befehl:

TRUNCATE `tabelle`


TRUNCATE leert eine Tabelle.

Es ist noch zu beachten, dass bei den Werten, die ', " und \ entschärft werden, da dies zu Fehlern führen könnte, sowie gerne auch für SQL Injection genutzt wird, in PHP ist ein Möglichkeit z.B. mysql_real_escape_string zu nutzen.

PHPminiAdmin

So ich möchte in der neuen Rubrik Programm des Moments immer wieder Programme, aber auch Skripte vorstellen.

Anfangen werde ich mit PHPminiAdmin, dieses gerade mal 26 KB große PHP Skript erleichtert den Umgang mit mySQL Datenbanken erheblich ohne gleich auf phpMyAdmin zugreifen zu müssen, vorallem ist es deutlich Server schonender. Die aktuelle Version ist die 1.7.110429 (Releasedatum 29. April 2011).

Ein Manko neben der nur Englisch erhältlichen Version ist allerdings: Es ist für Einsteiger nicht zu empfehlen, da die SQL Befehle direkt eingegeben werden müssen.

Für die kleine Wartung zwischendurch oder die schnelle Datensicherung ist es auf alle Fälle leichter zu handhaben wie phpMyAdmin, wobei ich auf auf letzteres nicht unbedingt verzichten möchte, bei größeren Aktionen.