Pourquoi PHP 5.2+ interdire résumé statiques les méthodes de la classe?
Après l'activation des mises en garde strictes en PHP 5.2, j'ai vu une charge de normes strictes mises en garde d'un projet qui a été écrit à l'origine sans une stricte avertissements:
Des Normes strictes: fonction Statique Programme::getSelectSQL() ne doit pas être résumé dans le Programme.classe.inc
La fonction en question appartient à une classe mère abstraite du Programme et est déclarée abstraite statique, car il devrait être mis en œuvre dans ses classes enfant, tels que TVProgram.
Je n'ai trouver des références à ce changement ici:
Chuté résumé statique de la classe de fonctions. En raison d'une erreur, PHP 5.0.x et 5.1.x a permis résumé des fonctions statiques dans les classes. Depuis PHP 5.2.x, seules les interfaces peuvent en avoir.
Ma question est: quelqu'un peut m'expliquer clairement pourquoi il ne devrait pas être un résumé statique de la fonction en PHP?
- De nouveaux lecteurs devraient noter que l'irrationnel restriction a été supprimée en PHP 7.
- Résumé des méthodes statiques Avis supprimé, ne provoque pas d'erreur
Vous devez vous connecter pour publier un commentaire.
méthodes statiques appartiennent à la classe qui les a déclarés. Lors de l'extension de la classe, vous pouvez créer une méthode statique du même nom, mais vous ne sont pas, en fait, la mise en œuvre d'une statique méthode abstraite.
En va de même pour l'extension de toute la classe avec des méthodes statiques. Si vous étendez la classe et de créer une méthode statique de la même signature, vous ne sont pas réellement substitution de la super-classe de la méthode statique
MODIFIER (Sept. 16th, 2009)
Mise à jour sur ce. L'exécution de PHP 5.3, je vois résumé statique est de retour, pour de bon ou de mauvais. (voir http://php.net/lsb pour plus d'info)
CORRECTION (par philfreo)
abstract static
n'est toujours pas autorisé en PHP 5.3, LSB différentes, mais liées.abstract static
peut être utile dans ce cas.C'est une longue et triste histoire.
Lors de PHP 5.2 de la première introduction de cet avertissement, late static bindings n'étaient pas encore dans la langue. Dans le cas où vous n'êtes pas familier avec les late static bindings, notez que ce code ne fonctionne pas de la même façon que vous pouvez attendre de nous:
En laissant de côté le mode strict avertissement, le code ci-dessus ne fonctionne pas. Le
self::bar()
appel dansfoo()
explicitement référence à labar()
méthode deParentClass
, même lorsquefoo()
est appelée comme une méthode deChildClass
. Si vous essayez d'exécuter ce code avec le mode strict off, vous verrez "PHP Fatal error: Impossible d'appeler la méthode abstraite Myclass::bar()".Compte tenu de cela, résumé des méthodes statiques dans PHP 5.2 étaient inutiles. Le tout le point de l'utilisation d'une méthode abstraite est que vous pouvez écrire du code qui appelle la méthode sans le savoir la mise en œuvre qu'il va être à l'appel, et ensuite fournir des implémentations différentes sur les différentes classes enfant. Mais depuis PHP 5.2 offre pas de propre façon d'écrire une méthode d'une classe parent qui appelle une méthode statique de la classe enfant sur lequel elle est appelée, cette utilisation de résumé des méthodes statiques n'est pas possible. Par conséquent, l'utilisation de
abstract static
en PHP 5.2 est un mauvais code, probablement inspiré par une incompréhension de la façon dont leself
mot clé fonctionne. Il était tout à fait raisonnable de lancer un avertissement sur ce.Mais alors PHP 5.3 est venu ajouté dans la capacité à se référer à la classe dans laquelle la méthode a été appelée par le
static
mot-clé (à la différence de laself
mot-clé, qui fait toujours référence à la classe dans laquelle la méthode a été défini). Si vous modifiezself::bar()
àstatic::bar()
dans mon exemple ci-dessus, il fonctionne très bien en PHP 5.3 et au-dessus. Vous pouvez en lire plus à propos deself
vsstatic
à Nouvelle auto vs statique.Avec le mot-clé static ajoutée, l'argument clair pour avoir
abstract static
lancer un avertissement avait disparu. Late static bindings' objectif principal était de permettre à des méthodes définies dans une classe parente, pour appeler des méthodes statiques qui seront définies dans les classes enfant; permettre résumé des méthodes statiques semble raisonnable et cohérent compte tenu de l'existence late static bindings.Vous pouvez toujours, je suppose, faire un cas pour le maintien de l'avertissement. Par exemple, on pourrait dire que depuis PHP vous permet d'appeler des méthodes statiques de classes abstraites, dans mon exemple ci-dessus (même après fixation par le remplacement de
self
avecstatic
) vous êtes exposant une méthode publiqueParentClass::foo()
qui est cassé et que vous ne voulez pas vraiment de les exposer. À l'aide d'un non-statique de la classe - qui est, en faisant toutes les méthodes de de méthodes d'instance et de rendre les enfants deParentClass
tous les singletons ou quelque chose - permettrait de résoudre ce problème, depuisParentClass
, abstrait, ne peut pas être instanciée, et donc ses méthodes d'instance ne peut pas être appelé. Je pense que cet argument est faible (car je pense que d'exposerParentClass::foo()
n'est pas une grosse affaire, et à l'aide de singletons au lieu de la statique des classes est souvent inutilement verbeux et laid), mais vous pourriez raisonnablement en désaccord - c'est un peu subjectif, appel.Donc sur la base de cet argument, les devs PHP gardé l'avertissement dans la langue, non?
Euh, pas exactement.
PHP rapport de bug 53081, ci-dessus, appelé pour que l'avertissement puisse être diminué depuis l'ajout de la
static::foo()
construire en avait fait abstrait des méthodes statiques raisonnable et utile. Rasmus Lerdorf (créateur de PHP) commence par l'étiquetage de la demande que de faux et passe par une longue chaîne de mauvais raisonnement pour tenter de justifier l'avertissement. Puis, enfin, de cet échange:La demande par Rasmus que le code dans son exemple "fonctionne très bien" est faux; comme vous le savez, il jette à un strict mode d'avertissement. Je suppose qu'il a été le test sans le strict mode est activé. Peu importe, une confusion Rasmus gauche la demande fermé par erreur comme "bidon".
Et c'est pourquoi l'avertissement est toujours dans la langue. C'est peut-être pas entièrement satisfaisante explication - vous avez probablement venu ici en espérant y a une justification rationnelle de l'avertissement. Malheureusement, dans le monde réel, parfois, les choix sont nés de banals les erreurs et les mauvaises raisonnement plutôt qu'à partir d'une prise de décision rationnelle. C'est tout simplement un de ces moments.
Heureusement, l'estimable Nikita Popov a supprimé l'avertissement de la langue en PHP 7 dans le cadre de PHP RFC: Reclasser E_STRICT avis. En fin de compte, la santé mentale qui a prévalu, et une fois de PHP 7 est sorti, nous pouvons tous heureusement utilisation
abstract static
sans réception de ce stupide avertissement.Il est très simple de contourner ce problème, ce qui fait réellement sens à partir d'une conception de point de vue. Jonathan a écrit:
Donc, comme vous pourriez le faire:
Et maintenant vous assurer que toute la classe sous-classement MyFoo implémente une méthode statique getInstance, et un public getSomeData méthode. Et si vous n'avez pas de sous-classe MyFoo, vous pouvez toujours mettre en œuvre iMyFoo pour créer une classe avec des fonctionnalités similaires.
static::
peut être utile.abstract static
méthodes, sans PHP râler....implements
🙂Je sais que c'est vieux, mais....
Pourquoi ne pas simplement jeter une exception que le parent de la classe de la méthode statique, de cette façon, si vous ne la supplante pas l'exception en soit la cause.
Je dirais qu'une classe abstraite/interface pourrait être vu comme un contrat entre les programmeurs. Il traite davantage de la façon dont les choses devraient se regarder et à se comporter comme et de ne pas mettre en œuvre effective de la fonctionnalité. Comme on le voit dans php5.0 et 5.1.x ce n'est pas une loi naturelle qui empêche les développeurs php de le faire, mais l'envie d'aller le long de avec d'autres OO modèles de conception dans d'autres langues. Fondamentalement, ces idées tenter de prévenir un comportement inattendu, si l'on est déjà familier avec d'autres langues.
Je ne vois pas de raison d'interdire statique résumé des fonctions. Le meilleur argument qu'il n'y a pas de raison de les interdire, c'est qu'ils sont autorisés en Java.
Les questions sont:
- Sont techniquement réalisable? - Oui, depuis le existé en PHP 5.2 et ils existent en Java.
Donc, on PEUT le faire. DEVRIONS-nous le faire?
- Ont-elles un sens? Oui. Il est donc logique d'appliquer une partie d'une classe et de laisser l'autre partie d'une classe à l'utilisateur. Cela a du sens dans le non-statique fonctions, pourquoi ne devrait-il pas du sens pour les fonctions statiques? Une utilisation de fonctions statiques sont des classes où il ne doit pas y avoir plus d'une instance (singletons). Par exemple un moteur de chiffrement. Il n'a pas besoin d'exister dans plusieurs cas, et il y a des raisons pour éviter cela - par exemple, vous avez à protéger que d'une partie de la mémoire contre les intrus. Il est donc parfaitement logique pour mettre en œuvre une partie du moteur et laisser l'algorithme de chiffrement de l'utilisateur.
Ce n'est qu'un exemple. Si vous êtes habitué à utiliser des fonctions statiques, vous trouverez beaucoup plus.
En php 5.4+ utilisation trait:
et de votre classe à mettre au début:
abstract public static function get_table_name();
dans une caractéristique et d'utiliser ce trait de caractère, au sein de ma classe abstraite sans plus E_STRICT avertissements! Ce continuent de s'appliquer la définition de la méthode statique dans les enfants comme je l'avais espéré. Fantastique!!!!Regarder dans PHP 'Late Static Binding questions. Si vous mettez les méthodes statiques de classes abstraites, vous allez probablement avoir à l'utiliser plus tôt plutôt que plus tard. Il est logique que le strict avertissements vous dire d'éviter d'utiliser cassé fonctionnalités de langage.