WEB-d Développement Web

PHP, SQL, HTML5, CSS3, Javascript, Mootools, Référencement, SEO, CMS, e-commerce, Apache, Linux, Ubuntu, ...

Premiers pas avec appserver.io : Installation, servlets et templates

appserver.io est un serveur web écrit en PHP, et conçu spécifiquement pour les grosses applications web PHP.

Il intègre dans ce but une série de fonctionnalités inédites:

Installation

Sur Ubuntu 14.04:


wget https://github.com/appserver-io/appserver/releases/download/1.0.6/appserver-dist_1.0.6-37.deb7_amd64.deb
wget https://github.com/appserver-io/appserver/releases/download/1.0.6/appserver-runtime_1.0.7-74.deb7_amd64.deb
sudo dpkg -i appserver-runtime_1.0.7-74.deb7_amd64.deb
sudo dpkg -i appserver-dist_1.0.6-37.deb7_amd64.deb

Et pour installer les éventuelles dépendances:


sudo apt-get install -f

appserver.io est maintenant installé dans /opt/appserver. La commande suivante permet de configurer le serveur pour le développement:


sudo /opt/appserver/server.php -s dev
sudo service appserver restart

Le serveur appserver.io est maintenant accessible à l'adresse http://localhost:9080

Servlets

L'utilisation des servlets est une fonctionnalité qu'on retrouve généralement dans les serveurs d'applications Java (Tomcat etc.).

Dans la plus-part des serveurs web PHP (Apache mod_php, PHP-FPM,...), l'entièreté du code nécessaire pour construire la page est évalué à chaque requête. Tous les les objets sont donc également instanciés puis détruits à chaque requête. Dans le cas d'applications complexes, cela représente un énorme gaspillage de ressources, et un énorme ralentissement.

Au contraire, dans le cas des servlets, un seul objet est instancié au démarrage du serveur. Lors de chaque requête, la méthode correspondante est appelée (généralement doGet pour les requêtes GET et doPost pour les requêtes POST). Typiquement, lors de l'instanciation de la servlet, on exécute toutes les tâches lourdes de configuration (bootstraping) qui sont communes à toutes les requêtes.

L'inconvénient: comme l'objet servlet est créé uniquement lors du démarrage du serveur, il faut redémarrer celui-ci après chaque modification du servlet.

Pour créer une servlet appserver.io:


cd /opt/appserver/webapps/

# Créer un dossier pour notre application
mkdir myapp
cd myapp

Les servlets doivent se trouver dans le dossier WEB-INF/classes et doivent suivre le standard PSR-0:


mkdir -p WEB-INF/classes/Me/MyApp
cd WEB-INF/classes/Me/MyApp

On peut enfin créer la servlet:

nano IndexServlet.php
<?php
namespace Me\MyApp;
// Doit correspondre au nom du répertoire !!

use AppserverIo\Psr\Servlet\Http\HttpServlet;

/**
 * @Route(name="index", urlPattern={"/index.do", "/index.do*"})
 */

class IndexServlet extends HttpServlet {
  // Le nom de la classe doit correspondre au nom du fichier!

  protected $value;

  public function init(ServletConfig $config) {
    parent::init($config);

    // Et ici, on initialise tout ce qui doit l'être
    // Spécialement si c'est lourd à calculer!!
    $this->value = "Hello";
  }


  public function doGet($servletRequest, $servletResponse) {
    $servletResponse->appendBodyStream("Ceci était long à calculer " . $this->value);
  }
}
 

Après avoir redémarré le serveur, la servlet sera visible à l'adresse

http://localhost:8090/myapp/index.do

Attention, en réalité ce n'est pas la même instance du servlet qui est utilisée à chaque requête, mais bien une copie. Les servlets ne peuvent donc pas être utilisées pour la communication entre les requêtes. L'exemple ci-dessous ne fonctionnera donc pas:


namespace Me\MyApp;

use AppserverIo\Psr\Servlet\Http\HttpServlet;

/**
 * @Route(name="index", urlPattern={"/index.do", "/index.do*"})
 */

class IndexServlet extends HttpServlet {

  protected $value = 0;


  public function doGet($servletRequest, $servletResponse) {
    $servletResponse->appendBodyStream("Nombre de visites: " . $this->value);
    $this->value++;
  }
}
 

Lors de chaque requête $this->value vaudra 0 car c'est une copie du servlet original qui est utilisée...

Templates

Les servlets sont donc extrêmement puissants pour le bootstrapping de l'application. Pour générer la page elle-même, mieux vaut utiliser des templates. Pour comparer avec le modèle MVC, la servlet sert alors de controller, et le template est la vue.


<?php

namespace Me\MyApp;

use AppserverIo\Psr\Servlet\Http\HttpServlet;

/**
 * @Route(name="index", urlPattern={"/index.do", "/index.do*"})
 */

class IndexServlet extends HttpServlet
{

    public function doGet($servletRequest, $servletResponse)
    {
        // récupérer les valeurs à afficher
        $servletRequest->getContext()->setAttribute("NAMES",
            array("Harry", "Hermione", "Ron"));

        // calculer le chemin complet vers le template
        $template = "templates/index.phtml";
        $webappPath = $servletRequest->getContext()->getWebappPath();
        $pathToTemplate = $webappPath . DIRECTORY_SEPARATOR . $template;

        if (!file_exists($pathToTemplate)) {
            throw new \Exception('Requested template not found: ' . $pathToTemplate);
        }

        // créer la page
        ob_start();
        require $pathToTemplate;
        $servletResponse->appendBodyStream(ob_get_clean());
    }
}
 

Et créer le template:

nano /opt/appserver/webapps/myapp/templates/index.phtml
<!DOCTYPE html>
<html lang="en">
<head>
    <title>appserver.io exemple</title>
</head>

<body>
    <h1>Example app</h1>
    <table class="table table-hover">
        <tr><th>Name</th></tr>

        <?php foreach ($servletRequest->getContext()->getAttribute("NAMES") as $name): ?>
        <tr><td><?php echo $name ?></td></tr>
        <?php endforeach; ?>

    </table>
</body>
</html>
 

Articles similaires