Tag: PHP

Deploy PHP on Heroku

Deploying PHP on Heroku is very easy.

Here is an example how to deploy an easy PHP project (no framework or so) from your GIT repo to Heroku.

Well, first you need to follow the first two steps of the Heroku Get started intructions (Sign up, Install toolbelt).

Then go to your command line and enter the following commands (replace the dummy project name with yours):

heroku create heroku-project-php --stack cedar
  Creating heroku-project-php... done, stack is cedar
  http://heroku-project-php.herokuapp.com/ | git@heroku.com:heroku-project-php.git

Now go to the path of your local GIT repo clone which you want to push to Heroku and add Heroku as remote branch:

git remote add heroku git@heroku.com:heroku-project-php.git
git push heroku master

Finished. Now you should see your running PHP on http://heroku-project-php.herokuapp.com.

How cool is that? :)

Note: Cedar is now the default stack, so you can use: heroku create myapp without –stack cedar now. I don’t know yet if you need to change it for new Heroku deployments.

Have fun trying it out.


Windows Azure: Custom PHP installation

I write this article because of an odyssey of bug tracing concerning my PHP application hosted in the Windows Azure cloud.

Before the Windows Azure SDK 1.6 the configuration of PHP with Fast CGI was done in the Web.config. Here you could define the exact path of your custom PHP.

Now with the SDK 1.6 and the different folder structure defined by the scaffolder, the integration of PHP has changed. The new way is to install PHP automatically by the predefined startup scripts. So you don’t need to put the whole PHP stuff into your package. You just add your php.ini modifications and maybe your special PHP extension DLLs.

Now, when you deploy your package the startup scripts will add some environment variables,  install PHP53, SQLDriverPHP53IIS and PHPManager.

That’s all quite cool, but last week my live application crashed (WORST CASE!) without any modifications by my side. I could not find the problem. A few days ago I recognized that on the compute instances runs a different PHP version than on my local dev environment. I could not figure out how this could happen. But since I know that the startup script uses webpicmdline (Web Plattform Installer for Commandline) to install the PHP stuff (s.o.) it’s clear to me. The WebPI always takes the newest PHP version for installation, and it’s not possible to set up a specific version number. In my case in need PHP 5.3.8 but WebPI installs PHP 5.3.9 which crashes my application with an ugly PHP53_via_FastCGI Error Code 0xc0000005.

Ok, how can I tell Azure to take my PHP version. The only way is to again put the whole PHP folder into the deployment package as explained in this tutorial.

I for my use case I needed to do it a little bit different:

  • I put the PHP folder into MyProject\WebRole\bin\PHP\v5.3\php-cgi.exe
  • The extensions are in MyProject\WebRole\bin\PHP\v5.3\ext\
  • In configureIIS.cmd I changed SET PHP_FULL_PATH=%~dp0php\php-cgi.exe to SET PHP_FULL_PATH=%~dp0PHP\v5.3\php-cgi.exe
  • To add the environment variables I leave add-environment-variables.cmd as it was
  • To set user permission I leave monitor-environment.cmd as it was

These changes bring some small losings (with which I can live):

  • SQLDriverPHP53IIS needs to be installed manually (ext\php_sqlsrv_53_nts_vc9.dll [2]).
  • No IIS PHPManager (Maybe it’s possible to install it by modifing the install-php.cmd).

The startup script part in my ServiceDefinition.csdef now looks like:

    <Startup>
      <Task commandLine="add-environment-variables.cmd" executionContext="elevated" taskType="simple" />
      <Task commandLine="installCustomPHP.cmd" executionContext="elevated" taskType="simple">
        <Environment>
          <Variable name="EMULATED">
            <RoleInstanceValue xpath="/RoleEnvironment/Deployment/@emulated" />
          </Variable>
        </Environment>
      </Task>
      <Task commandLine="monitor-environment.cmd" executionContext="elevated" taskType="background" />
    </Startup>

I renamed the configureIIS.cmd from the tutorial to installCustomPHP.cmd.

One thing: It very strange to make the experience as Azure PHP developer that there are sometime changes within the Azure Plattform which are crashing my live application. And I have no chance to get warned/informed early enough to fix the problems before my customers get a blank page.

Corrections, tips and hints are welcome :)

Links:


Windows Azure and symfony 1.4 important php.ini settings

When you try to get symfony running (for instance with windowsazure4e) there will occur some problems with the deployed version.

I could solve the problems with these very important php.ini settings:

  • Locate the “cgi.force_redirect” setting and remove the comment and set the value to “0“‘ (Note: 0 for IIS and 1 for Apache or iPlanet).
  • Locate the “cgi.fix_pathinfo” setting and remove the comment. Leave the value as “1” (Note: cgi.fix_pathinfo provides full PATH_INFO/PATH_TRANSLATED support for CGI. Previously the behavior of PHP was to set PATH_TRANSLATED to SCRIPT_FILENAME, and to ignore PATH_INFO. For more information on PATH_INFO, see the cgi specs. Setting this to 1 will cause PHP CGI to fix its paths to conform to the spec.).
  • Locate the “fastcgi.impersonate” setting and remove the comment, leave the value as “1” (Note: FastCGI under IIS supports the ability to impersonate security tokens of the calling client. This allows IIS to define the security context that the request runs under.).
  • Locate “extension_dir” and set it to “ext“.

PHP: Symfony Framework Pros&Contras

Im Folgenden werden u.a. die Pros und Contras des Symfony-Frameworks vorgestellt, welches für viele als eine mögliche Alternative zur aktuellen Lösung angesehen wird.

Definition

Das Symfony-Framework wurde von Sensio Labs entwickelt. Es kapselt jahrelange Erfahrung der PHP-Entwicklung und vereinfacht enorm die Entwicklung mittlerer bis großer Web-Projekte. Es ist aus der Idee heraus entstanden das perfekte Tool für Web-Entwickler zu kreieren die Kunden mit hoch performanten Ansprüchen bedienen.

Symfony basiert auf dem MVC Design-Pattern und versucht die Entwickler selbst dazu zu bringen sauberen, gut strukturierten Code zu produzieren. D.h. in Templates nur Präsentationslogik, Controller lediglich als eine Art schlankes Batch-Script zu gebrauchen und die Businesslogik in den Modell- und Form-Klassen zu hinterlegen.

Es bietet zahlreiche Hilfsmittel um die Entwicklungszeit von komplexen Web-Applikationen stark zu reduzieren. Außerdem sind gängige Aufgaben automatisiert, so dass sich die Entwickler mehr auf die Anwendungslogik konzentrieren können. Ziel ist es das Rad nicht immer wieder neu zu erfinden wenn eine neue Web-Applikation entwickelt wird.

Symfony ist komplett in PHP geschrieben und hat sich bereits in zahlreichen Real-World-Projekten bewiesen. Darunter auch High-Demand Webseiten (z.B. delicious.com und answers.yahoo.com, dailymotion.com).

Symfony Features

Symfony wurde entwickelt um die folgenden Anforderungen zu erfüllen:

  • Einfach auf den gängigsten Plattformen zu installieren und konfigurieren.
  • Datenbank-Engine-Unabhängig.
  • Ãœberwiegend einfach zu benutzen aber dennoch flexibel genug um komplexe Klassen zu adaptieren.
  • Verträglich mit den meisten Web-Best-Practises.
  • Stabil genug für Langzeit-Projekte.
  • Sehr lesbarer Code mit phpDocumenter-Kommentaren für einfache Wartung.
  • Einfach zu erweitern. Integration von anderen Code-Bibliotheken ist möglich.
  • Ein Mal geschriebener Code soll möglichst einfach wiederverwendbar sein (Components, Slots).

Webprojekt-Features

  • Symfony Autoloader für .class.php Dateien in lib-Verzeichnissen.
  • Parameter-Holder für saubere Ãœbergabe von http-Request Parametern mit Getter und Setter.
  • Internationalisierungs-Ebene.
  • Die Präsentations-Ebene ist Template-basiert und unterstützt AJAX-Funktionalitäten (jQuery).
  • Formulare lassen sich automatisiert validieren und einfach wiederverwenden.
  • Ausgabefilterung schätzt vor Cross-Site-Scripting durch korrupte Daten.
  • Die Cache-Management-Features reduzieren die Bandbreitennutzung und den Server-Load.
  • Authentifizierungs- und Rechtefeatures vereinfachen die Erstellung von geschätzten Bereichen und ermöglichen Benutzer-Sicherheits-Management.
  • Routing und Smart URLs machen Seitenadressen Suchmaschinen tauglich.
  • E-Mail-Management (SWIFT-Mailer).
  • Benutzerfreundliche Listen durch automatisch generierte Pager, Sortierer und Filter.
  • Factories, Plugins und Events ermöglichen einen hohen Grad der Erweiterbarkeit.

Entwicklungsumgebung und Werkzeuge

Symfony beinhaltet bereits standardmäßig verschiedene Entwicklungsumgebungen und bietet verschiedene Werkzeuge und automatisierte Tasks für gängige Aufgaben der Software-Entwicklung:

  • Code-Generierungs-Werkzeuge sind bestens geeignet für Prototypen und Administrationen.
  • Das eingebaute Unit- und Functional-Testing Framework bietet Tools für Test-Driven-Development-Unterstützung.
  • Das Debug-Panel beschleunigt das Debugging durch das Anzeigen vieler wichtiger Seiten-Informationen die ein Entwickler benätigt (SQL Queries, Ladezeiten, Chaching-Informationen, http-Parameter, Logs, Umgebungsvariablen etc.).
  • Kommandozeilen-Schnittstellen automatisieren das Deployment zwischen zwei Servern.
  • Live-Änderung an den Konfigurationen sind möglich und effektiv.
  • Die Logging- und Exception-Features geben Administratoren Transparenz über die Anwendungsaktivitäten.

Symfony vs. Zend

An dieser Stelle muss zuerst erwähnt werden, dass sich beide Frameworks wohl kaum vergleichen lassen, da sie unterschiedlicher nicht sein könnten.

Wie das .NET Framework ist das Zend Framework (ZF) eine Ansammlung von Funktionen welche zusammen gute Schnittstellen bereitstellen um die komplexesten Anforderungen, die regelmäig auftreten, von Webentwicklern zu befriedigen. Der größte Vorteil aber auch Nachteil von ZF ist, dass es keinen bestimmten Weg bzw. Konventionen vorgibt wie die Anforderungen zu bewerkstelligen sind.

Bei ZF gibt es kaum Code-Generierung und Konfigurationen werden alle im Front-Controller vorgenommen. Symfony (SF) generiert anhand des DB-Schemas eine Menge Code, welcher zunächst die Code-Basis aufbläht aber den Entwicklern viel Zeit erspart. Konfigurationen (wie Authentifizierung, Caching, Layout uvm.) können in hierarchischer Erbreihenfolge von Applikation über Module bis hinunter zur einzelnen Action über YAML-Files vorgenommen werden. ZF lässt einem bei der Ordnerstruktur alle Freiheiten, wohingegen symfony eine strikte Struktur vorgibt. Dies trägt am Anfang nicht zu einer höheren Lernkurve bei, aber die Einheitlichkeit lässt die Entwickler später sehr leicht im Code navigieren.

Symfony hat eine sehr gute und aktuelle online Dokumentation sowie daraus entstandene Begleitbücher. Darüber hinaus ist die Community sehr aktiv und auch bei komplexeren Problemen sehr hilfreich. ZF verfügt leider nicht über so viel Dokumentation und richtet sich sehr stark an die erfahreneren Entwickler die schon sehr geübt sind mit den komplexeren Aspekten der objektorientierten Programmierung.

Im Gegensatz zu ZF hat SF eine sehr aktive Plugin- und Erweiterungs-Community. Man kann sogar ZF-Funktionalitäten über das Zend-Framework-Plugin in Symfony integrieren.

Symfony 1.4 vs Symfony2

Sensio Labs veröffentlicht ein neues Major-Release Symfony2.0, worauf dieser Abschnitt kurz eingeht:

Unterschiede (soweit bekannt):

  • Neues Template-System (Twig), bisher PHP-Files die von den Actions die Template-Variablen erben.
  • Partials und Page-Templates werden nicht mehr unterschieden.
  • Templates unterstützen Vererbung.
  • Actions entsprechen Components (Components sind wiederverwendbar).
  • Kein sfWebRequest Objekt mehr. Ãœber das Routing werden Parameter direkt übergeben.
  • Mit Doctrine 2 wird der Active Record Pattern durch den Entity Pattern ersetzt.
  • Nur noch einen Entity-Manager statt einer Factory (Table Object) pro Model.
  • Logger und Caches von Zend Framework.
  • Für Unit-Tests werden statt Lime PHPUnit Tests verwendet.
  • Mit PHP 5.3 Verwendung von Namespaces etc.
  • Forms bestehen nicht mehr aus Widgets und Validatoren sondern aus Feldern mit Renderern und Validatoren).

Es stellt sich die Frage ob so kurz vor einer grundlegend neuen Version nicht schon diese verwendet werden sollte. Nun, auf der Projekt-Homepage selbst steht, dass Symfony2.0 noch nicht reif ist für den produktiven Einsatz. Das Final-Release ist für ~März 2011 geplant. Es wird empfohlen neue Projekte, mindestens bis zu diesem Termin, mit Symfony 1.4 umzusetzen. Symfony 1.4 (aktuell 1.4.8) wird bis Ende 2012 unterstützt.

Von Symfony 1.0 ist bekannt dass erste Major-Release-Versionen noch voller Kinderkrankheiten stecken, welche erst nach Jahren zufriedenstellend beseitig werden. Symfony 1.4 hat diese Zeit erfolgreich gemeistert und eine treue Anhängerschaft um sich gebildet. Symfony2.0 steht hier noch am Anfang. Symfony versucht immer einen gewissen Grad an Updatefähig zu gewährleisten, vorausgesetzt die Entwickler halten sich so gut es geht an die vorgegebenen Konventionen. Auch kann man schon von vorn herein versuchen so zu entwickeln das ein evtl. Update später leichter möglich ist, wenn man sich mit den Änderung in der Version 2.0 befasst (s.o.).

Kurzum ein neues Projekt sollte derzeit noch mit Symfony 1.4 umgesetzt werden, jedoch mit technischer Voraussicht auf Symfony2.0.

Symfony2 Benchmark Results:

For the “Product” application, Symfony2 is about:

  • 50% faster than Yii 1.1.1
  • 2.5 times faster than symfony 1.4.2
  • 3 times faster than Zend 1.10
  • 6 times faster than CakePHP 1.2.6

Quelle: http://symfony-reloaded.org/fast

Symfony Nachteile

Symfony hat natürlich auch ein paar Nachteile die Beachtung finden sollten:

  • Größe der Framework-Dateien ohne die Modelklassen: ~30MB.
  • Der Einstieg ist vergleichsweise aufwendig, da erst die Strukturen, Konfigurationsmöglichkeiten und nutzbaren Funktionen gelernt werden müssen.
  • Bei komplexeren Aufgaben kommt man nicht umhin sich mit dem Framework-Kern zu befassen.
  • Nicht dokumentierteÄ nderungen am Kern erschweren Framework-Updates.
  • Wenn kein Zugriff auf die Kommandozeile möglich ist muss ggf. ein Weg gefunden werden die Symfony-Tasks (Unit-Test, Model-Klassen generieren, Cache löschen etc.) auf anderem Wege auszuführen.
  • Symfony ist gerade auf dem Sprung in ein neues Major-Release, welches viele Äderungen mit sich bringt. Es kann sein dass die alte Community evtl. an Aktivität verliert.
  • Viele Vorteile des Frameworks (Admin-, Form- CRUD-Generator etc.) sind Abhängig von einem Datenbank-Modell.
  • Template-Files sind nicht alle in einem Verzeichnis. Grafiker müssen sich ggf. mit der Ordnerstruktur auskennen.
  • YAML-Konfigurations-Files sind sehr empfindlich gegenüber Tippfehlern (Leerzeichen).
  • Updates auf neue Versionen sind oft nicht ganz Problemlos.
  • Ungewolltes überschreiben von Konfigurationsdateien über die Hierarchieebenen.

Ist Symfony das richtige für einen Umstieg?

Für einen kleinen Funktionsumfang wäre Symfony wahrscheinlich zu viel des Guten. Es wäre wohl damit getan sich auf eine Businesslogikstruktur zu einigen und ein Template-System zu integrieren. Doch die meisten Plattformen werden sich ohne Zweifel weiter entwickeln, um den professionellen Ansprüchen der Kunden gerecht zu werden. Hier bietet Symfony bereits die nötige Schablone um solch ein Projekt Modul für Modul zu skalieren bis hin zu höchsten High-Demand-Anforderungen. Der Weg ist durch Symfony bereits geebnet und muss mit unseren Ideen nur noch befahren werden.

Es kam die Frage auf, ob man nicht evtl. nur Teile des Frameworks benutzen könnte. Eigentlich sind nahezu alle Symfony-Features für eine moderne Web-Anwendung essentiell. Trotzdem lassen sich über die tiefgreifenden Konfigurationsfiles die meisten Features einfach abschalten.

Natürlich darf dabei nicht vergessen werden, dass ein Framework auch Probleme mit sich bringen kann, wenn die Umgebung oder die Anforderung an das System zu speziell sind. Spontan stellen sich dann Symfony-Erfahrene die Frage nach der korrekten Funktionsweise des Symfony Caches, des Session-Management, Logging oder das Ausführen von Tasks, was bisher Konsolenzugriffe sowie ein beschreibbares Filessystem voraussetzt. Beantworten lässt sich die Frage mit den symfony-Factories, über die sich nahezu alle Standard-Handler, die für die genannten Funktionen zuständig sind, mit eigenen Lösungen überschreiben oder anpassen lassen.

Symfony ist vielleicht nicht die schnellste Lösung, aber unter den umgesetzten Notwendigkeiten, um die eine Webapplikation nicht herumkommt, unübertroffen. Es lässt sich leicht hardwaretechnisch eine Performancesteigerung erreichen, aber es ist sehr schwer einen neuen Entwickler einem existierenden Projekt hinzuzufügen um es performanter zu machen.

Quellen

Bücher

  • A Gentle Introduction to Symfony 1.4 (ISBN-13: 978-2918390305)
  • More with Symfony 1.3 & 1.4 (ISBN-13: 978-2918390176)

Symfony: Propel: Criteria SQL (hibernate sql)

Hi Volks,

today I had a lot of testing with the symfony criteria object. And everyone who knows about the problem to get the raw SQL query out of the criteria object.

There is a toString method, but the result just looks like this:

SELECT FROM media, media_category WHERE media.FEATURED=? AND media.MEDIATYPE IN (?,?) AND 1=1 AND media_category.CID NOT IN (?,?,?,?) AND media.MID=media_category.MID GROUP BY media.MID
Parameters to replace: array (
0 =>
array (
'table' => 'media',
'column' => 'FEATURED',
'value' => true,
),
1 =>
array (
'table' => 'media',
'column' => 'MEDIATYPE',
'value' => 'video',
),
2 =>
array (
'table' => 'media',
'column' => 'MEDIATYPE',
'value' => 'audio',
),
3 =>
array (
'table' => 'media_category',
'column' => 'CID',
'value' => 10,
),
4 =>
array (
'table' => 'media_category',
'column' => 'CID',
'value' => 9,
),
5 =>
array (
'table' => 'media_category',
'column' => 'CID',
'value' => 4,
),
6 =>
array (
'table' => 'media_category',
'column' => 'CID',
'value' => 7,
)
)

And it is very strange to fill the question marks by hand with the related values from the parameters array.

So I wrote a function which does this for me:

function getCriteriaSQL($c, $select = '*')
{
$params = array();
$r = BasePeer::createSelectSql($c, $params);
$o = str_replace('?', '%s', $r);

$ggg = array();
foreach($params AS $e)
{
if(is_integer($e['value']) OR is_bool($e['value']))
{
$ggg[] = $e['value'];
}
else
{
$ggg[] = "'".$e['value']."'";
}
}

$sql = vsprintf($o, $ggg);

$sql = str_replace('SELECT ', 'SELECT '.$select, $sql);

return $sql;
}

I just wanted to share this with you and I appreciate your comments.


Copyright © 2007-2012 iTopia. All rights reserved.
Jarrah theme by Templates Next | Powered by WordPress