8753 sujets

Développement web côté serveur, CMS

Pages :
Bonjour à tous

J'ai un "fichier modèle" en HTML qui a l'allure suivante :

  <head>
      ..........
    <script>$ENGINE$</script>
      ..........
  </head>
   <body>
      ..........
      <script>$DATA$</script>
      ..........
   </body>
</html>

Je dois créer un fichier qui comprend ce modèle avec $ENGINE$ remplacé par le contenu d'un fichier X et $DATA$ par le contenu d'un fichier Y

Ma question : y a-t-il un moyen simple d'écrire cela en PHP ?
Merci de vos conseils
Modifié par PapyJP (12 Jun 2024 - 12:49)
Salut Papy,

Ce que tu décris est un besoin de base.
Tu n'utilises pas de moteur de template ? (Twig, Smarty, Slim, etc.)
Il en existe des dizaines plus ou moins universels selon les langages. Par exemple, moi, sous Node.js j'utilise Pug (mais son support n'est pas optimal sous PHP).

Pour PHP, Twig est un grand classique.
Olivier C a écrit :
Salut Papy,

Ce que tu décris est un besoin de base.
Tu n'utilises pas de moteur de template ? (Twig, Smarty, Slim, etc.)

Non, je ne sais pas ce que c'est, et mon expérience est que plus on utilise de moteurs externes, plus on passe du temps à apprendre des choses qu'on aura vite fait d'oublier si on ne les utilise pas fréquemment.
Je crois que je me suis mal exprimé:
si je voulais envoyer le résultat directement vers le navigateur, il suffirait de transformer le fichier modèle en php et de mettre des include dans le code.

<html>
<head>
      ..........
    <script>
<?php include fichier X; ?>
</script>
      ..........
  </head>
   <body>
      ..........
      <script>
<?php include fichier Y; ?>
</script>
      ..........
   </body>
</html>

Mais ce que je veux faire c'est envoyer le résultat dans un fichier.
Si tu veux le faire à la main, il va falloir te rapprocher de
file_get_contents()
pour lire un fichier (par exemple ton fichier X)
et ensuite faire un str_replace()
pour remplacer ta variable $ENGINE$

On aurait ton fichierModel.html qui serait :
  <head>
      ..........
    <script>$ENGINE$</script>
      ..........
  </head>
   <body>
      ..........
      <script>$DATA$</script>
      ..........
   </body>
</html>

Ensuite un fichier php pour "fusionner" le tout :

// ton fichier x qui contient ce que tu souhaite
$fichierX = 'chemin/vers/fichierX.html';

// on lit le fichier x et le template chez qui tu veux remplacer les variable
$contenuX = file_get_contents($fichierX);
$template = file_get_contents('chemin/vers/fichierModele.html');

// on remplace la fameuse variable
$template = str_replace('$ENGINE$', $contenuX, $template);

// on l'écrit dans un nouveau fichier
file_put_contents('chemin/vers/fichierFinal.html', $template);

echo $template;

Modifié par JENCAL (12 Jun 2024 - 16:47)
Oui, c'est ce que j'avais prévu de faire mais j'espérais qu'il y aurait quelque chose de plus direct.
Mettre le contenu des très gros fichiers X et Y dans des variables n'est pas très efficace.
Dans le cas du premier fichier, la taille est de 223 Ko, le fichier Y fait plusieurs centaines de Ko, dans certains cas plusieurs Mo.
J'ai commencé par essayer sur le premier fichier, qui contient un gros script en .js minifié, je n'arrive pas à le mettre dans une variable, pour je ne sais trop quelle raison.

Mon code actuel est dans la partie admin de mon site, je vais le déplacer dans un répertoire accessible pour pouvoir partager mon code.
Modérateur
Salut,

Olivier C a écrit :
(Twig, Smarty, Slim, etc.)


Slim est un routeur et non un moteur de template. Slim n'est pas un micro framework. C'est un routeur avec injection de dépendance (ce qui fait sa force). Je pense que tu veux parler de Mustache par exemple.

En soi, PHP est un moteur de template relativement basique. Quand les besoins sont simples, php suffit amplement. C'est vrai que Twig ou même Smarty (c'est du php masqué), c'est sexy.
Modifié par niuxe (12 Jun 2024 - 18:01)
Bonsoir,

Une autre stratégie que tu peux essayer, plutôt que de t'amuser avec str_replace voire preg_replace et donc peut-être plus facile, c'est la tamporisation de sortie (output buffering).


<?php
ob_start();
echo "Tout ce que tu veux !";
includ('xyz.php');
echo "Encore n'importe quoi !";
$data = ob_get_contents();
ob_end_clean();
file_put_contents('fichier.html', $data);
?>


IL n'empêche que ce n'est quand même pas hyper adapté aux gros fichiers, car le contenu va s'accumuler en mémoire puis être copié une seconde fois dans $data. Prévoir au moins 3 ou 4 fois autant de mémoire que la taille totale de la sortie attendue.
Modifié par QuentinC (12 Jun 2024 - 18:20)
Je suis arrivé à faire fonctionner le programme avec le fichier X, je verrai avec le fichier Y plus tard.
C'est bien le code auquel je pensais, à base de file_get_contents, str_replace, etc.
Un peu lourd...
Modifié par PapyJP (12 Jun 2024 - 19:31)
QuentinC a écrit :
Bonsoir,

Une autre stratégie que tu peux essayer, plutôt que de t'amuser avec str_replace voire preg_replace et donc peut-être plus facile, c'est la temporisation de sortie (output buffering).

.........

Il n'empêche que ce n'est quand même pas hyper adapté aux gros fichiers, car le contenu va s'accumuler en mémoire puis être copié une seconde fois dans $data. Prévoir au moins 3 ou 4 fois autant de mémoire que la taille totale de la sortie attendue.

oui, c'est à ce genre de solution que je pensais.
Est-ce vraiment plus consommateur en mémoire que de mettre tous les fichiers dans des variables et faire de la chirurgie ?
niuxe a écrit :
Slim est un routeur et non un moteur de template. Slim n'est pas un micro framework. C'est un routeur avec injection de dépendance (ce qui fait sa force). Je pense que tu veux parler de Mustache par exemple.

Je connais Mustache. Mais Slim est aussi le nom du moteur de template par défaut de Ruby on Rails. C'est d'ailleurs lui qui a inspiré le moteur Pug.js que j'utilise.
Modifié par Olivier C (12 Jun 2024 - 20:47)
Modérateur
Olivier C a écrit :

Je connais Mustache. Mais Slim est aussi le nom du moteur de template par défaut de Ruby on Rails. C'est d'ailleurs lui qui a inspiré le moteur Pug.js que j'utilise.


Je ne connais pas le monde de Ruby. Je pensais que tu parlais de SlimPHP puisque PapyJP code en php.
Bonsoir,

Perso, j'utilise la methode de QentinC.


<?php

Namespace Controllers;

class HomeController
{
    public function render($pageTitle, $cssFileName): string
    {
        // 'home.php' est le $content à insérer dans 'default.php'
        $viewPath = 'xx/xxx/views/home.php';
        
        ob_start();
            require $viewPath;
        $content = ob_get_clean();

        return $content;
    }
}

default.php

<!DOCTYPE html>
<html lang="fr">
<head>
</head>
<body>
    <?= $content; ?>
</body>
</html>

home.php

<main>
    <h1>démo</h1>
    <div>Lorem, ipsum dolor sit amet consectetur adipisicing elit. 
Dolore excepturi corporis dolorem sapiente numquam earum eius
eum libero, eaque totam!</div>
</main>
Modérateur
alain_47 a écrit :
Bonsoir,

Perso, j'utilise la methode de QentinC.


&lt;?php

Namespace Controllers;

class HomeController
{
    public function render($pageTitle, $cssFileName): string
    {
        // 'home.php' est le $content à insérer dans 'default.php'
        $viewPath = 'xx/xxx/views/home.php';
        
        ob_start();
            require $viewPath;
        $content = ob_get_clean();

        return $content;
    }
}

default.php

&lt;!DOCTYPE html&gt;
&lt;html lang="fr"&gt;
&lt;head&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;?= $content; ?&gt;
&lt;/body&gt;
&lt;/html&gt;

home.php

&lt;main&gt;
    &lt;h1&gt;démo&lt;/h1&gt;
    &lt;div&gt;Lorem, ipsum dolor sit amet consectetur adipisicing elit. 
Dolore excepturi corporis dolorem sapiente numquam earum eius
eum libero, eaque totam!&lt;/div&gt;
&lt;/main&gt;


Ce n'est pas le controller qui doit faire un rendu. C'est la vue (class View) !

SOLID...
Modifié par niuxe (14 Jun 2024 - 18:38)
Bonjour Niuxe,

Vous avez raison.

En fait, dans mon système, c'est mon fichier index.php qui rend la vue.

Le routeur contrôle l'uri, si c'est ok passe au contrôler qui donne les parametres à la vue qui retourne la vue au controller, et le controller retourne la vue au fichier index (qui est le seul à etre renvoyer en response).

dans mon fichier index.php :

$controllerPath = '\\Controllers\\'.$controler; 
$controller = new $controllerPath;

$content = $controller->render($pageTitle, $cssFileName);

// Affichage de la response
require 'xx/xxx/views/layout/default.php';


mais effectivement, j'aurais pu (dû peut être ?) faire le require directement dans le fichier "vue".

Merci du conseil.
Modifié par alain_47 (15 Jun 2024 - 10:58)
a écrit :
oui, c'est à ce genre de solution que je pensais.
Est-ce vraiment plus consommateur en mémoire que de mettre tous les fichiers dans des variables et faire de la chirurgie ?


Non, c'est du même ordre de grandeur.

Ca reste proportionnel à la taille totale des données chargées, ou, dit autrement, c'est linéaire.
Finalement le problème réel était nettement plus complexe que ce que j'expliquais dans le premier post.
J'ai donc dû utiliser une autre façon de faire en utilisant DOMDocument, s'agissant de greffer des balises d'un document dans un autre document.
Merci à tous pour vos messages, ils serviront à une autre occasion.
Hmm! Ce n’est pas si simple.
Comme il s’agit en fait de copier des balises d’un fichier html à un autre, l’utilisation de DOMDocuments et d’importation de balises marche très bien, mais ce qui ne va pas c’est qu’il s’agit parfois de très gros fichiers, le simple chargement d’un très gros fichier dans un DOMDocument prend tellement de temps que ça finit par une erreur 500.
Il’ a falloir revoir la façon de faire.