Simple SQL-Abfragen in Magento

Magento bietet einen hervorragenden Datenbank-Abstraktionslayer. Und im Allgemeinen sollte man diesen Layer auch für Datenabfragen und vor allem für Datenmodifikationen im Magento-System nutzen.

Manchmal ist es aber doch der einfachste und performanteste Weg, wenn man direkt per SQL auf die Datenbank zugreifen kann. Das geht auch in Magento, und zwar auf folgende Weise.

$sql = "SELECT foo FROM bar WHERE baz";
$data = Mage::getSingleton("core/resource")->getConnection(Mage_Core_Model_Resource::DEFAULT_READ_RESOURCE)->fetchAll($sql);

Pear für XAMPP auf OS-X aktivieren

Pear ist zwar bei XAMPP mit dabei, aber, zumindest in Version „XAMPP für Mac OS X 1.0.1“, nicht funktionstüchtig. Dieser Umstand lässt sich mit folgenden Schritten beheben.

1. Im Terminal folgende Befehle ausführen

sudo /Applications/XAMPP/xamppfiles/bin/pear channel-update pear.php.net
sudo /Applications/XAMPP/xamppfiles/bin/pear install PEAR

2. In den letzten Zeile der Konfiguration /etc/php.ini

;***** Added by go-pear
include_path=".:/Applications/xampp/xamppfiles/lib/php"
;*****

gegen das hier austauschen:

include_path = ".:/Applications/XAMPP/xamppfiles/lib/php:/Applications/XAMPP/xamppfiles/lib/php/pear"

Nach einem Neustart des Apache sollte Pear nun funktionieren.

parent:: macht den Methoden-Namen bei __call() lowercase

Wenn eine PHP-Klasse die Methode __call() besitzt, wird diese beim Versuch eine nicht existierende Methode aufzurufen, aufgerufen, anstatt einen Fehler zu erzeugen.

Im ersten Parameter steht dann der Name der Methode und im zweiten Parameter stehen die Argumente die an die nicht existierenden Methode übergeben wurden… Soweit, so klar.

Wird __call() aber über parent:: aktiviert, wird der erste Parameter, also der Methoden-Name seltsamerweise lowercase. Dieses Verhalten zeigt zumindest PHP 5.2.9.

Das folgende Code-Beispiel zeigt, was genau gemeint ist.

<?php
class Daddy
{
    function __call($method, $args)
    {
        echo 'class: '.get_class($this).', method: '.$method."n";
    }
}

class Son extends Daddy
{
    function getSomeData()
    {
        return parent::getSomeData();
    }
}

$daddy = new Daddy();
echo $daddy->getSomeData();

$son = new Son();
echo $son->getSomeData();

Die Ausgabe ist:

class: Daddy, method: getSomeData
class: Son, method: getsomedata

Was der Sinn davon ist, weiss ich leider nicht. Ich vermute mal einen Bug in PHP.

Die Scan-Zeit von NetBeans 6.7 lässt sich drastisch reduzieren

Ich mag NetBeans zur PHP-Entwicklung. Allerdings scannte NetBeans 6.7 nach dem Start zunächst sehr lange die Dateien des Sourcecodes („Scanning Projects…“). Vor allem, wenn man auf einem gemounteten Serverlaufwerk arbeitet. Wenn man während des Scannens Änderungen am Code macht, bleibt NetBeans meist hängen, was den langen Scan ärgerlich macht.

Um die Geschwindigkeit von NetBeans zu erhöhen habe ich heute ausprobiert, ungenutzte Plugins zu deaktivieren… und siehe da, nachdem ich das CSV-Plugin deaktivert hatte, war die Scanzeit zum Start der Entwicklungumgebung auf unter eine Minute reduziert.

PHP debuggen – mit NetBeans, XAMPP und xdebug

Dieser Artikel zeigt, wie man einfach einen xdebug-Debugger unter XAMPP zum Laufen bekommt und diesen dann von NetBeans aus nutzen kann. Dieses Verfahren wurde unter OS-X Leopard mit XAMPP 1.0.1 für Mac OS X ausprobiert.

1. xdebug-Erweiterung in XAMPP kopieren

Wer die xdebug-Erweiterung nicht selbst kompilieren möchte, kann sie hier für OS-X Leopard (Intel) herunterladen: xdebug.so

Das xdebug.so muss in folgendes Verzeichnis kopiert werden.

/Applications/XAMPP/xamppfiles/lib/php/php-5.2.9/extensions/no-debug-non-zts-20060613

2. Die Erweiterung in etc/php.ini konfigueren

In der php.ini wird die Erweiterung konfiguriert.

zend_extension="/Applications/XAMPP/xamppfiles/lib/php/php-5.2.9/extensions/no-debug-non-zts-20060613/xdebug.so"
xdebug.remote_enable=1
xdebug.remote_handler=dbgp
xdebug.remote_mode=req
xdebug.remote_host=127.0.0.1
xdebug.remote_port=9000
xdebug.idekey=

Das wars auch schon. Apache neu starten und der Debugger sollte nun mit NetBeans funktionieren.

Den Speicher erhöhen, den NetBeans zur Verfügung hat

Um auch größere Projekte mit NetBeans programmieren zu können, ist es sinnvoll, den für NetBeans verfügbaren Speicher zu erhöhen. Die hier beschriebene Methode habe ich unter OS-X Leopard ausprobiert. Mit anderen Betriebssystemen ist die Vorgehensweise wahrscheinlich ähnlich.

In dem Verzeichnis

/Applications/NetBeans/NetBeans 6.5.app/Contents/Resources/NetBeans/etc

findet man die Datei „netbeans.conf„, in der auch Parameter der Java-Laufzeitumgebung konfiguriert werden können. Die dafür zuständige Zeile ist:

netbeans_default_options="-J-client -J-Xverify:none -J-Xss2m -J-Xms32m -J-XX:PermSize=32m -J-XX:MaxPermSize=200m -J-Dapple.laf.useScreenMenuBar=true -J-Dsun.java2d.noddraw=true"

Mit

netbeans_default_options="-J-client -J-Xverify:none -J-Xss16m -J-Xms384m -J-Xmx768m -J-XX:PermSize=64m -J-XX:MaxPermSize=256m -J-Dapple.laf.useScreenMenuBar=true -J-Dsun.java2d.noddraw=true"

startet die Virtual-Machine mit 384 MB Speicher und erlaubt maximal 768 MB. Je nach RAM des Computers kann man so den vom NetBeans-Java genutzten Speicher sinnvoll einstellen.

Zur Website von NetBeans

CakePHP Controller ohne Model und Datenbanktabelle

Wenn man in CakePHP einen Controller erstellt, ohne, dass man die zugehörige Datenbanktabelle anlegt, bekommt man die Fehlermeldung „Database table for model was not found“.

Um diese Fehlermeldung zu umgehen und einen Controller zu erstellen, der kein direktes Model nutzt, ist es jedoch möglich, wie im nachfolgenden Code-Schnipsel gezeigt, den Klassenparameter $uses auf null zu setzen. 

class FooController extends AppController
{
    var $uses = null;             // ohne Datenbanktabelle "foos" und Model "Foo"

    function doSomething()
    {
        $this->loadModel('User'); // andere Models nachladen geht trotzdem
    }
}

Problem mit UTF-8 in CakePHP mit MySQL

CakePHP kann zwar mit UTF-8 umgehen, allerdings werden die Daten nicht als UTF-8 in der MySQL-Datenbank gespeichert. Datensätze sehen dann beispielsweise so aus: „Bündnis 90 Die Grünen“.

Im Konstruktor des AppModel („/app/app_model.php“) kann man dieses Problem aber beheben, indem man „SET NAMES ‚UTF8′“ ausführen lässt, bevor andere Abfragen an die Datenbank gestellt werden.

class AppModel extends Model
{
    function __construct($id=false, $table=null, $ds=null)
    {
        parent::__construct($id, $table, $ds);
        if(!defined('SET_NAMES_UTF8'))
        {
            $this->query("SET NAMES 'UTF8'");
            define('SET_NAMES_UTF8', true);
        }
    }
}

CakePHP-Entwicklung im Allgemeinen und speziell unter OS-X

cake2000_medGrob gesagt ist CakePHP ein MVC-Framework in PHP. Es unterstützt Validierung, Internationalisierung und bietet eine automatischer Objektserialisierung in die Datenbank. Mit CakePHP kann man Model, Controller und Views generieren backen. Besonders praktisch ist, dass man mit CakePHP die notwendigen Objekte und Seiten für ein voll funktionstüchtiges CRUD (Change Read Update Delete) inklusive Admin-Interface erstellen kann. 

Seit ich es vor einem Jahr entdeckt habe, möchte ich keine PHP-Anwendung mehr ohne CakePHP machen. CakePHP ist Open-Source, klein, klar, gut programmiert, anständig dokumentiert und relativ leicht verständlich. Es beschleunigt nicht nur die Entwicklung ungemein, sondern sorgt auch mit einem klaren Benennungs-Schema dafür, dass der Code sauber und übersichtlich bleibt. 

Installation

Zur Installation wird CakePHP lediglich entpackt und dann in den htdocs-Ordner des Webservers kopiert. In dem entpackten Ordner befindet sich eine im Finder unsichtbare .htaccess-Datei, die unbedingt mit kopiert werden muss. Falls die Startseite nach der Installation so aussieht, als hätte sie kein CSS, wurde das wahrscheinlich vergessen.

CakePHP läuft sowohl mit MAMP, als auch mit XAMMP. Alle weiteren, für die Installation notwendigen Dinge, wie Datenbank-Konfiguration und Verzeichnisberechtigungen, werden nach Aufruf der Startseite in der Installations-URL im Browser angezeigt. 

Nach der Installation sollte die Startseite so grün, wie im folgenden Screenshot aussehen.

cakephp-installation

Backen

Mit CakePHP lassen sich Model-Objekte, Controller und die CRUD-GUI-Seiten automatisch aus in der Datenbank angelegten Entities generieren. Dazu geht man mit dem Terminal in den Ordner /cake/console und kann nun die gewünschten PHP-Klassen mit

/Applications/xampp/xamppfiles/bin/php cake.php bake 

wenn man XAMPP benutzt oder 

/Applications/MAMP/bin/php5/bin/php cake.php bake

mit MAMP, generieren.

Datenbank

Datenbanktabellen sollten für CakePHP immer in der Mehrzahl benannt werden, also „users“ oder „locations“. CakePHP kann einen von der Datenbank generierten Primärschlüssel nutzen. Unter MySQL beispielsweise legt man einen auto_increment key mit

`id` int(11) NOT NULL auto_increment,

an. Wenn man dem Primärschlüssel den typ CHAR(36) gibt, generiert CakePHP beim Speichern der Objekte automatisch eine UUID als Primärschlüssel. 

Die Felder „created“ und „modified“ werden von CakePHP automatisch  mit dem Datum der Erstellung und der letzten Änderung des Datensatzes befüllt. 

`created` datetime NOT NULL,
`modified` datetime NOT NULL,

Folgende Datentypen können für das CakePHP-Model im Fall von MySQL genutzt werden:

CakePHP Datentyp MySQL Datentyp
primary_key NOT NULL auto_increment
string varchar(255)
text text
integer int(11)
float float
datetime datetime
timestamp datetime
time time
date date
binary blob
boolean tinyint(1)

Die Datentypen für weitere Datenbanken, wie PostgreSQL, DB2 oder Oracle findet man hier im Cookbook

Dokumentation

Weitere Informationen über CakePHP

Ich wünsche frohes backen!

PHP-Seiten bei Auslieferung zippen

Mit zwei einfachen Zeilen in der .htaccess lässt sich der Inhalt von PHP-Seiten bei der Auslieferung automatisch gzippen, was zu einer Reduzierung der Seitengröße um bis zu 90% führen kann.

php_value output_buffering On
php_value output_handler ob_gzhandler

Diese Konfiguration lässt sich auch mit folgenden Zeilen in der php.ini durchführen.

output_buffering = On;
output_handler = ob_gzhandler;

…oder direkt im PHP-Sourcecode, durch Hinzufügen von

<?php
ob_start("ob_gzhandler");
?>

Notwendig für die Funktionsfähigkeit dieser Komprimierung ist die zlib-Erweiterung von PHP. Diese Erweiterung ist aber allgemeiner Standard bei PHP-Hosting-Anbietern.

Dokumentation zu ob_gzhandler auf php.net