by:

Ich bin seit Jahren MySQL Benutzer aus Überzeugung und verwende es in nahezu jeder Webanwendung, die ich programmiere.
Allerdings häufen sich in letzter Zeit Anwendungsszenarien, die sich mit MySQL etwas schwierig gestalten...
Bevor ich jedoch meine Contraliste ausfahre, möchte ich noch ein paar positive Worte finden...

"MySQL ist eine tolle relationale Datenbank, solange man keine relationale Datenbank braucht" (Unknown)

Pro:
MySQL ist OpenSource
MySQL läuft auf nahezu jeder Platform
MySQL ist schnell und zuverlässig

Entgegen vielen anderen Berichten im Netz, ist auf meiner Contraliste die folgende Aussage nicht zu finden:
MySQL kann keine Transaktionen und Stored Procedures.
Dies ist schlicht nicht mehr der Fall, allerdings gibt es ein paar andere Limitationen in MySQL und damit komme ich nun zu den Contra Punkten.

Es ist nicht möglich Transaktionen in Stored Procedures oder Funktionen auszuführen.

Es ist nicht möglich eine Tabelle in mehrere Partitionen zu teilen, (diese auf mehreren Hosts zu verteilen)
und parallel abzufragen.

Es ist nicht möglich variable Tabellennamen in Triggern zu verwenden.

Es ist nicht möglich ein Update auf sich selbst zu machen (ausser mit dem Umweg über einen View)

Vereinfachtes BSP:
update test set x="y" where id in (select id from test)

Interessant finde ich die Interpretation von "between".
"Between" ist für mich "zwischen", between 1 and 3 wäre folglich 2.
MySQL interpretiert "between" aber als eine range (from - to).
Folgendes Beispiel ergibt daher true:

Between 1 and 3 = 1,2,3

select 1 between 1 and 3
select 2 between 1 and 3
select 3 between 1 and 3

Interessanterweise interpretiert Postgres between 1 and 3 als 2 und 3. Irgendwie verwirrend...

Was mich auch sehr stört ist, dass in MySQL von Haus aus keine effiziente Lastenverteilung möglich ist.

Um es kurz zu machen, ich glaube MySQL hat bei Webanwendungen einen guten Platz gefunden,
wo es sich behauptet kann, allerdings bleibt abzuwarten, was nach der Übernahme
von Oracle aus MySQL wird.

Ich für meinen Teil würde mir wünschen, dass MySQL wieder unabhängig von Sun und Oracle wird, aber
das ist natürlich eher ein Wunschtraum der sich in der nahen Realität wohl kaum verwirklichen wird.

Mich würde sehr interessieren was euch an MySQL gefällt und was nicht.

LG
Andreas


Kommentare

by:

Kommentare

by:

Das ist der erste Co- Authoren Beitrag auf meiner Seite zum Thema Captchas.
Vielen Dank vorab an: Sereby (http://www.sereby.org/)


Man findet Sie überall und man kommt auch nicht mehr dran vorbei:
Captcha's (Completely Automated Public Turing test to tell Computers and Humans Apart)
Sie werden von Webseiten-Administratoren z.B. bei Kontaktformularen, Shoutboxen oder Downloads verwendet, um sicher zu stellen, dass Bots nicht die Möglichkeit haben die Shoutbox oder ähnliches voll zu spammen oder in einem Downloadbereich dafür zu sorgen, dass nicht unendlich viel Traffic verbraucht wird, weil der Downloadlink tausende Male ausgeführt wird.

Nun zum eigentlichen Code:
Download

zunächst muss die Klasse TCaptcha eingebunden werden um auf die Validierungsfunktionen zuzugreifen
Code


<?
include('captchaTCaptcha.php');
?>
<form action="" method="post" name="111">
    <!-- 
        Einbinden des Captcha's über ein <img> tag.
        Wenn mehrere Captcha's verwendet werden sollen, dann
        müssen Sie die ID verändern!
    -->
    <img src="captcha/show.php?id=1" alt="Sicherheitscode 1" />

    <input type="text" name="captcha_code1" size="13" /> <input type="submit" value="OK" />

    <?
        //code überprüfen
        if (isset($_POST['captcha_code1'])){
            // Validate(* Getippter Code *, * Captcha-ID die verglichen werden soll *) 
            if (TCaptcha::Validate($_POST['captcha_code1'], 1)){
                echo 'Code OK!';
            }else{
                echo 'Falscher Code eingegeben!';
            }
        }
    ?>
</form>


Nun die eigentliche Captcha Klasse

Code

<?php
session_start
();
define('CAPTCHA_SESSION_ID''php_captcha');
define('CAPTCHA_IGNORE_CASE'false);

class 
TCaptcha
{
    var 
$IgnoreCase;
    var 
$CharSet;
    var 
$font;
    var 
$font_size;
    var 
$width;
    var 
$height;
    var 
$bgimg;
    var 
$maxlen;

    public 
$Code;

    public function 
__construct($FontFile './xfiles.ttf'$iWidth 100$iHeight 40)
    {
        
$this->IgnoreCase CAPTCHA_IGNORE_CASE;
        
$this->font       $FontFile;
        
$this->bgimg      './bg.png';
        
$this->maxlen     5;
        
$this->font_size  20;
        
$this->CharSet    'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
        
$this->SetWidth($iWidth);
        
$this->SetHeight($iHeight);
        
$this->Code '';
    }
    
    function 
SetWidth($iWidth)
    {
        
$this->width $iWidth;
        if (
$iWidth 500$this->width 500;
    }

    function 
SetHeight($iHeight)
    {
        
$this->height $iHeight;
        if (
$iHeight 200$this->height 200;
    }
    
    private function 
randomString($len)
    {
        
//zufallszahl
        
function make_seed()
        {
            list(
$usec $sec) = explode (' 'microtime());
            return (float) 
$sec + ((float) $usec 100000);
        }
        
srand(make_seed());

        
//zufallsstring
        
$str '';
        while (
strlen($str)<$len)
        {
            
$str .= substr($this->CharSet, (rand()%(strlen($this->CharSet))), 1);
        }
           return(
$str);
    }
   
    function 
GenerateCode()
    {
        
//captcha-id
        
$CaptchaID = (is_numeric($_GET['id']) ? $_GET['id'] : '1');
        
        
//code generieren
        
$this->Code $this->randomString($this->maxlen);
        
        
//groß / kleinschreibung beachten?
        
if ($this->IgnoreCase)
        {
            
$this->Code strtoupper($this->Code);
        } 

        
//in die Session schreiben
        
$_SESSION[CAPTCHA_SESSION_ID][$CaptchaID] = $this->Code;
    }

    function 
Create()
    {
        
//Hintergrundbild einlesen
        
$picinfos GetImageSize($this->bgimg);
        
$OldIMG   ImageCreateFromPNG($this->bgimg);
        
        
//größe anpassen
        
$img      ImageCreateTrueColor($this->width$this->height);
        
ImageCopyResized($img,$OldIMG,0,0,0,0,$this->width,$this->height,$picinfos[0],$picinfos[1]);

        
//Farbe der Schrift
        
$color ImageColorAllocate($img000); 
        
        
//ZufallsCode generieren
        
$this->GenerateCode();
        
        
//justierung
        
$spacing = ($this->width $this->maxlen);
        
$t_y_min min($this->height$this->font_size);
        
$t_y   rand($t_y_min 1.2$t_y_min 2.8) + $spacing;
        
$angle rand(0,7);
        
$t_x   rand(5,10);
        
$a     0;

        
//text auf das bild schreiben. Zeichen für Zeichen
        
for ($i 1$i <=$this->maxlen$i++)
        {
            
ImageTTFText($img$this->font_size$angle$t_x$t_y$color$this->font$this->Code{$a});
            
$t_x $t_x $spacing -3;
            
$a++; // nächstes zeichen
        
}
        
        
//bild anzeigen
        
header("Content-type: image/gif");
        
ImageGIF($img);
        
        
//bild freigeben
        
ImageDestroy($img);
    }
    
    function 
Validate($MyCode$ID 1$IgnoreCase CAPTCHA_IGNORE_CASE)
    {
        if (
$IgnoreCase)
        {
            
$MyCode strtoupper($MyCode);
        }

        if (!empty(
$_SESSION[CAPTCHA_SESSION_ID][$ID]) && $MyCode == $_SESSION[CAPTCHA_SESSION_ID][$ID])
        {
            unset(
$_SESSION[CAPTCHA_SESSION_ID][$ID]); //wiederbenutzen vermeiden
            
return true;
        }
        return 
false;
    }
}
?>


Fertig!

Nachtrag von Andreas:

Es gibt auch Möglichkeiten ein Captcha zu umgehen, dies sei an dieser Stelle noch erwähnt. In der Praxis sind die Methoden allerdings eher ineffektiv oder doch etwas kompliziert.

Trotzdem möchte ich kurz auf ein, zwei Möglichkeiten hinweißen.

OCR Software, also Texterkennungssoftware die das Captcha versucht zu interpretieren. Ist in
der Anwendung kompliziert und schwer zu implementieren, aber dennoch der erfolgsversprechendste Ansatz.

Ich habe auch mal von der Möglichkeit gehört, die Captcha bei seiner privaten Seite einzubinden
um seine Besucher die Arbeit erledigen zu lassen indem man sie dazu nötigt die Captchas zu entschlüsseln.
Dies gelingt natürlich nur auf einer interessanten Seite mit viel Traffic.

Andere Varianten nutzen meist nur schlecht programmierte Captcha aus, bei denen z.b. das Lösungswort
in einem hidden field steht...

Vielen Dank Sereby für deinen ersten Beitrag!

Andreas


Kommentare

by:

Was ist ein Redirect Service ?

Ein Redirect oder auch Alias Service ist eine Methode, mit der man aus einer langen Internetadresse, eine gekürzte Form machen kann ...
Bsp.:
Aus
http://maps.google.at/maps?hl=de&ie=UTF8&ll=48.203397,16.373062&spn=0.094503,0.305557&z=12
Wird
http://kickmeto.ath.cx/wien

Nötig wird so ein Service, wenn man bei der Zeilenlänge eingeschränkt ist,
wie etwa in einer eMail, bei einer SMS oder auch bei Twitter.

Was benötigen wir für unseren eigenen Redirect Service ?

Eine möglichst kurze Domain
Einen Webserver mit PHP und mod_rewrite (Apache)
Eine Datenbank (im Beispiel verwende ich MySQL)

Ich habe zum Demonstrieren http://kickmeto.ath.cx/ online gestellt, was
auf folgendem Code basiert.

Zuerst erstellen wir unsere MySQL Tabelle "redirect":

CREATE TABLE `redirect` (
`id` bigint(20) unsigned NOT NULL auto_increment,
`url` text NOT NULL,
`name` varchar(255) default NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;


Hier haben wir einen primären Schlüssel (id), die Adresse (url) welche wir in den Namen (name) umwandeln möchten.

Jetzt erstellen wir eine Konfigurationsdatei, in der wir unsere Datenbankparameter, wie user, passwort etc.
reinschreiben:

Code

<?
    /***   mysql connection information   ****/
    /*****************************************/
    $db      = "redirect";
    $db_host = "localhost";
    $db_user = "user";
    $db_pass = "pass";
    $url     = "http://kickmeto.ath.cx/";
    /*****************************************/

?>


Jetzt kommt das Herzstück der Weiterleitung, folgender Script (index.php) übernimmt alle Aufgaben, die wir benötigen

1. Weiterleitung der Kurzadressen
2. Speichern neuer Adressen
3. Fehlerüberprüfung

Code

<?
include("./config.php");
$sOut="";

//wir bauen eine verbindung zur datenbank auf
$connect=@mysql_connect("$db_host", "$db_user", "$db_pass")
or die("<li>Cant connect to: $db_host  with user: $db_user</li>");
@mysql_select_db($db, $connect)or die("Cant select DB");

//im folgenden teil versuchen wir einen redirect in der datenbank zu finden
//wenn nicht das eingabe formular gefragt ist
if($_SERVER[REQUEST_URI]!=="/"){

    $surl=mysql_escape_string(strip_tags(substr($_SERVER[REQUEST_URI], 1)));
    $sql='select url from redirect where name="'.$surl.'" or id="'.$surl.'" limit 1';
    $query=mysql_query($sql);
    $row=mysql_fetch_array($query);
    if($row[url]){
    //hier paasiert die eigentlich weiterleitung
    header("Location: $row[url]");
    }else{
    $sOut.= "Kurzadresse nicht gefunden";
    }

}
//wenn jemand speichern drückt
if($_POST){

    //überprüfe ob die url syntax richtig ist
    if(preg_match("/(((https?)|(ftp))://([-w]+.)+w{2,3}(/[%-w]+(.w{2,})?)*(([w-.?/+@&#;`~=%!]*)(.w{2,})?)*/?)/i", $_POST[url])){
        //maskiere die parameter und speichere sie in die datenbank
        $nurl=mysql_escape_string($_POST[url]);
        if($_POST[name]){
            $sqlstr="'".mysql_escape_string(strip_tags($_POST[name]))."'";
            $name=mysql_escape_string(strip_tags($_POST[name]));
        } else {
            $sqlstr="NULL";
        }
        //hier überprüfen wir ob der name schon existiert
        if(url_exist($name)){
            $sOut="Der Name existiert leider schon, versuchs mit einem anderem.";
        } else {
            //nun schreiben wir die neue kurzurl in die datenbank
            $sql="insert into redirect VALUES ('', '$nurl', $sqlstr)";
            mysql_query($sql);
            $id=mysql_insert_id();        
            $sOut.='Deine Adresse ist nun unter folgender Adresse erreichbar:<br>';
            if($_POST[name]){
                $sOut.='<a href="'.$url.''.$name.'">'.$url.''.$name.'</a> oder <br>';
            }
            $sOut.='<a href="'.$url.''.$id.'">'.$url.''.$id.'</a>';
        }
    }else{
        $sOut.="Bitte check deine URL";
    }
}


function url_exist($url){
    $sql='select url from redirect where name="'.$url.'" or id="'.$url.'" limit 1';
    $query=mysql_query($sql);
    $row=mysql_fetch_row($query);
    if($row[0]){
        return true;
    } else {
        return false;
    }

}


?>
<html>
<head>
<style type="text/css">
body{
    background-color:#000000; 
    color: #ffffff;
    text-align:center;
}
</style>
</head>
<body>
<div class="header">Banner

Short Url Service
</div>
<div class="msg">
<?=$sOut?>
</div>
<form method="post">
<table align="center">
    <tr>
        <td>Url:</td>
        <td><input type="text" name="url" value="http://"></td>
    </tr>
    <tr>
        <td>Name (Optional)</td>
        <td><input type="text" name="name"></td>
    </tr>
        <td> </td>
        <td><input type="submit" name="Save" name="Speichern"></td>
    </tr>
</table>
</form>
</body>
</html>




Das wichtigste noch zum Schluss, die ModRewrite Anweisung (.htaccess), die alle Anfragen umleitet..

RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

Ich hoffe der Script ist weitgehend selbsterklärend, ansonsten kannst du mich gerne anschreiben, wenn
du Fragen oder Verbesserungsvorschläge hast.

Andreas


http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html


Kommentare

by:

Generell begrüße ich die Idee das Internet sicherer zu machen, es gibt viel fragwürdiges Material im Internet, sei es Kinderpornographie, Rechtsextremismus oder Schadsoftware, doch ich denke nicht, dass der Zweck alle Mittel heiligt.
Man sollte doch stark differenzieren.

Die Tendenz geht immer mehr in eine Richtung die mich persönlich betrifft, ohne dass ich es direkt bemerke und ohne dass ich jemanden etwas böses will.

Es hat alles mit dem Deckmantel der Terrorbekämpfung angefangen, ging weiter mit der Vorratsdatenspeicherung und nun auch noch die DNS Blocklisten...

Wer die Freiheit aufgibt, um Sicherheit zu gewinnen, wird am Ende beides verlieren.

Benjamin Franklin

Ich persönlich fühle mich in meiner Freiheit sagen wir zumindest eingeschränkt, da ich jederzeit damit rechnen muss, überwacht zu werden.
Das klingt etwas paranoid, tatsächlich werden wir aber jeden Tag überwacht, sei es in der U-Bahn, am Telefon oder beim eMail schreiben...

Wenn ich zum Beispiel eine Recherche im Internet über den Nationalsozialismus mache, oder meine Freundin am Telefon anrufe, werden meine Daten gesammelt, verknüpft und von einer Maschine interpretiert. Datamining heisst das Zauberwort. Es ist leider in unser Technologie Gesellschaft sehr leicht möglich persönliche Profile mit wenigen Mausklicks zu erstellen, leider sind solche Programme relativ dumm (ich weiss das, da ich vergleichbare Anwendungen programmiere).
Sie nehmen, sagen wir drei Parameter: Wohnort, Alter und Geschlecht und leiten davon Ihre Lebenserwartung, das durchschnittliche Einkommen und ihre Bonität ab.

Ein Mobilfunkbetreiber, dessen Namen ich nicht nennen möchte, hat ein vergleichbares Programm, so kann es sein, dass Sie keinen Handyvertrag bekommen wenn sie in der falschen Gegend wohnen, da in ihrem Umfeld oder ihr Vormieter die Rechnungen nicht zahlte.

Ich will damit sagen das solche Programme wenig nutzen für die Gesellschaft bringen, vergleichbar aber enorm fehleranfällig und teuer sind.

Nun werden solche Programme nicht nur von Unternehmen sonder auch vom Staat benutzt, die Frage die sich mir dabei stellt, mit welchem Recht hat der Staat die Befugnisse erhalten soviel über mich zu erfahren ??
Was ist mit dem Fernmeldegeheimnis passiert ?
Ist uns unsere Privatssphäre nicht mehr wichtig ?

Eine DNS Sperre kann nicht ausreichen, da diese den fragwürdigen Inhalt nicht aus dem Internet verbannt sondern nur eine Art Vorhang für ein bestimmtes Publikum darstellt.

Da ist die bisherige Lösung, das ein Gericht entscheidet, ob eine Seite wirklich vom Netz geht oder nicht, meines erachtens nach besser.

Ebenso wird keine DNS Sperre Gewalt oder sexuellen Missbrauch an Kindern verhindern oder unterbinden.

Ich vermute eher dass es in einer Welt wo andere entscheiden was ich sehen darf und was nicht, schwerer wird sich selbst ein Urteil zu bilden.


Kommentare


Seiten: