Typo3 4.6.4 Update und Zend Server

Ein kleines Update ist heute veröffentlicht worden. Alle Änderungen sind im Release-Log aufgeführt.

Ich habe seit neustem auf meinem Windows x64 System ein Problem mit dem Zend Server CE (PHP 5.2) 5.6.0 und Typo3 Version 4.6.3. Mit Version 5.5 hat noch alles problemlos funktioniert. Ich weiß nicht, ob es an den “Security Enhancements” in PHP 5.3.9 liegt, aber der Login in den Backend-Bereich von Typo3 ist in dieser Umgebung nicht mehr möglich. Nach Absenden des Login-Formulars erschient eine Meldung ala “Wollen Sie die index.php Datei speichern oder öffnen…”. Darin ist ein 500-HTTP-Status-Code enthalten, jedoch erscheint in den Apache und PHP-Log-Dateien keinerlei Hinweis darauf. In der Ereignisanzeige von Windows sieht das ganz anders aus. Dort scheint die php-cgi.exe einen Fehler zu verursachen.

Ich werde das morgen mit der neuen Typo3-Version testen und auch Bilder und genaue Fehlermeldungen nachliefern.

Update

Eine Aktualisierung auf Typo3 4.6.4 brachte wie vermutet keinen Erfolg. Wie versprochen ein paar Details zu dem Fehler:

Typo3 4.6.3 Login Screen

Typo3 4.6.3 Login Screen

Fehlermeldung nach Login

Fehlermeldung nach Login

 

Inhalt der Datei index.php

Inhalt der Datei index.php
Windows Ereignisanzeige Fehlermeldung

Windows Ereignisanzeige - Fehlermeldung

Nochmal als Text (damit Google das findet):

Name der fehlerhaften Anwendung: php-cgi.exe, Version: 5.3.9.0, Zeitstempel: 0x4ef33bca
Name des fehlerhaften Moduls: php5.dll, Version: 5.3.9.0, Zeitstempel: 0x4ef33bc8
Ausnahmecode: 0xc0000005
Fehleroffset: 0x00092b20
ID des fehlerhaften Prozesses: 0xd1c
Startzeit der fehlerhaften Anwendung: 0x01ccdb33ed105389
Pfad der fehlerhaften Anwendung: C:\Program Files (x86)\Zend\ZendServer\bin\php-cgi.exe
Pfad des fehlerhaften Moduls: C:\Program Files (x86)\Zend\ZendServer\bin\php5.dll
Berichtskennung: f2e4d78f-4728-11e1-bd4d-005056c00008
Noch eine Meldung in der Windows Ereignisanzeige

Noch eine Meldung in der Windows Ereignisanzeige

 

Fehlerbucket , Typ 0
Ereignisname: APPCRASH
Antwort: Nicht verfügbar
CAB-Datei-ID: 0
 
Problemsignatur:
P1: php-cgi.exe
P2: 5.3.9.0
P3: 4ef33bca
P4: php5.dll
P5: 5.3.9.0
P6: 4ef33bc8
P7: c0000005
P8: 00092b20
P9:
P10:

 Update 2:

Das Problem ist vorübergehend gelöst, indem man die Datei /typo3/contrib/RemoveXSS/RemoveXSS.php in der Größe verändert. Schuld daran ist ein PHP-Bug. Einen herzlichen Dank an Jürgen für den Tip (siehe Kommentare).

Formular unter Zend validieren

Ich nehme mal an, dass wir den Rumpf eines Formulars vorliegen haben (zf create form…) und eines der Felder validieren wollen:

class Application_Form_MyForm extends Zend_Form
{
  // initialization
  public function init()
  {
    $this->setMethod('post');
 
    $this->addElement(
      'text', 'myelement', array(
        'label' => 'Mein Element*:',
        'required' => true,
        'filters' => array('StringTrim'),
        'validators' => array(array('stringLength', 
                                    false, array(8, 8)), 
                        array('digits'), 
               array(new Application_Form_Validator_MyValidator()))
      )
    );

Dem Element myelement werden unterschiedliche Validatoren hinzugefügt z. B. das nur Zahlen erlaubt sind (digits). Die Validatoren, die das Zend Framework bereits mitbringt, findet man im Verzeichnis Validate. Interessant ist an dieser Stelle der eigene Validator. Damit das ZF den Validator findet muß man zuerst den Autoloader anpassen. Bei mir liegt die Klasse Application_Form_Validator_MyValidator im Verzeichnis application/forms/validators und ist als MyValidator.php abgespeichert. Die Autoloader-Anweisung in der Bootstrap-Klasse lautet wie folgt:

$loader=$this->getResourceLoader();
$loader->addResourceType('validators', 'forms/validators', 
                         'Form_Validator');

Der Validator selbst leitet von der abstrakten Klasse Zend_Validate_Abstract ab und sieht exemplarisch folgendermaßen aus:

class Application_Form_Validator_MyValidator 
                                 extends Zend_Validate_Abstract
{
  // consts
  const INVALID='invalid';
  //----
  
  // properties
  protected $_messageTemplates = array(self::INVALID=>
                               "'%value%' ist kein gültiger Wert");
  //----
  
  // validation
  public function isValid($value, $context = null)
  {
    $this->_setValue($value);
    // validierung
    if(true) // pseudo code
      return true;
 
    $this->_error(self::INVALID);
    return false;
  }
}

Zugriff auf mehrere Datenbanken unter Zend

Wenn man innerhalb einer Zend Anwendung auf verschiedenen Datenbanken (mysql, mssql, etc.) zugreifen möchte, kann die Verbindungen in der application.ini hinterlegen:

resources.db.adapter = "pdo_mysql"
resources.db.params.host = "localhost"
resources.db.params.username = "xxx"
resources.db.params.password = "yyy"
resources.db.params.dbname = "zzz"
resources.db.isDefaultTableAdapter = true
 
resources.multidb.db1.adapter = "Sqlsrv"
resources.multidb.db1.host = "server-1"
resources.multidb.db1.dbname = "xxx"
resources.multidb.db1.username = "yyy"
resources.multidb.db1.password = "zzz"
resources.multidb.db1.charset = utf8
...

Anschließend kann die Instanz des Adapters geholt werden:

$front=Zend_Controller_Front::getInstance();
$bootstrap=$front->getParam('bootstrap');
$resource=$bootstrap->getPluginResource('multidb');
/**
 * @var Zend_Db_Adapter_Sqlsrv
 */
$db=$resource->getDb('db1');

Super, oder?

Zend Controller produziert JSON

Damit ein Controller in einer Zend Applikation kein Layout ausgibt bzw. auch keine View-Dateien verarbeitet, genügen zwei Zeilen im Controller:

$this->_helper->layout()->disableLayout();
$this->_helper->viewRenderer->setNoRender(true);

Dadurch wird keinerlei Markup ausgegeben.

Ein möglicher Anwendungsfall sind Webseiten, die Inhalte per AJAX nachladen. Das kann mittels jQuery leicht über folgende Funktion realisiert werden:

jQuery.getJSON( url [, data] [, success(data, textStatus, jqXHR)] )

Der Parameter url ruft eine Aktion eines Controllers auf, der eben nur JSON zurückliefert. Dies kann anschließend im Javascript weiterverarbeitet werden.

Update:

Noch einfacher geht es über folgenden Helper:

$this->_helper->json($data);

 

Zend Framework und Liquibase

Wer ein größeres Projekt inklusive verschiedenen Lebenszyklen realisieren will, der muß sich auch um das Datenbankmanagement kümmern. Das Database Change Management Tool Liquibase bietet sich dafür an und ergänzt die fehlende Funktion des Zend-Frameworks. Ich möchte hier beschreiben, wie dies in ein Projekt integriert werden kann. Ich möchte hierbei auf den bereits veröffentlichen Artikel “Das Zend Framework – Ein Startversuch” aufbauen. Desweiteren habe ich eine grobe Beschreibung der Funktionalität von Liquibase in meinem Artikel “Datenbankmigration mit Liquibase” vorgenommen. Continue reading

Das Zend Framework – Ein Startversuch

Nun endlich möchte ich mir das Zend Framework genauer ansehen. Auf der Homepage kann man sich den Zend Server Community Edition herunterladen, der alles beinhaltet was benötigt wird (Webserver, Zend Framework, Verwaltungsoberfläche). Das ist sehr komfortabel und funktioniert auch sofort. Da ich bereits XAMPP zur lokalen Entwicklung nutze, möchte ich nur das Framework verwenden. Im Download-Bereich lade ich mir die Zip-Datei herunter. Dazu benötigt man einen gültigen Login. Anschließend entpacke ich die Dateien und kopiere die Dateien in ein Testprojekt. Schnell noch einen vhosts-Eintrag anlegen und die Windows hosts Datei anpassen und den Apache neustarten, dann ist bereits die Basis vorhanden.

<VirtualHost *:80>
    ServerAdmin mymail@adres.se
    DocumentRoot "C:/wwwroot/zend_test"
    ServerName zendtest.local   
   <Directory "C:/wwwroot/zend_test">
        Options Indexes FollowSymLinks Includes +ExecCGI
        AllowOverride All
        Order allow,deny
        Allow from all
    </Directory>
</VirtualHost>

Im Quick-Start-Tutorial auf der Zend-Seite sind alle weiterenSchritte ausführlich beschrieben. Damit unter PHP das Framework gefunden werden kann, muß man den include_path in der php.ini korrekt setzen. Bei mir sieht das exemplarisch so aus:

include_path = ".;\xampp\php\PEAR;\wwwroot\zend_test\zend\library"

Außerdem muß man den Windows Path anpassen, damit man in der Konsole den Befehl zf ausführen kann:

...;C:\xampp\php;C:\wwwroot\zend_test\zend\bin

Anschließend wechsle ich in der Windows Konsole (cmd) in das Verzeichnis meines Testprojekts und erzeuge ein Grundgerüst mit Hilfe des zf Tools:

zf create project test

Die erzeugte Struktur sieht nun bei mir in Eclipse folgendermaßen aus:

Beispielstruktur eines Zend Testprojekts

Rufe ich nun die Url im Browser auf, erhalte ich bereits folgende Ansicht:

Zend Welcome Darstellung

Fazit: Die Installation funktioniert genauso, wie im Zend Tutorial beschrieben. Dafür gibts bereits dicke Pluspunkte. Mal sehen, auf was für Problem ich bei einem kleinen Testprojekt stoße.

Verwendung von Zend_Tools

Eine kleine Übersicht:

Application erstellen:

(*nix Systemen): % zf create project newproject
(Windows): C:> zf.bat create project newproject

Im folgenden werden nur noch die Linux-Kommandos aufgeführt.

Layouts aktivieren

% zf enable layout

Klasse für Datentabelle:

% zf create db-table Person person

Model Klasse:

% zf create model Person

Controller Klasse:

% zf create controller Person

Formular Klasse:

% zf create form Person

Zusätzliche Aktion:

% zf create action detail Person