Home-Produkte-Testarea-Kontakt-Datenschutz-Aktualisiert: 05-Apr-2010
< Voriger Tag   Nächster Tag >

Montag, 05. April 2010

Aufgefallen: Löschen funktioniert, Roboter und Körpersprache, Pepper, ...

11 Links aus verschiedenen Bereichen u.a. Löschen statt Sperren funktioniert -- "Phishing mit Ködern" -- Interaktion zwischen Robotern und Menschen -- Pepper - Platform independent NPAPI -- "10 Golden Principles of Successful Web Apps" -- Eclipse Pair Programming mit Saros und Was aus YouTube-Stars wurde.

"Das Löschen kinderpornografischer Angebote im Internet funktioniert – Sperren braucht es nicht", 29-Mar-2010, eco

Zahlen über das erfolgreiche Löschen von kinderpornografischen Angeboten im Internet. Zitat: Die seit Mai 2009 fortgeschriebene Statistik der Beschwerdestelle, die eco mit zusammen mit der Freiwilligen Selbstkontrolle Multimedia e. V. unter dem Portal www.internet-beschwerdestelle.de betreibt, verzeichnet für in Deutschland gehostete kinderpornografische Internetseiten eine Erfolgsquote von 100 Prozent. Die Herunternahme erfolgt in jeweils binnen Stunden oder Minuten. Im Ausland gespeicherte Angebote sind zu 50 Prozent binnen 5 Tagen, zu 93 Prozent binnen zwei Wochen und der Rest danach offline. Nach Angaben des Bundeskriminalamts* dauert es sogar lediglich eine Woche, bis in 86 Prozent aller Fälle der Zugriff auf die beanstandeten Inhalte an der ausländischen Quelle gesperrt wird.

[via: Jörg-Olaf Schäfers]

Carsten Eilers, "Standpunkt Sicherheit: Phishing mit Ködern", 29-Mar-2010, Standpunkt Sicherheit

Eine grundlegende Sicherheitsregel lautet: "Ein Passwort immer nur direkt auf der einen Website eingeben zu der das Passwort gehört." Und es damit niemals in Formularen auf anderen Websites einzugeben.

Wie einfach man dennoch mit einer Belohnung Menschen dazu bewegen kann Passwörter auf fremden Seiten einzugeben, beschreibt Carsten Eilers in obigen Artikel.

Hans-Arthur Marsiske, "Roboter mit Körpersprache und Tastsinn", 01-Apr-2010, heise online

Ausführlicher Bericht mit vielen interessanten Aspekten vom 1. Tag des New Frontiers in Human-Robot Interaction-Symposiums über die Interaktion zwischen Menschen und Robotern.

Hans-Arthur Marsiske, "Die Robotergefährten der Zukunft", 02-Apr-2010, heise online

Ausführlicher Bericht mit vielen interessanten Aspekten vom 2. Tag des New Frontiers in Human-Robot Interaction-Symposiums über die Interaktion zwischen Menschen und Robotern.

Elizabeth Naramore, "Why People Don't Contribute to OS Projects, and What We Can Do About It", 31-Mar-2010, The Blog of ElizabethN

Gute Vorschläge zur Motivation von Menschen zum Mitmachen bei Open Source-Projekten.

"Plugins:PlatformIndependentNPAPI", 30-Mar-2010, MozillaWiki

Pepper (PlatformIndependent NPAPI) ist ein Vorschlag zur Verbesserung der API für Browser-Plugins mit einer ganzen Reihe wichtiger Verbesserungen:

Zitat:

  1. Giving a clear semantics to NPAPI across browsers that implement plugins in a separate process from the renderer/browser itself.
  2. Integrating plugin rendering with the browser's compositing process, allowing HTML overlays, etc., to work correctly with plugins.
  3. Defining events, 2D rasterization, and an initial take on 3D graphics access in a way that is common across operating systems and browsers.
  4. Determining which plugins are available to a browser without loading the plugin. Although a much smaller issue, it is currently one of the more platform specific portions of NPAPI and one that lends itself to a relatively simple solution.

[via: Golem.de]

Jan Willem Boer, "Joel on Software - a summary", 21-Mar-2010, JWB's blog

Im Joel on Software-Blog von Joel Spolsky gibt es viele gute Texte zum Thema Softwareentwicklung. Jan Willem Boer fasst diese jeweils in einem Satz zusammen.

[via: Hacker News]

Keir Whitaker, "Fred Wilson's 10 Golden Principles of Successful Web Apps", 30-Mar-2010, Carsonified

10 Tipps (Video, Transkript) für erfolgreiche Web-Applikationen -- u.a. Instant Utility, Less is More, Make it Programmable, Make it Personal, Playful. Lukasz Konieczny hat sie auf Deutsch zusammengefasst.

[via: Falk Hedemann]

Peer Wandiger, "Twitter für Selbständige – Die ersten Schritte", 31-Mar-2010, Selbständig Im Netz

Hilfreiche Tipps zur Kommunikation mit Twitter.

"Saros - Distributed Collaborative Editing and Distributed Party Programming", , inf.fu-berlin.de

Pair Programming übers Internet mit der Eclipse-IDE (Screencast, 11:15 Min.).

[via: Sarosian]

"Internetberühmtheiten - Das wurde aus den YouTube-Stars", 29-Mar-2010, sueddeutsche.de

Zitat: Internetberühmtheiten Das wurde aus den YouTube-Stars Ob niesender Panda, verzweifelter Britney-Fan oder Erfinder der Cola-Fontäne: YouTube kann Unbekannte zu Stars machen. Doch was dann? Eine Spurensuche. (Auf einer Seite)

[Direktlink]

PHP: RuBisCO ORM -- 1:1 Beziehung

Das Speichern einzelner Objekte jeweils in eine Tabelle lässt sich sehr direkt umsetzen. Mit Objekten, die miteinander in Beziehung stehen, sieht das schon komplizierter aus. Mal in kleinen Schritten anhand konkreter Beispiele herantasten.

Für die 1:1-Beziehung benutze ich das To Do-List Beispiel. Jedem Task kann ein User zugeordnet werden, der sich um die Umsetzung der Aufgabe kümmert.

ID Task Assigned
1Task 1alice
2Task 2alice
3Task 3bob

SQL-Tabellen

Benutzt werden dazu folgende Tabellen:

CREATE TABLE IF NOT EXISTS users (
  id     INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  login  VARCHAR(256) NOT NULL
) ENGINE=INNODB;


CREATE TABLE IF NOT EXISTS tasks (
  id       INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  task     VARCHAR(256) NOT NULL,
  assigned INT, FOREIGN KEY (assigned) REFERENCES users(id)
                                       ON UPDATE RESTRICT
                                       ON DELETE SET NULL,
  INDEX (assigned)
) ENGINE=INNODB;

PHP-Objekte

Die auf folgende PHP-Objekte abgebildet werden:

class User {
    protected $_id    = null;
    protected $_login = null;
}


class Task {
    protected $_id       = null;
    protected $_task     = null;
    protected $_assigned = null;

    public $usersRef = null;
}

Für jede Tabelle gibt es also weiterhin jeweils eine Klasse. Und die 1:1-Verbindung der Objekte erfolgt über die Referenz in $task->usersRef.

Wie müssen jetzt die Methoden fürs Lesen, Einfügen, Aktualisieren, ... aussehen?

Read

Per JOIN werden die Daten aus den benötigten Tabellen mit einer SELECT-Anweisung gelesen und dann den einzelnen Objekten zugewiesen.

$sqlReadTask = 'SELECT tasks.id AS tasks_id, tasks.task AS tasks_task,
			tasks.assigned AS tasks_assigned, users.id AS users_id,
			users.login AS users_login
		FROM tasks JOIN users ON tasks.assigned = users.id
		WHERE tasks.id = :id';
fetch();

$this->id       = $result['tasks_id'];
$this->task     = $result['tasks_task'];
$this->assigned = $result['tasks_assigned'];

$this->usersRef        = new UserDB();
$this->usersRef->id    = $result['users_id'];
$this->usersRef->login = $result['users_login'];

Insert

Beim Einfügen muss das referenzierte Objekt bereits in der Datenbank vorhanden sein, ansonsten gibt es durch den FOREIGN KEY einen Fehler. Deshalb wird als erstes das referenzierte Objekt mit $this->usersRef->insertOrUpdate() gespeichert. Danach folgen die Daten des Tasks-Objekts. Für usersRef wird insertOrUpdate() benutzt, da der User schon in der Datenbank vorhanden sein kann. In diesem Fall kommen nur die Daten des Task-Objekts neu hinzu.

Wenn die _id des Tasks-Objekts bisher null war, also nicht selbst gesetzt wurde, wird sie anschließend aus der Datenbank gelesen und dem Objekt zugewiesen.

try {
    $this->app->beginTransaction();

    if(!is_null($this->usersRef)){$this->usersRef->insertOrUpdate();}

    $sqlInsertTask = 'INSERT INTO tasks (id, task, assigned)
                             VALUES (:id, :task, :assigned)';
    insert();

    if(is_null($this->_id)) {
        $this->_id = $this->dbh->lastInsertId();
    }

    $this->app->commit();
} catch (Exception $e) {
    $this->dbh->rollBack();
    throw $e;
}

Update

update() geht davon aus, dass sich sowohl das Objekt als auch die referenzierten Objekte bereits in der Datenbank befinden und nur deren Werte aktualisiert werden müssen. Damit reduziert sich die Methode auf ein UPDATE der Daten.

try {
    $this->app->beginTransaction();

    if(!is_null($this->usersRef)){$this->usersRef->update();}

     $sqlUpdateTask = 'UPDATE tasks SET task = :task, assigned = :assigned
                       WHERE tasks.id = :id';

     execute();

     $this->app->commit();
} catch (Exception $e) {
     $this->dbh->rollBack();
     throw $e;
}

Insert or Update

Zum Teil möchte oder kann man nicht zwischen INSERT und UPDATE unterscheiden. Hier hilft die insertOrUpdate()-Methode weiter.

insertOrUpdate() fügt das Objekt neu in die Datenbank ein, falls es noch nicht vorhanden ist und aktualisiert im anderen Fall die Daten des Objekts. Bei MySQL wird hierzu INSERT INTO ... ON DUPLICATE KEY UPDATE ... benutzt.

Bei eingefügten Objekten wird gegebenfalls anschließend wie bereits bei insert() die _id aus der Datenbank gelesen.

$sqlInsert = 'INSERT INTO tasks (id, task, assigned)
                          VALUES (:id, :task, :assigned)
              ON DUPLICATE KEY UPDATE task = :task, assigned = :assigned';

execute();

if(is_null($this->_id)) {
    $this->_id = $this->dbh->lastInsertId();
}

Delete

delete() löscht nur das Objekt aus der Datenbank. Die Behandlung der referenzierten Objekte wird der Datenbank durch die ON CASCADE-Deklaration überlassen.

$sqlDeleteTask = 'DELETE FROM tasks WHERE id = :id';

execute();

setAssigned($value)

Wichtig ist insbesonders die Verarbeitung einer Zuweisung an assigned und damit einer Änderung des Users: $task->assigned = 2.

Wenn sich mit assigned das zur Referenz gehörende Feld ändert, dann muss das Programm die Referenz aktualisieren. Dies geschieht durch überschreiben von setXXX() -- in diesem Fall setAssigned(). Hier wird $this->usersRef() (neu) eingelesen, wenn sich der Wert von assigned ändert.

Die setXXX()-Funktionen werden automatisch bei Zuweisungen wie $task->assigned = 2 aufgerufen.

Fehler: Was im Moment noch nicht berücksichtigt wird ist, dass sich umgekehrt mit einer Änderung in $task->usersPref->id auch der dazugehörige Wert in $task->assigned ändern muss.

public function setAssigned($value) {
    $oldValue = $this->assigned;

    parent::setAssigned($value);

    if($oldValue !== $this->assigned) {
        try {
            if(is_null($this->usersRef)) {
                $this->usersRef = new UserDB();
            }

            $this->usersRef->read($this->assigned);

            return $this;
         } catch (\Exception $e) {
             $this->usersRef = null;
             $this->_assigned   = null;
             throw $e;
         }
     }
}// setAssigned

Verschachtelte Transaktionen

Da ein Objekt die insert()-, update()-, ...-Methoden eines anderen Objekts aufruft, müssen sich die SQL-Transaktionen verschachteln lassen. Dies ist im Applikations-Objekt, in diesem Fall Todo, mit beginTransaction() und commit() umgesetzt. Gezählt wird die Verschachtelungstiefe in transactionCount.

/**
* Begin nested database transaction.
*/
public function beginTransaction() {
    if(0 == $this->transactionCount) {
        $this->dbh->beginTransaction();
    }

    $this->transactionCount++;
}// beginTransaction


/**
* Commit nested database transaction.
*/
public function commit() {
    $this->transactionCount--;

    if(0 == $this->transactionCount) {
        $this->dbh->commit();
    }
}// commit

Referenz oder Array?

Eine 1:1-Beziehung ist recht speziell. Bei der 1:n-Beziehung wird dann statt nur einer Referenz ein Array benötigt. Eventuell macht es daher Sinn für die 1:1 Beziehung auch ein Array mit nur einen Eintrag zu benutzen. Dadurch entfällt der Sonderfall mit nur einem Referenzfeld und die Programmierung wird einfacher.

Quelltext (MIT Lizenz)

Der komplette Quelltext von RuBisCO ORM liegt in Subversion: Heutige Revision 27, aktuelle Version.

Das generierte Beispiel steht in examples/onetoone/src/.

Die Generierung geschieht in erster Linie in Table.php.

[Direktlink]

< Voriger Tag   Nächster Tag >

  RSS V0.91

<April 2010 >
   01020304
05060708091011
12131415161718
19202122232425
2627282930  

Home-Produkte-Testarea-Kontakt-Datenschutz-Aktualisiert: 05-Apr-2010
(C) 2000-2018 by Sven Drieling