Je construis une classe d'utilisateurs pour mon nouveau site Web, mais cette fois, je pensais la construire un peu différemment ...
C ++ , Java et même Ruby (et probablement d'autres langages de programmation) permettent l'utilisation de classes imbriquées / internes dans la classe principale, ce qui nous permet de rendre le code plus orienté objet et organisé.
En PHP, j'aimerais faire quelque chose comme ceci:
<?php
public class User {
public $userid;
public $username;
private $password;
public class UserProfile {
// some code here
}
private class UserHistory {
// some code here
}
}
?>
Est-ce possible en PHP? Comment puis-je y parvenir?
METTRE À JOUR
Si c'est impossible, les futures versions de PHP pourraient-elles prendre en charge les classes imbriquées?
User
, par exemple:public class UserProfile extends User
etpublic class UserHestory extends User
.Réponses:
Intro:
Les classes imbriquées se rapportent aux autres classes un peu différemment des classes externes. Prenant Java comme exemple:
Les classes imbriquées non statiques ont accès aux autres membres de la classe englobante, même si elles sont déclarées privées. En outre, les classes imbriquées non statiques nécessitent une instance de la classe parente pour être instanciée.
Il existe plusieurs raisons impérieuses de les utiliser:
En PHP
Vous pouvez avoir un comportement similaire en PHP sans classes imbriquées.
Si tout ce que vous voulez réaliser est la structure / organisation, comme Package.OuterClass.InnerClass, les espaces de noms PHP peuvent suffire. Vous pouvez même déclarer plusieurs espaces de noms dans le même fichier (bien que, en raison des fonctionnalités de chargement automatique standard, cela ne soit pas conseillé).
Si vous souhaitez émuler d'autres caractéristiques, telles que la visibilité des membres, cela demande un peu plus d'efforts.
Définition de la classe "package"
Cas d'utilisation
Essai
Production:
REMARQUE:
Je ne pense vraiment pas qu'essayer d'émuler les innerClasses en PHP soit une si bonne idée. Je pense que le code est moins propre et lisible. De plus, il existe probablement d'autres moyens d'obtenir des résultats similaires en utilisant un modèle bien établi tel que le modèle Observer, Decorator ou COmposition. Parfois, même un simple héritage suffit.
la source
De vraies classes imbriquées avec
public
/protected
/private
accessibilité ont été proposées en 2013 pour PHP 5.6 en tant que RFC mais ne l'ont pas fait (pas encore de vote, pas de mise à jour depuis 2013 - à partir du 29/12/2016 ):https://wiki.php.net/rfc/nested_classes
Au moins, des classes anonymes ont été intégrées à PHP 7
https://wiki.php.net/rfc/anonymous_classes
À partir de cette page RFC:
Donc, nous pourrions avoir des classes imbriquées dans une version future, mais ce n'est pas encore décidé.
la source
Vous ne pouvez pas faire cela en PHP. Cependant, il existe des moyens fonctionnels pour y parvenir.
Pour plus de détails, veuillez consulter cet article: Comment faire une classe PHP imbriquée ou des méthodes imbriquées?
Ce mode de mise en œuvre est appelé interface fluide: http://en.wikipedia.org/wiki/Fluent_interface
la source
Depuis la version 5.4 de PHP, vous pouvez forcer la création d'objets avec un constructeur privé par réflexion. Il peut être utilisé pour simuler des classes imbriquées Java. Exemple de code:
la source
Selon le commentaire de Xenon à la réponse d'Anıl Özselgin, des classes anonymes ont été implémentées dans PHP 7.0, qui est aussi proche des classes imbriquées que vous l'obtiendrez en ce moment. Voici les RFC pertinentes:
Classes imbriquées (statut: retiré)
Classes anonymes (état: implémenté dans PHP 7.0)
Un exemple de l'article original, voici à quoi ressemblerait votre code:
Ceci, cependant, vient avec une mise en garde très désagréable. Si vous utilisez un IDE tel que PHPStorm ou NetBeans, puis ajoutez une méthode comme celle-ci à la
User
classe:... bye bye auto-complétion. C'est le cas même si vous codez sur des interfaces (le I en SOLID), en utilisant un modèle comme celui-ci:
À moins que vos seuls appels à
$this->profile
proviennent de la__construct()
méthode (ou de toute autre méthode$this->profile
définie dans), vous n'obtiendrez aucune sorte d'indication de type. Votre propriété est essentiellement "cachée" à votre IDE, ce qui rend la vie très difficile si vous comptez sur votre IDE pour l'auto-complétion, le reniflage d'odeur de code et la refactorisation.la source
Vous ne pouvez pas le faire en PHP. PHP prend en charge "include", mais vous ne pouvez même pas faire cela dans une définition de classe. Pas beaucoup de bonnes options ici.
Cela ne répond pas directement à votre question, mais vous pourriez être intéressé par "Namespaces", une \ syntaxe \ hacked \ on \ top \ de PHP OOP: http://www.php.net/manual/en/language .namespaces.rationale.php
la source
Il attend le vote en tant que RFC https://wiki.php.net/rfc/anonymous_classes
la source
Je pense avoir écrit une solution élégante à ce problème en utilisant des espaces de noms. Dans mon cas, la classe interne n'a pas besoin de connaître sa classe parente (comme la classe interne statique en Java). A titre d'exemple, j'ai créé une classe appelée 'User' et une sous-classe appelée 'Type', utilisée comme référence pour les types d'utilisateurs (ADMIN, OTHERS) dans mon exemple. Cordialement.
User.php (fichier de classe utilisateur)
Using.php (Un exemple de la façon d'appeler la 'sous-classe')
la source
Vous pouvez, comme ça, en PHP 7:
la source
Mettez chaque classe dans des fichiers séparés et «exigez» les.
User.php
UserProfile.php
UserHistory.php
la source