PHP - obtenir tous les noms de classe à l'intérieur d'un espace de nom particulier
Je veux obtenir toutes les classes à l'intérieur d'un espace de noms. J'ai quelque chose comme ceci:
#File: MyClass1.php
namespace MyNamespace;
class MyClass1() { ... }
#File: MyClass2.php
namespace MyNamespace;
class MyClass2() { ... }
#Any number of files and classes with MyNamespace may be specified.
#File: ClassHandler.php
namespace SomethingElse;
use MyNamespace as Classes;
class ClassHandler {
public function getAllClasses() {
//Here I want every classes declared inside MyNamespace.
}
}
J'ai essayé get_declared_classes()
à l'intérieur de getAllClasses()
mais MyClass1
et MyClass2
n'étaient pas dans la liste.
Comment pourrais-je le faire?
- avez-vous réussi à trouver une solution à cela? merci.
- Pour une solution voir mon répondre
Vous devez vous connecter pour publier un commentaire.
L'approche générique serait d'obtenir tous les noms de classe entièrement qualifié (classe avec plein d'espace de noms) dans votre projet, puis filtrer par le voulais de l'espace de noms.
PHP offre certaines fonctions natives pour obtenir ces classes (get_declared_classes, etc), mais ils ne seront pas en mesure de trouver des classes qui n'ont pas été chargés (include /require), donc il ne fonctionne pas comme prévu avec les chargeurs automatiques (comme Compositeur par exemple).
C'est un problème majeur de l'utilisation de chargeurs automatiques est très commun.
De sorte que votre dernier recours est de trouver tous les fichiers PHP par vous-même et les analyser pour en extraire de l'espace de noms et de classe:
Si vous suivez PSR 0 ou PSR 4 normes (votre arborescence de répertoire reflète votre espace de noms), vous n'avez pas de filtre à rien: il suffit de donner le chemin d'accès qui correspond à l'espace de noms que vous voulez.
Si vous n'êtes pas un fan de copier/coller le code ci-dessus des extraits, vous pouvez simplement installer cette bibliothèque: https://github.com/gnugat/nomo-spaco .
Si vous utilisez PHP >= 5.5, vous pouvez également utiliser la bibliothèque suivante: https://github.com/hanneskod/classtools .
Mise à jour: Depuis cette réponse, c'est devenu assez populaire, j'ai créé un packagist paquet de simplifier les choses. Il contient en fait ce que j'ai décrit ici, sans la nécessité d'ajouter la classe vous-même ou de configurer les
$appRoot
manuellement. Il peut éventuellement prendre en charge plus que juste le PSR-4.Que le paquet peut être trouvé ici: haydenpierce/classe-finder.
Voir plus d'infos dans le fichier README.
Je n'étais pas heureux avec toutes les solutions ici, donc j'ai fini la construction de ma classe pour gérer cela. Cette solution nécessite que vous:
En un mot, cette classe tente de comprendre où les classes vivent sur votre système de fichiers basé sur les espaces de noms que vous avez définies dans
composer.json
. Par exemple, les classes définies dans l'espace de nomsBackup\Test
sont trouvés dans/home/hpierce/BackupApplicationRoot/src/Test
. Cela peut être de confiance en raison de cartographie de la structure de répertoire de l'espace de noms est requis par le PSR-4:Vous devrez peut-être ajuster
appRoot
pour pointer vers le répertoire qui contientcomposer.json
.Assez intéressant qu'il ne semble pas être une méthode de réflexion qui le fait pour vous. Cependant, je suis venu avec un peu de classe qui est capable de lire les informations d'espace de noms.
Pour ce faire, vous avez à parcourir creux de toutes les classes définies. Puis, nous avons l'espace de noms de la classe et de les stocker dans un tableau avec le nom de la classe elle-même.
La sortie sera:
array(2) { [0]=> string(17) "ClassTwo\ClassTwo" [1]=> string(20) "ClassTwo\ClassTwoNew" }
Tout bien sûr en plus de la NameSpaceFinder classe même si assemblés rapide et sale. Alors n'hésitez pas à nettoyer la
include
mess en utilisant le chargement automatique.get_declared_classes()
ne contiennent déjà de l'auto-chargement des classes. Qui aurait besoin MyClass1 et MyClass2 à être utilisé ("auto-loaded") avant de vous pouvez les trouver.Je pense que beaucoup de gens ont peut-être un problème de ce genre, donc je me suis appuyé sur les réponses de @hpierce et @loïc-faugeron pour résoudre ce problème.
Avec la catégorie décrite ci-dessous, vous pouvez avoir toutes les classes dans un espace de noms ou qu'ils respectent un certain terme.
Dans ce cas, vous devez utiliser Composer pour effectuer l'auto-chargement de classes. À l'aide de la ClassMap disponibles sur elle, la solution est simplifiée.
-o
option pour que cela fonctionne avec toutes les classes.composer dump-autoload -o
Localiser Les Classes De
Une classe peut être localisé dans le système de fichier par son nom et son espace de noms, à l'instar de l'autochargeur n'. Dans le cas normal, l'espace de noms doit dire le chemin d'accès relatif à la catégorie fichiers. Les chemins à inclure sont les points de départ des chemins relatifs. La fonction
get_include_path()
renvoie une liste des chemins à inclure dans une seule chaîne. Chaque chemin peut être testé, si il existe un chemin relatif qui correspond à l'espace de noms. Si le chemin est trouvé, vous connaissez l'emplacement des fichiers de classe.Obtenir Les Noms De Classe
Dès que l'emplacement des fichiers de classe est connu, les classes peuvent être extraites à partir du fichier des noms, parce que le nom d'un fichier de classe devrait être composé du nom de la classe suivi par
.php
.Exemple De Code
Voici un exemple de code pour obtenir tous les noms de classe de l'espace de noms
foo\bar
comme un tableau de chaînes:Je vais donner un exemple qui est effectivement utilisée dans notre Laravel 5 application, mais il peut être utilisé presque partout. L'exemple suivant renvoie les noms de classe avec l'espace de noms, qui peuvent facilement être prises, si ce n'est pas requise.
Légende
Code
Laravel les gens peuvent utiliser
app_path() . '/{{2}}/*.php'
à glob().class_parents
,spl_classes()
etclass_uses
peut être utilisé pour récupérer tous les noms de classeVous pouvez utiliser
get_declared_classes
mais avec un peu de travail supplémentaire.Alors d'abord vous obtenez toutes les classes déclarées et puis vérifier lequel d'entre eux commence avec votre espace de noms.
Note: vous obtiendrez tableau où les touches ne commence pas par 0. Pour arriver à cela, vous pouvez essayer:
array_values($neededClasses);
.App
, la classeAppendIterator
serait inclus aswell.La façon la plus simple devrait être d'utiliser votre propre autochargeur
__autoload
fonction et à l'intérieur de lui enregistrer les classes chargées, les noms. Ne qui Vous convient ?Sinon, je pense que Vous aurez à traiter avec une certaine réflexion méthodes.
__autoload
. exemple:$a = new MyClass1()
. Je sais seulement l'espace de noms, pas les noms de classe.pour symfony, vous pouvez utiliser le Finder Composant:
http://symfony.com/doc/current/components/finder.html
J'ai juste fait quelque chose de similaire, c'est relativement simple, mais peut être construit hors de.
Quelques réponses intéressantes ci-dessus, certaines sont en fait particulièrement complexe pour la tâche proposée.
Pour ajouter un goût différent de ses possibilités, voici un moyen rapide et facile de la non-optimisé en fonction pour faire ce que vous demandez l'aide de la plupart des techniques de base et des déclarations communes, je pense:
Utiliser simplement comme:
J'ai écrit cette fonction suppose que vous êtes pas l'ajout de la dernier "slash" (
\
) sur l'espace de noms, de sorte que vous n'aurez pas à le doubler pour lui échapper. 😉Veuillez noter que cette fonction n'est qu'un exemple et a de nombreux défauts. Basé sur l'exemple ci-dessus, si vous utilisez la "
namespace\sub
" et "namespace\sub\deep
' existe, la fonction retournera toutes les classes de découverte dans les deux espaces (à se comporter comme si elle était récursive). Cependant, il serait simple de s'ajuster et de développer cette fonction pour beaucoup plus que cela, la plupart nécessitant un couple de réglages dans leforeach
bloc.Il peut ne pas être le summum de la code-art nouveau, mais au moins il fait ce qui a été proposé et devrait être assez simple pour être auto-explicatif.
J'espère qu'il contribue à ouvrir la voie pour vous d'obtenir ce que vous cherchez.
Remarque: PHP 5 et 7 convivial.