Archiv für Kategorie PHP
Neues sf.net-Projekt: h2benchw2csv / Ergebnis der iSCSI Performance-Tests
Die letzten beiden Tage habe ich unser SAN und das dahinter liegende iSCSI-Geraffel ausführlich mit h2benchw von Heise / c’t getestet. Da ich absolut keine Lust hatte, alle Ergebnisse in den Text-Dateien (waren knapp 20 Files) per Hand in Excel einzutippen, frickelte ich mir kurzerhand ein PHP-Script zusammen, dass mir aus den .txt-Dateien von h2benchw eine große CSV-Datei baut. Diese kann dann wiederum in Excel oder irgendeinem anderen Tabellen eingelesen werden.
Weiterhin unterstützt h2benchw2csv - so der Name des kleinen Scripts – die automatische Umwandlung der .ps-Dateien nach .pdf. Dies geschieht mit Hilfe des PDFCreators, der in der %PATH%-Variable verfügbar sein muss. Gegenwärtig ist h2benchw2csv noch im sf.net Approval State, sollte aber morgen oder übermorgen freigeschaltet werden.
Features:
- Umwandeln von h2benchw .txt-Ergebnissen in eine CSV-Datei
- Komplette Inhalte von Verzeichnissen können in der CSV-Datei gespeichert werden
- Deutsch/Englisch
- Umwandlung der h2benchw .ps-Dateien mit Hilfe des PDFCreators nach PDF
- 100% Open Source und Kommandozeile
- Benötigt wird nur PHP – es wird keine zusätzliche Bibliothek benötigt
Zu den Ergebnissen meiner iSCSI-Performance-Messung ist folgendes zu schreiben:
- Round-Robin oder Weighted Path in einem Verbund von 4 Netzwerkkarten auf Client und Server bringen rein gar nichts, wenn sie gemeinsam auf ein Target zugreifen. Die maximale Leserate betrug 75 MByte/s, die maximale Schreibrate 60 MByte/s. Wir gingen eigentlich davon aus, dass mit jeder (Gigabit)-Netzwerkkarte die Performance mitskaliert – also eine NIC: 70 MByte/s, zwei NICs 140 MByte/s u.s.w. Dem ist aber eindeutig nicht so.
- Interessant war hingegen, dass bei 4 Targets und Fail Over der Gesamtdurchsatz auf ca. 200 MByte/s beim Lesen und 170 MByte/s beim Schreiben anstieg.
- Für mich schaut das nach einem Problem im iSCSI Initiator oder -Treiber aus.
- Bonding und Multipath gemeinsam benutzt bringen nichts.
- Die Firmware 1.46 des Areca 1231 kann nun vernünftig mit NTP-Servern umgehen – bringt aber keine bessere Performance
- FileIO ist beim Schreiben geringfügig schneller als BlockIO (2 MByte/s)
- Jumboframes (MTU 9000 auf Windows Server 2003 und 9014 auf DSS) brachten bei uns keinen Performance-Unterschied
- Fail Over ist schneller als Weighted Path, Weighted Path ist schneller als Round Robin
- Keine der vier Intel-Netzwerkkarten wurde unter Windows Server 2003 zu mehr als 50% ausgelastet. Hier gibt es eventuell auch Treiber-Probleme.
- Trotz allem ist unser iSCSI-SAN fix
XCache / PHP liefert falsche Dateien zurück
Ich erwähnte das Problem bereits vor ein paar Tagen: Flo’s Blog ist unter http://prunkster.ecw.de zu erreichen, meiner unter http://wap.ecw.de. Wir beide fahren die Wordpress-Version. Auf dem Server läuft ein PHP 5.3.8 mit der aktuellen XCache-Version.
Das Problem ist nun folgendes: In bestimmten Abständen sind Flo’s-Seiten nicht erreichbar. Im error.log des Apache ist dann zu finden, dass zuerst die richtige Datei geladen wird, er dann aber die Datei im Verzeichnis von wap.ecw.de lädt. Ich vermutete zu Anfang, dass der Fehler im Apache entsteht. Allerdings ist dem nicht so – unter http://xcache.lighttpd.net/ticket/117 gibt es dazu bereits ein Ticket, das genau auf unsere Fehlerbeschreibung zutrifft. Ich hoffe, dass sich die Jungs von XCache mal daran setzen und den Bug irgendwie fixen.
Besonders interessant ist, dass das oben genannte Ticket auf einen Eintrag im PHP-Bugtracker verweist – sich die PHP-Entwickler darum aber nicht kümmern.
Mir ist es mittlerweile auch schon zweimal passiert, dass ein offensichtlicher Bug als “Bogus” abgelehnt worden ist.
Wordpress: Smilies für vorformattierten Text deaktivieren
Der JavaScript Syntax-Highlighter SyntaxHighlighter ist mittlerweile recht bekannt und auch als Plugin für Wordpress verfügbar. Leider ist nun so, dass bestimmte Zeichen in einem Quellcode – z.B. 8); – zu einem Smiley konvertiert werden.
Das sorgt dafür, dass die Smilies den kompletten Quellcode zerstören. Für die Umwandlung von Sonderzeichen sorgt die Funktion wp-includes/formatting.php/convert_smilies($text).
Mit folgendem Code (WP 2.7.1, ab Zeile 1094) werden vorformattierte Texte – d.h. die mit <pre> eingeleitet werden – nicht mehr mit Smilies verunreinigt:
/**
* Convert text equivalent of smilies to images.
*
* Will only convert smilies if the option 'use_smilies' is true and the globals
* used in the function aren't empty.
*
* @since 0.71
* @uses $wp_smiliessearch, $wp_smiliesreplace Smiley replacement arrays.
*
* @param string $text Content to convert smilies from text.
* @return string Converted content with text smilies replaced with images. Pre-formatted text is ignored.
*/
function convert_smilies($text) {
global $wp_smiliessearch, $wp_smiliesreplace, $post;
$output = '';
if ( get_option('use_smilies') && !empty($wp_smiliessearch) && !empty($wp_smiliesreplace) ) {
// HTML loop taken from texturize function, could possible be consolidated
$textarr = preg_split("/(<.*>)/U", $text, -1, PREG_SPLIT_DELIM_CAPTURE);
// capture the tags as well as in between
$stop = count($textarr);// loop stuff
$bInPreFormattedText = FALSE;
for ($i = 0; $i < $stop; $i++) {
$content = $textarr[$i];
// pre-formatted text reached => set flag
if (strpos($content, "<pre") !== FALSE) {
$bInPreFormattedText = TRUE;
}
// pre-formatted text ends => disable flag
if (strpos($content, "</pre>") !== FALSE) {
$bInPreFormattedText = FALSE;
}
if ((strlen($content) > 0) && ('<' != $content{0}) && !$bInPreFormattedText) {
// If it's not a tag and we are not in an <pre>-tag
$content = preg_replace($wp_smiliessearch, $wp_smiliesreplace, $content);
}
$output .= $content;
}
} else {
// return default text.
$output = $text;
}
return $output;
}
Projekt-Plan PDT 2.0
Kurzer Quote aus dem Projektplan, den Roy Ganor gerade veröffentlichte:
• 2.0 M1 – November 03 (done)
• 2.0 M2 – November 24
• 2.0 RC1 – December 08
• 2.0 RC2 – December 14
• 2.0 RC3 – December 23 (tentative)
• 2.0 Release – December 29
PDT: Type Hinting for var with multiple implemented interfaces
Mein Bug-Report für das PDT, der unter https://bugs.eclipse.org/bugs/show_bug.cgi?id=215114 liegt, wurde heute geschlossen – der passende Patch wurde in das CVS comittet.
Sehr schön.
In wenigen Schritten von ISO-8859-1 zu UTF-8
Verfasst von Schakko unter Datenbanken, PHP am 7. Oktober 2008
Ich frickel momentan an der Umstellung meines Blogs und damit steht auch die Umstellung von ISO-8859-1 auf UTF-8 auf dem Plan.
Damit alles wunderbar funktioniert, hier die Vorgehensweise für eine MySQL 5-Datenbank:
- In PDT/ZS als Encoding des Projekts UTF-8 auswählen und Projekt neu builden lassen.
- Eventuell noch einmal mit Notepad++ sich die View-Scripte anschauen und manuell nach UTF-8 konvertieren (Format > Konvertiere zu UTF-8).
- Im head-Tag das obligatorische
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
einfügen.
- Einen Dump der aktuellen MySQL-Datenbank ziehen
- Diesen Dump mit Notepad++ nach UTF-8 konvertieren (s.o.)
- Im Dump CHARSET=latin1 durch CHARSET=utf8 ersetzen
- Neuen Dump einspielen und eventuell beim Connecten mit PHP zur Datenbank SET NAMES ‘utf8′ aufrufen.
- Glücklich sein.
PHP 5.3 alpha 2: parse_ini_file liefert leeres Array
Gerade habe ich die Alpha 2 von PHP 5.3 angetestet und bin gleich über die ersten Fehler gestolpert:
parse_ini_file liefert ein leeres Array, wenn die ini-Datei als UTF-8 gespeichert ist. Ich hab unter http://bugs.php.net/bug.php?id=45991 gleich mal einen Eintrag hinzugefügt.
Der nächste “Fehler” besteht darin, dass pdo_mysql sich nicht mehr mit MySQL < 4.1 verbinden kann.
Dann wird der include_path falsch interpretiert. Enthält der include_path Backslashes -was er zwar nicht sollte, aber in PHP 5.2.x erlaubt war- wird das nachfolgende Zeichen hinter dem Backslash als Meta-Character interpretiert. "dir\trunk" wird in "dir runk" umgewandelt (\t => Tab).
Zu finden unter http://bugs.php.net/bug.php?id=45992.
Als letztes kam dann noch der Fehler, dass die Klasse Zend_Session nicht geladen werden konnte.
PHP kann die Datei Zend/Session/Namespace.php des Zend Frameworks nicht einbinden.
Der Fehler ist ebenfalls im Bugtracker zu finden, und zwar unter http://bugs.php.net/46000.
Fazit: Alpha2 taugt bis jetzt noch nicht viel.
Erstellen einer eigenen Update Site für Eclipse
Da ich gerade am Überlegen bin, ob ich eine eigene Update Site für die Nightly Builds des Eclipse PDTs erstelle, musste ich erst einmal schauen, wie denn der Update-Mechanismus überhaupt funktioniert.
Sobald in Eclipse die URL zu einer Update Site (http://wap.ecw.de/eclipse/update) angegeben wurde, wird dort die Datei site.xml (http://wap.ecw.de/eclipse/update/site.xml) gesucht.
Die site.xml enthält die verfügbaren JAR-Archive und sieht folgendermaßen aus:
PDT Nightly Build Update Site
Die angegebene JAR-Datei enthält folgende Ordnerstruktur:
- /META-INF/MANIFEST.MF
- /META-INF/eclipse.inf
- /eclipse_update_120.jpg
- /epl-v10.html
- /feature.properties
- /feature.xml
- /license.html
Am wichtigsten ist dabei die feature.xml, die z.B. so aussehen kann:
<id="org.eclipse.php_feature" label="%featureName" version="2.0.200808011-7H--9qMqC" provider-name="%providerName" plugin="org.eclipse.php"> %description %license <id="org.eclipse.php.core" download-size="0" install-size="0" version="2.0.200808011"/> <id="org.eclipse.php.debug.core" download-size="0" install-size="0" version="2.0.200808011" unpack="false"/> <id="org.eclipse.php.debug.ui" download-size="0" install-size="0" version="2.0.200808011" unpack="false"/> <id="org.eclipse.php.server.core" download-size="0" install-size="0" version="2.0.200808011" unpack="false"/> id="org.eclipse.php.server.ui" download-size="0" install-size="0" version="2.0.200808011" unpack="false"/> <id="org.eclipse.php.ui" download-size="0" install-size="0" version="2.0.200808011" unpack="false"/> <id="org.eclipse.php" download-size="0" install-size="0" version="2.0.200808011" unpack="false"/> <id="org.eclipse.php.debug.daemon" download-size="0" install-size="0" version="2.0.200808011" unpack="false"/> <id="org.eclipse.php.help" download-size="0" install-size="0" version="2.0.200808011" unpack="false"/>
An sich ist die Umsetzung des Scripts relativ einfach: Am Morgen wird das letzte erfolgreiche Nightly und Integration Build von der Downloadseite des PDT-Projekts geladen, danach wird die ZIP-Datei entpackt und eine neue feature.jar mit der o.g. feature.xml erstellt. Die Plugins müssen dann unter bspw. http://wap.ecw.de/eclipse/update/plugins liegen.
Apache crasht mit Zend Framework RC 1.7 bei Benutzung von Zend_View_Helper_FormElement
Nun musste ich die letzte halbe Stunde einen Bug im Zend Framwork 1.7 RC1 fixen.
Problem war folgendes:
$form = new Zend_Form();
$form->setName('someFormName');
$form->addElement(new Zend_Form_Element_Text('id'));
Sobald der Code-Abschnitt ausgeführt wird, stürzt der komplette Apache ab. Nach dem Verfolgen der einzelnen Methoden-Aufrufe, fand ich die Stelle, die daran schuld ist. In Zend_View_Helper_FormElement Zeile 105 wird folgendes gemacht:
if (isset($info['attribs']['id'])) {
$info['id'] = (string)$info['attribs']['id'];
}
Da aber ‘id’ in dem Sinne meinem Zend_Form_Element_Text entspricht, wird nun das komplette Objekt zum String gecastet. Dies ist nicht Sinn der Sache und führt dazu (trotz toString()-Implementierung), dass PHP (5.2.1) den Code falsch interpretiert und der Apache (2.0.61) abschmiert.
Lösung: Entweder den Code des ZFs so patchen, dass als name-Attribut nicht der Wert ‘id’ benutzt werden darf oder aber einfach selbst nicht mehr den Wert ‘id’ benutzen.
In den ZF-Bugtracker habe ich das bereits eingetragen: http://framework.zend.com/issues/browse/ZF-3825.
Arbeiten bei gefühlten 45 Grad
Verfasst von Schakko unter Ajax, BibaBlog intern, Entwicklung, Java, PHP am 31. Juli 2008
Sommerzeit bedeutet nicht immer Ferienzeit – für mich hieß es in den letzten Tagen: Fehler in unserer IT-Infrastruktur fixen, bis die Tastatur glimmt. Unter anderem konnte die Administrationsoberfläche des McAfee ePO 3.61 nicht mehr aufgerufen werden. Überraschenderweise stellte ich nach einiger Zeit fest, dass unsere MSSQL MSDE-Instanz, auf der das ePO liegt, alle Benutzer aus der Datenbank gedroppt hat. Ich konnte mich weder mit Domänen-Administrator, noch mit sa einloggen. Wie das Problem zustande gekommen ist, ist mir ein Rätsel – aber jetzt läuft wieder alles und ich habe gleich auf das ePO 4.0 geupgradet.
Nebenbei etabliert sich langsam aber sicher Trac als ein gutes Bugtracking-System. Unsere komplette Infrastruktur wird über das Trac-Wiki dokumentiert, alle aufgetretenen Fehler kommen inkl. Lösung in den Bugtracker. Unsere Scripte für Backup, Tools u.s.w. liegen in einem zentralen SVN-Repository, das an das Trac angebunden ist.
Sicherlich ist dieser Lösungsansatz nicht unbedingt ITIL-konform, aber er funktioniert und das ganz gut.
Vor zwei Tagen ist in mir auch langsam die Idee des Deployens unserer Anwendungen gereift. Da alle bestehenden Deployment-Tools nicht direkt unseren Anforderungen entsprechen, habe ich beschlossen, etwas eigenes zu bauen.
Unser Deployment-Client läuft als Java-Tool auf den jeweiligen Deploy-Server. Sobald von einem zentralen Server über REST ein Deployment-Prozess getriggert wird, lädt sich das Tool das jeweils zu deployende Artefakt aus unserem Artefakt-Repository und führt die Installation aus. Alle Artefakte sind als ZIP-Datei verfügbar und besitzen eine deploy.xml-Datei. Diese wiederum benutzt Ant-Tasks.
Florian kümmert sich um den Client, damit er auch mal in den Geschmack einer zu programmierenden Servlet-Anwendung unter Java kommt (eingesetzt wird Java 1.5, Jetty und Ant)
Unser momentaner Praktikant hat in den letzten Tagen von mir die Aufgabe bekommen, sich mit dem Zend Framework, CakePHP, Doctrine und Propel auseinander zu setzen. Für den Serverteil unseres Deyploment-Tools, den ich entwickle, habe ich mich für das Zend Framework und Doctrine entschieden.
Was mir besonders beim Zend Framework fehlt, ist die Möglichkeit des Scaffoldings. Zwar existiert ein Proposal, das ist aber weder ausgereift, noch für den Einsatz mit Doctrine gedacht. Im Internet existiert bis dato auch keine vernünftige Zend_Doctrine_Scaffolding-Klasse.
Deshalb habe ich mich heute Nachmittag daran gesetzt, und eine rudimentäre Klasse zusammenzuschustern. Die Ergebnisse lassen sich sicherlich hier in ein paar Tagen bestaunen.
Die Scaffolding-Klasse werde ich übrigens auch für meinen neuen Blog einsetzen. Sobald die Tage wieder etwas länger und dunkler werden, werde ich die komplette Seite auf das Zend Framework und ebenfalls Doctrine umstellen. Unter anderem ist für die neue Seite Google Maps-Integration, Post-Deployment über XML-RPC an andere Blogs, eine neue Bildergalerie, eventuell Anbindung an das Active Directory der Firma und ein bissel AJAX geplant. Das Design soll weiter bestehen bleiben und natürlich bleiben auch alle Einträge erhalten.
Sag was!