12
votes

Conception de la classe de base du modèle OOP: accès statique et non statique

J'essaie de faire une classe de base ... infraction minuscule si vous allez juste pour la pratique

alors je commence par exemple de classe enfant car il a moins de code !! xxx

voici ma classe de base xxx

Voici le problème, je veux faire filtre ou obtenir la méthode (lecture essentiellement à partir de la base de données) statique, puis renvoyez une matrice d'objets de données de base de données xxx

Voici le problème, avec Filtre comme fonction statique __ construct in utilisateur ne sera pas appelé et table_columns , Table_Name sera vide

également dans la méthode Je ne peux pas y accéder à eux, car ils ne sont pas statiques ... je peux faire un mannequin utilisateur Objet dans la méthode du filtre et résolvez ces problèmes, mais il ne se sent pas juste

essentiellement, j'ai un problème de conception toute suggestion est accueillie


6 commentaires

FYI: N'utilisez jamais foreach de si etc ... comme ceci: foreach ($ this-> table_columns comme € Col) . Toujours utiliser des crochets.


@karacsi_maci désolé je ne l'obtiens pas, qu'est-ce que Brakets [] a à voir avec foreach et si est-ce que vous voulez dire des accolades bouclées {} pour si ? J'aime changer ce si (! $ ceci -> $ col) continue; à si (! $ ceci -> $ COL) {continue; }


Désolé, tu as raison, des accolades


Pour référence: martinfowler.com/aacatalog/rowdatagateway.html


Vous n'avez pas à utiliser des accolades si votre bloc de déclaration est une seule ligne. L'utilisation de bretelles facilite l'évité d'éviter les erreurs, mais si vous ne prévoyez que pour votre boucle d'envelopper une ligne de code, ils ne sont pas nécessaires.


BTW, "inster dans". $ Ceci-> Nom de table. "($ Colonne) valeurs ($ valeurs)" doit être "$ this-> Nom de table". Colonne) Valeurs (valeurs $) "


4 Réponses :


1
votes

En général, il est une bonne idée de séparer la logique de stocker et de récupérer les données et la structure des données elles-mêmes en deux classes séparées. Un «référentiel» et un «modèle». Cela rend votre propre nettoyeur de code et corrige également ce problème.

Bien sûr, vous pouvez mettre en œuvre cette structure à bien des égards, mais quelque chose comme celui-ci serait un excellent point de départ: P>

class Repository{
    private $modelClass;

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

    public function get($id)
    {
        // Retrieve entity by ID
        $modelClass = $this->modelClass;
        return new $$modelClass();
    }

    public function save(ModelInterface $model)
    {
        $data = $model->getData();
        // Persist data to the database;
    }
}


interface ModelInterface
{
    public function getData();
}


class User implements ModelInterface;
{
    public int $userId;
    public string $userName;

    public function getData()
    {
        return [
            "userId" => $userId,
            "userName" => $userName
        ];
    }
}

$userRepository = new Repository('User');
$user = $userRepository->get(2);

echo $user->userName; // Prints out the username


1 commentaires

merci j'ai une certaine lecture à faire, je suis une de ces personnes qui ont appris à travailler avec MVC CADRESTS Avant d'apprendre complètement OOP, je ne fais que retourner fondamental, mais je veux éventuellement créer quelque chose comme Laravel Orm



3
votes

Le problème est que l'objet statique n'est pas vraiment "créé" lorsque vous exécutez statiquement.

Si vous voulez que le constructeur fonctionne, mais toujours de manière statique, vous avez besoin d'un "singleton". C'est ici que l'objet est créé une fois, puis vous pouvez réutiliser. Vous pouvez mélanger cette technique de manière statique et non statique (comme vous créez un objet "global" qui peut être partagé).

un exemple est xxx < / Pré>

Chaque fois que cela reçoit le même exemple et se souvient de l'Etat d'avant.

Si vous souhaitez conserver votre base de code avec aussi peu de modifications que possible, vous pouvez créer une variable "initialisée" statiquement - il vous suffit de vous rappeler de l'appeler dans chaque fonction. Bien que cela sonne bien, c'est encore pire qu'un singleton, car il se souvient toujours d'Etat et que vous devez vous rappeler l'initial à chaque fois. Cependant, vous pouvez utiliser ceci mélangé avec des appels statiques et non statiques. xxx

mais lu un peu avant de vous installer sur une structure. La première est bien meilleure que la seconde, mais même si vous l'utilisez, assurez-vous que vos classes singletons peuvent être véritablement couru à tout moment sans dépendance à l'état précédent.

Parce que les deux classes se souviennent d'état, là-bas De nombreux puristes de code vous avertissent de ne pas utiliser de singletons. Vous créez essentiellement une variable globale qui peut être manipulée sans contrôle de n'importe où. (Disclaimer - J'utilise des singletons, j'utilise un mélange de toutes techniques requises pour le travail.)

Google "PHP Singleton" pour une gamme d'opinions et d'autres exemples ou où / où / où ne pas les utiliser. / p>


0 commentaires

2
votes

Je suis d'accord avec beaucoup de vos locaux dans votre code et votre conception. Premier - utilisateur code> devrait être une classe non statique. Deuxièmement - base code> doit avoir une fonction statique qui agit une usine pour les objets code> utilisateur code>.

Permet de concentrer sur cette partie de votre code à l'intérieur de la méthode du filtre P> xxx pré>

Le problème est que les lignes 1 code> et 10 code> tentent d'utiliser ceci code> et que vous voulez savoir la meilleure façon de l'éviter. P>

Le premier changement que je ferais est de changer protégé $ $ Table_Name; code> to const table_name code> Comme dans ce commentaire dans le documents PHP http://php.net/manual/fr/language.oop5.constants.php#104260 . Si vous avez besoin TABLE_NAME CODE> Pour être une variable modifiable, c'est le signe de la mauvaise conception. Cela vous permettra de changer de ligne 1 code> à: p> xxx pré>

pour résoudre le problème en ligne 10 code> - je crois que vous avez Deux bonnes options. P>

Option 1 - constructeur: strong> p>

Vous pouvez réécrire votre constructeur pour prendre un 2e paramètre facultatif qui serait un tableau. Votre constructeur attribuerait ensuite toutes les valeurs du tableau. Vous réécrivez ensuite votre pour code> boucle (lignes 6 code> à 15 code>) à: p> xxx pré>

Et changer votre constructeur sur: p> xxx pré>

option 2 - magie __set strong> p>

Ceci serait similaire à la fabrication de chaque propriété, Mais au lieu d'accéder directement aux propriétés, ils courraient d'abord à travers une fonction que vous avez le contrôle. p>

Cette solution ne nécessite que l'ajout d'une seule fonction à votre code> la classe code> et un petit changement à votre boucle actuelle p> xxx pré>

puis modifier la ligne 10 code> - 11 code> ci-dessus à: p>

foreach($q as $col => $val) {
    $obj->$col = $val
}


0 commentaires

1
votes

Je ne pense pas qu'il y ait quelque chose de mal à votre approche. Cela dit, c'est la façon dont je le ferais: xxx

, puis la classe de base, nous pouvons utiliser une reliure statique tardive ici statique au lieu de auto . xxx

maintenant à la surface, cela semble trivial mais considérez ceci: xxx

ici nous avons un Mise en œuvre complètement différente de ces méthodes à partir de la classe d'utilisateurs. Donc, ce que nous avons fait, c'est forcer la mise en œuvre de ces valeurs dans les cours d'enfant où il appartient.

En outre, en utilisant des méthodes au lieu de propriétés, nous avons un endroit pour mettre la logique personnalisée pour ces valeurs. Cela peut être aussi simple que de retourner un tableau ou d'obtenir les propriétés définies et de filtrer quelques-uns d'entre eux. Nous pouvons également les accéder à l'extérieur de la classe (comme) si nous en avons besoin d'une autre raison pour une autre raison.

Globalement, vous n'étiez pas si loin, vous avez juste besoin d'utiliser statique Reliure statique tardive et méthodes au lieu de propriétés.

http://php.net/manual/fr/language.oop5.late-static-bindings.php

-Notes-

  • Vous avez également orthographié insérer mal inster .
  • Je mettez aussi _ devant des trucs protégés / privés, juste quelque chose que j'aime faire.
  • final est facultatif mais vous pouvez utiliser static au lieu de auto si vous avez l'intention d'étendre la classe enfant plus loin.
  • La méthode du filtre a besoin de travail encore comme vous avez un tableau à la conversion à cordes et ce qui n'est pas.

3 commentaires

Total Nitpicks mais ici ça va. Vous avez dit final est facultatif, mais honnêtement ne marquez jamais une classe comme final sauf si vous vraiment veut y vouloir. Dans ce cas, cela ne devrait jamais être définitif. Le _ devant protégé / privé est un "obsolète" (remarquez le "), il a été utilisé avant l'introduction des niveaux de visibilité dans PHP, dans les anciens jours non-oop, ce n'est pas Nécessaire autant. Il n'y a rien de mal à cela, mais cela favorise les mauvaises habitudes qui doivent mourir. Mes 2 cents, ne sortez pas de votre pitchforks.


@Andrew - lol, j'aime toujours utiliser le _ , il est également plus facile de dire ce qui est public et ce qui n'est pas, juste un Quant Visual, ou peut-être que je suis toujours une petite école. Pour finale, j'ai principalement ajouté qu'en raison de l'utilisation de la reliure statique tardive, dans ce cas (non finale), vous voudrez / j'aurais pu utiliser statique pour ceux-ci, mais je voulais mettre en évidence les différences entre auto et < Code> statique . Par exemple, on peut vouloir les utiliser dans des classes enfant, mais avec soi-même, il peut ne pas donner les valeurs souhaitées. Donc, en le faisant finale, nous pouvons vous assurer que soi-même est utilisé correctement (et puis je peux donner un exemple correct de LSB)


Par celles-ci, je veux dire d'autres utilisateurs, nous voudrions donc faire référence à des propriétés et des méthodes à l'aide de LSB, par exemple auto :: $ _ table_columns comme statique :: $ _ table_columns Au lieu de cela, si nous prévoyons d'étendre cette classe et de modifier davantage ces méthodes ou propriétés. J'ai changé la classe d'utilisateurs secondaire pour montrer que nous pourrions plutôt faire finale sur les méthodes. Et, j'apprécie le commentaire, mais c'est en grande partie un choix de style personnel.