Frash - Framework PHP 7

a marqué ce sujet comme résolu.

Bonjour,

J’aimerai vous présenter mon framework Frash, que j’ai passé sur PHP 7 afin d’utiliser le typage des paramètres. Je développe ce framework afin que tous les composants indépendants d’un projet (Du core du framework au gestionnaire de tests unitaires) y soient intégrés directement.

Aujourd’hui, j’ai trois repos, pour l’installer, pour le framework et pour la documentation, pas très avancée pour l’instant. J’ai plus de 1000 commits sur le repo du framework ( :D ), plus de 80 issues représentant autant de pistes d’améliorations, et j’ai commencé à utiliser les pull requests, seul, il y a quelques semaines.

J’ai des idées de fonctionnalité à venir, et qui seraient utile : Un BrowserKit (Nom du composant Symfony) ou la création de Mock. Cette dernière servirait principalement pour le gestionnaire de tests unitaires. Le BrowserKit y serait également utile, mais pourrait servir sur d’autres points.

J’ai vu que l’on pouvait créer des sockets en PHP, et c’est une fonctionnalité que je souhaiterai implémenter.

Si le framework commence à vous intéreresser, je place ses liens :

Concernant les fonctionnalités déjà implémentées, on peut compter sur un moteur de templates, un ORM compatible MySQL et PGSQL (J’aimerai pouvoir intégrer MongoDB, mais ça m’a l’air complexe), et j’ai une idée de la façon d’implémenter les jointures.

Si vous souhaitez m’aider, j’ai fait un petit CONTRIBUTING.md qui précise encore quelques pistes d’améliorations - supplémentaires.

Pour ne pas vous laisser sans démonstration :

Un exemple de Routing.php :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
namespace Configuration;
use Frash\Framework\Routing\TreatmentPhp;

class Routing extends TreatmentPhp
{
    public function __construct()
    {
        $this->group([ 'bundle' => 'AppBundle' ], function(){
            $this->group([ 'middleware' => 'Connected' ], function(){
                $this->group([ 'middleware' => 'Admin' ], function(){
                    $this->get('admin', 'AdminController:adminAction');
                });

                $this->get('interface', 'InterfaceController:interfaceAction');
                $this->post('create', 'CreateController:createAction');
            });

            $this->group([ 'middleware' => 'NoConnected' ], function(){
                $this->get('home', 'IndexController:indexAction');
                $this->post('connexion', 'IndexController:connexionAction');
            });

            $this->get('deconnexion', 'IndexController:deconnexionAction');
            $this->post('ajax/route', 'AjaxController:routeAction');
        });
    }
}

Un exemple de vue :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
{{ extend base.tpl }}

{{ part body }}
    <div id="corps">
        <div id="emplac_form_conn_home">
            {{ @form.start }}
                <h2 class="text-info">Connexion</h2>
                {{ @form.ident }}<br>
                {{ @form.password }}
                <div id="form_conn_two_droite">
                    <p id="p_submit_conn">{{ @$form["submit"] }}</p>
                    {{ traduction mdp_oubli }} ? <a href="{{ route mdp_oubli/ }}">{{ traduction mdp_modif }}</a>
                </div>
            {{ @form.end }}
        </div>
    </div>
{{ end_part body }}

Pour l’affichage "simple" de variable, on peut les déclarer par {{ @variable }} ou {{ @$form["submit"] }}. Dans le cas deuxième cas, dans le controller, le paramètre passé serait sous la forme :

1
2
3
4
5
return $this->tpl->view('view.tpl', [
    'form' => [
        'submit' => ...
    ]
];

Une piste d’amélioration serait de ne pas avoir à mettre le "@" lorsqu’on met un "$".

Développer un framework seul n’est pas vraiment motivant, si vous avez PHP 7 et/ou que vous êtes intéressé pour m’aider, je vous invite à fork le framework, et à proposer des issues et des PR. :)

(Pour avoir PHP 7 ( :p ) : Virtualbox Debian, PHP7-FPM via dépôt Dot-deb)

Si vous voulez que je détaille un sujet, demandez :)

Je vous remercie :)

+4 -0

Bonjour,

Ce matin, j’ai merge la version 1.4.16, elle intègre notamment une première version du "BrowserKit" qui, pour l’instant, permet de récupérer ce que renvoie la route ou l’URL indiquée, le response code et le header ($http_response_header).

Je me suis rendu compte après coup qu’il y a deux variables que je n’avais pas changé, c’est un fix bug qui va être mergé ce midi. ^^ Les deux variables (La même : $this->system), dans OrmFactory, renvoyaient une erreur si j’utilisais finder() ou counter(), mauvais namespace ( :D ).

La 1.4.16, sinon, met à jour l’affichage d’Exception, intègre {{ call Bundle:Controller:action }} dans le moteur de templates, unifie les QueryBuilder, Counter et Finder de MySQL et PGSQL (Ce qui a amené au bug de namespace). Lors de l’exécution de la commande Framework:init, vous renseignez les langues disponibles pour la traduction ( "fr/en/de/it/…" ), pour chaque langue indiquée, la commande va générer le fichier de traduction. (TradFr, TradEn, etc…)

Pour finir, j’ai complété légèrement les tests unitaires en ajoutant checkRegex() et checkNotRegex() ainsi qu’une class de tests unitaires pour la class Framework\Utility\Generator.

1
$this->checkRegex('/^([a-zA-Z]*)$/', Generator::get(10, false, true, true, false));

Merci :)

+0 -0

Bonjour,

La version 1.1 de frash-install est en release. Elle permet l’utilisation de la 1.4.17 du framework.

La version 1.4.17 complète la fonctionnalité {{ call }} du moteur de templates, ainsi, vous pourrez mettre {{ call POST route/ }}, par exemple.

Cette version met également en place un "Dispatcher", instancié par le frontcontroller, qui va se charger du DIC, du routing et de l’instanciation du controller et de l’action.

Enfin, il y a une première version introduisant les paramètres personnalisés pour l’action, ainsi, vous pourrez faire :

1
public function indexAction(IndexRepository $index, Finder $finder, Counter $counter, Session $session, ...){

Comme vous pouvez également ne mettre aucun paramètre pour l’action et vous servir uniquement du Dic passé par BaseController.

Merci :)

Salut !

Après un petit moment d’absence, j’ai pu améliorer la 1.4.17.

J’ai ajouté une fonction get() à la méthode Collection. En lui passant un paramètre "key1.key2.key3", get() retourna la valeur de key3 contenue dans key2 qui est contenue dans key1 ^^

1
2
3
4
5
6
7
$arr = [
    'key1' => [
        'key2' => (object) [
            'key3' => true
        ]
     ]
];

Cet exemple retournera donc true.

Un petit ajout est la class StringFormat, qui pour l’instant ne contient que la fonction replace(), elle permettra à terme d’avoir :

1
2
$sf = new StringFormat(' Hello ');
$sf->replace('ll', 'w')->trim()->lcfirst();

Par cette class, j’ai voulu reproduire le "comportement" de Javascript (var.replace().trim()…).

J’ai placé deux fonctions (dump() et predump()) dans un fichier helpers. Ca évite l’instanciation d’une class pour l’appel d’une fonction de débugage. predump() affiche un print_r() entouré par <pre>.

J’ai enfin revu la syntaxe concernant l’affichage de variables dans une vue, à l’extérieur d’une loop. Au lieu de mettre @param, c’est maintenant $param.

Je vous remercie. :)

Bonjour :)

Ca fait un petit moment que j’ai pas donné de nouvelles concernant l’avancée du framework. Il a bien avancé ^^

J’ai notamment intégré les jointures pour PostGreSQL.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
$sel = new Join('table1', [ 'order' => 'table1.nom ASC' ]);
$sel->colJoin('table1.id');
$sel->colJoin('table1.nom');
$sel->colJoin('table1.responsable', 'responsable');
$sel->colJoin('immobilier.nom', 'local');
$sel->colJoin('table3.nom', 'table3_nom');
$sel->colJoin('table3.prenom', 'table3_prenom');
$sel->join('INNER JOIN', 'immobilier', 'table1.immobilier', 'immobilier.id');
$sel->join('LEFT JOIN', 'table3', 'table1.responsable', 'table3.id');
$sel->where('table1.superieur', ':sup')->execute([ $sup ]);

return $this->queryJoin($sel);

Assez classique, et ça retourne un array, d’arrays.

J’ai effectué quelques modifications, notamment dans la syntaxe de parsing du moteur de templates. Désormais, les variables "référencées" dans un foreach du moteur de template peuvent être des arrays multidimensionnels.

La syntaxe donne :

1
{{ foreach $array.other.other2 :: key, data }}

Concernant le Routing, lors de la définition d’une get optionnel ( :id? ), l’on peut ajouter la clé "default"… Pour renseigner une valeur par défaut.

1
$this->get('route/:id?', 'IndexController:organisationAction', [ 'get' => [ 'id' => [ 'type' => 'integer', 'default' => 0 ]]]);

Je vous remercie :)

Bonjour,

J’ai démarré à côté deux projets basés sur le framework, expliquant que je n’ai pas donné d’indications sur l’avancée ce dernier mois ^^

Je viens donc de valider la PR comprenant la version 1.4.20. Une fonctionnalité que j’ai rajouté est en lien avec les deux projets parallèles.

Des bundles dans le dossier src de frash/. Je n’ai pas encore transféré la homepage et la bottom bar dans des bundles. Une fois fait, ça me permettra d’enlever des fonctions dédiées à l’affichage de vues spéciales… situées dans le vendor.

J’ai fait une révision du code pour la compatibilité PSR-2.

J’ai également commencé la création d’une API automatique inspirée sur Loopback. Y’a juste le select all de fonctionnel. L’implémentation d’un moyen de sécurisation permettra le développement, et l’utilisation, d’autres types de requêtes (UPDATE, …).

J’ai enfin mit à jour le générateur de documentation, j’ai corrigé les erreurs. Une prochaine mise à jour du générateur permettra de générer des fichiers plus esthétiques :D

Je vous remercie.

Bonjour,

Depuis le dernier message, j’ai pu transférer la homepage dans un bundle spécial. J’ai également reproduit les class Bundle (Une class AppBundle dans le dossier AppBundle), c’est inspiré de Symfony et ça m’a permit d’alléger de plusieurs fonctions certaines class, comme Templating.

J’espère pouvoir vous redonner plus régulièrement des informations sur les progrès du framework. Je vous remercie.

Salut à vous :)

Alors, oui, ça fait 6 mois que je n’ai pas posté. Mais je reviens avec quelques ajouts au framework. :)

La prise en charge (partielle) de MongoDB.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
use Frash\ORM\MongoDB\QueryBuilder;

class AppRepository extends QueryBuilder
{
    public function updateExample(string $id)
    {
        $upd = $this->newUpdate('database.collection');
        $upd->filter([ '_id' => new \MongoDB\BSON\ObjectID($id) ])->update([ '$push' => [ 'subdocument' => 'value' ]]);

        $this->update($upd);
    }

    public function insertExample(string $name)
    {
        $ins = $this->newInsert('database.collection');
        $ins->setId()->fields([ 'name' => $name ]);

        $this->insert($ins);
    }

    public function findExample(string $id)
    {
        $sel = $this->newSelect('database.collection', [ 'options' => [ 'limit' => 1 ]]);
        $sel->filter([ 'other_id' => $id, 'default' => true ]);

        return $this->find($sel, true);
    }
}

Ca, ce ne sont que des exemples. Dans le findExample(), l’exemple donné est développé pour retourner un seul résultat, enlevons l’array dans le newSelect() et le true dans le $this->find() et ça retournera autant de résultats que Mongo en trouve.

De même, le Delete n’est pas encore prit en charge. Tout comme d’éventuels Finder et Counter que l’on trouve dans l’ORM côté SQL (compatibles MySQL et PGSQL).

La traduction

Désormais, dans une class de Traduction, vous pourrez faire comme ceci :

1
protected $key_test = 'Bonjour {{ $1 }} !';

Ainsi, dans votre vue, en mettant :

1
{{ trad key_test Alix_Speroza }}

Vous obtiendrez "Bonjour Alix_Speroza !".

Faker

J’ai commencé le développement d’un faker, il est pour l’instant très basique mais peut générer des données et les enregistrer dans une base de données SQL.

Documentation

C’était un gros défaut de mon framework je pense, l’absence de documentation est paliée pour les fonctionnalités autres que celles listées ici. :-°

Routing

Une petite fonctionnalité, au lieu de faire :

1
2
$this->get('route', 'Controller:action');
$this->post('meme_route', 'MemeController:memeAction);

Vous pouvez regrouper ces deux lignes :

1
$this->many([ 'get', 'post' ], 'route', 'Controller:action');

Filtres du moteur de template

A l’image de TWIG, vous pouvez attribuer un filtre (Pour l’instant) à une variable affichée. Le seul filtre "officiel" disponible pour l’instant permet de passer la variable en paramètre de la fonction rawurlencode(). Bientôt, il y aura ucfirst(), lcfirst(), etc.

Vous pouvez faire vos propres filtres. Dans Configuration\Service, vous devrez renseigner plusieurs informations sur votre filtre :

1
2
3
4
5
6
'templating' => [
    'filter' => [
            'number_format' => [ 'call' => 'nb', 'class' => 'Bundles\AppBundle\Service\NumberFormatFilter' ]
        ],
    'extension' => []
]

La class du filtre donnera :

1
2
3
4
5
6
7
class NumberFormatFilter
{
    public function define(InitialTemplate $template, $tag)
    {
        return 'number_format('.$tag.', 0, ",", " ")';
    }
}

La méthode define() est obligatoire. Le moteur de template appellera directement cette méthode aussitôt la class du filtre instanciée.

Kernel

Dans Configuration\Config, il y a désormais la clé kernel dans l’array de configuration. Il contient les namespace vers toutes les class Bundle dont a besoin le framework : Les class des bundles à l’intérieur du framework, tout comme les class de vos bundles.

Controller et Service

Dans les paramètres d’une Action, vous pouvez désormais appeler directement un Service, en faisant précéder le nom de la variable par le nom de la class du service.

1
public function exampleAction(ExampleService $ex, ...){}

Condition dans une vue

Dernier ajout plus ou moins important, si vous effectuez une condition dans votre vue, vous pouvez retranscrire un in_array().

1
{{ if $example_array has "value_test" }}

Je vous remercie d’avoir prit le temps pour cette longue lecture. :)

Salut à vous :)

Au début du framework, je ne l’avais pas doté de bundles. Je les ai intégré plus tard. Récemment, j’ai travaillé sur Laravel et Symfony Flex.

Et ça m’a poussé à revenir également en BundleLess. Il est vrai que ça simplifie à la fois le code de l’application (Avis personnel :D ) mais aussi le code interne du framework.

Le prochain chantier du framework devrait tourner autour des entités et de l’ORM.

Bonjour ! :)

J’ai donc continué à développer le framework en bundleless. Concernant la configuration, le paramètre "env" pourra maintenant prendre en valeur "prod" ou "dev". "local" remplacé par "dev", ça me semble plus logique :-° .

Comme je l’avais dit, je me suis concentré surtout sur l’ORM, avec pour inspiration Laravel. J’ai développé les changements cités ci-dessous en développant en même temps un jeu en ligne.

Migration SQL

Et j’ai donc commencé par faire un système de migration, exécutable par la commande console :

php console.php ORM:migration --all

Dans le dossier database/migration (Hiérarchie de dossiers très inspirée :-° ), vous pourrez créer vos class de migration. Dans mon cas, pour ma table user, voici le code de la class :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php
namespace Database\migration;
use Frash\ORM\Database\Migration;

class CreateUserTable extends Migration
{
    public function upload()
    {
        $this->addTable('user', function(){
            $this->increment('id');
            $this->varchar('pseudo')->length(30);
            $this->char('password')->length(40);
            $this->varchar('mail')->length(100);
            $this->bigint('points')->default(20);
            $this->bigint('main_territory')->default(0);
            $this->bigint('current_territory')->default(0);
            $this->smallint('rang')->default(2);

            $this->timeRecord();
            $this->deleteRecord();
        });
    }
}

`

$this->timeRecord() va créer deux colonne "created_at" et "updated_at" dans la table. $this->deleteRecord() créera une colonne "deleted_at".

La class peut s’appeler de la façon dont on veut. Et le système de migration n’est pour l’instant compatible qu’avec MySQL :D

Entity

J’ai revu le fonctionnement des entités et des repositorys. L’on peut instancier une entity ou un repository depuis l’action d’un controller. Et dans un repository, on peut instancier, par exemple, l’entité et le querybuilder dans le __construct.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<?php
namespace App\Repository;
use App\Entity\User;

class UserRepository
{
    public $user;

    public function __construct(User $user)
    {
        $this->user = $user;
    }
}

Concernant l’entité, pour l’instant, il y a seulement plusieurs propriétés à renseigner :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
<?php
namespace App\Entity;
use Frash\ORM\Query\Entity\Entity;

class User extends Entity
{
    public $table = 'user';
    public $primary_key = 'id';

    public $time_record = true;
    public $delete_record = true;

    public $cols = [
        'pseudo', 'password', 'mail', 'points', 'rang'
    ];

    public $defaults = [
        'points' => 20, 'rang' => 2
    ];
}

Dans le repository, ou le controller, vous pouvez créer une requête directement grâce à l’entité. (Avant, il fallait obligatoirement le faire dans le repository, avec le QueryBuilder).

Insert
1
2
3
4
5
6
7
8
9
<?php
public function insertUser(string $pseudo, string $password, string $mail): int
{
    $this->user->pseudo = $pseudo;
    $this->user->password = $password;
    $this->user->mail = $mail;

    return $this->user->insert();
}

Fonctionnalité à venir, si vous mettez true dans ->insert() , ça vous retournera l’entité intégrale avec toutes les colonnes et leur valeur.

Update
1
2
3
4
5
<?php
public function updateRangUser(int $user_id, int $rang)
{
    $this->user->where('id', $user_id)->update([ 'rang' => $rang ]);
}
Select - Premier résultat
1
2
3
4
5
<?php
public function getRangUser(int $user_id): int
{
    return $this->user->where('id', $user_id)->just('rang')->first();
}

Pour ce cas-ci, j’ai utilisé la fonction just() intégrée à l’entity. Ca va tout simplement remplacer le * dans le SELECT * FROM, par les colonnes indiquées.

Count
1
2
3
4
5
<?php
public function countByPseudo(string $pseudo): int
{
    return $this->user->where('pseudo', $pseudo)->count();
}
Where

Concernant le Where, vous pouvez toujours renseigner de cette manière :

1
2
3
<?php
where('id', $user_id);
where('id', '>', $user_id);

S’il n’y pas de troisième paramètre, comme dans la première ligne, le signe de comparaison sera automatiquement "=".

Si vous voulez renseignez plusieurs where d’affilés, et que ce n’est pas un OR (Pas encore intégré), comme Laravel, vous pouvez faire :

1
2
3
4
5
<?php
where([
    [ 'col' => 'dest_id', 'value' => $user_id ],
    [ 'col' => 'type', 'sign' => 'IN', 'value' => [ 'type1', 'type2' ]]
]);

Dans le cas d’un IN, la clé "value" doit obligatoirement être reliée à un array.

On a fait le tour des quelques premières intégrations de l’entity.

Middleware

Dans le routing, vous pouvez faire un $this->group([ 'middleware' => '...' ], function(){}); J’ai intégré la possibilité d’ajouter un paramètre au middleware individuellement pour chaque route.

1
2
3
4
<?php
$this->group([ 'middleware' => '...' ], function(){
    $this->get('route', 'Controller:action', [ 'middleware' => [ 'params' => [ 'test_param' => 'value_test' ]]]);
});

Ainsi, dans votre middleware, vous pourrez récupérer ce paramètre avec $this->params['test_param'].

Webprofiler

Un autre composant du framework que je souhaite développer énormément, c’est un WebProfiler comme celui de Symfony (J’ai de l’ambition :-° ) avec une DebugBar.

La DebugBar est actuellement assez moche et ne donne que le code HTTP, le temps total d’exécution, le controller et l’action.

En bref, tout ça m’aura permit de réorganiser une petite partie du code du framework. Et c’est finit pour la présentation du jour :D

Je vous remercie pour le temps passé à lire ce gros pavé :-° .

+0 -0

Hello,

Cette fois, j’ai surtout revu l’organisation interne du framework. Pour bon nombre de composants du framework, je les ai "singletonisé" :-° afin d’éviter de leur passer d’office dans le constructeur l’instance du Dic, que je passe normalement à toutes les class.

Mais il y a quand même quelques nouveautés.

:…

Qu’est-ce donc ? Avec une route, c’est mieux :

1
$this->get('route/route/:get1/:...', ...);

":get1" est une… Get. :… va servir à obtenir une string de tout ce qui se suit, jusqu’à la fin de l’URL.

"route/route/je_suis_une_get/blabla/route/5/id/7"

":get1" correspondra à "je_suis_une_get" et "…", accessible avec :

1
$this->request->get()->route_end;

"route_end" renverra donc la string "blabla/route/5/id/7", vous pouvez ainsi faire le traitement que vous voulez sur cette string.

Where Entity

Jusqu’à maintenant, si l’on mettait plusieurs paramètres dans une fonction where(), il fallait faire comme ceci :

1
2
3
4
$this->entity->where([
    [ 'col' => 'column', 'sign' => '=', 'value' => $value ],
    [ ... ]
]);

Désormais, plus besoin de mettre les clés "col", "sign" et "value", juste des valeurs. Egalement, si le signe de comparaison est "=", c’est optionnel de l’indiquer. En interne, la fonction mettra "=" d’office si le "sous-array" n’a que deux clés.

Maintenance et Profiler

Deux fonctionnalités à développer, un mode maintenance qui permettra d’afficher automatiquement un template par défaut indiquant aux utilisateurs que le site est en maintenance, hormis aux utilisateurs ayant l’IP indiquée dans le fichier Config.php. C’est une feature à développer.

Quant au Profiler, lui aussi est à améliorer. Le but, à l’avenir, va être de déclarer des microtime dans chaque class, que le Profiler enregistrera et retournera sous la forme d’une timeline (Inspiré je l’avoue sur le WebProfiler de Symfony :-° ).

Auth

La dernière fois, mon post pouvait montrer une grande inspiration de Laravel. J’ai continué. Avec une class Auth, fonctionnant basiquement comme celle de Laravel.

Auth::id(); Auth::user()->column;

1
Auth::check([ 'mail' => $mail, 'password' => $no_hashed_password ]);

Dans Config.php, une nouvelle clé, "auth" permet de configurer cette class.

1
2
3
4
5
'auth' => [
    'entity' => 'App\Entity\User',
    'column_password' => 'password',
    'crypt_password' => 'sha1'
],

Auth::check() vérifiera automatiquement si le user avec les paramètres que vous lui passerez en array existe. Si oui, il créera la session frash_auth contenant les valeurs de chaque colonne de l’entité indiquée dans la configuration.

Voilà :)

+0 -0

Hello !

Je ne suis pas sûr, mais ce n’est pas un antipattern, les singletons ? Quand j’avais développé mon mini framework pour le fun (quelques centaines de lignes, rien à voir avec le tien), j’avais mis ma connexion à la BDD, ainsi que la session en singletons, et ça me faisait l’effet d’utiliser des variables globales qui n’étaient là que parce que je n’avais pas réussi à les intégrer autrement dans mon code.

+0 -0

Hello !

Je ne suis pas sûr, mais ce n’est pas un antipattern, les singletons ? Quand j’avais développé mon mini framework pour le fun (quelques centaines de lignes, rien à voir avec le tien), j’avais mis ma connexion à la BDD, ainsi que la session en singletons, et ça me faisait l’effet d’utiliser des variables globales qui n’étaient là que parce que je n’avais pas réussi à les intégrer autrement dans mon code.

melepe

C’est ce que j’ai vu/entendu également. Mon problème, jusqu’à maintenant, c’est que chaque class appelée (Controller, Service, … ou class interne au framework) devait avoir le $dic en paramètre dans le construct, ça impliquait donc de lui passer l’instance intégrale du Dic, avec toutes les instances de class déjà ouvertes par le Dic.

Quand je fais un print_r sur une variable Dic passée en paramètre, c’est un très long print_r ^^ J’arrive même à avoir des "Récursion".

Et comme je ne sais pas si c’est lourd en termes de performance de passer à chaque fois le Dic en paramètre, j’ai voulu essayer le Singleton.

En soit, je pourrais me passer du Singleton, mais ça obligerait de passer en paramètre à chaque class instanciée "$this->dic". Alors que dans les quelques class en Singleton, je charge ce dont j’ai besoin. :)

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte