web-dev-qa-db-fra.com

Comment obtenir le chemin d'une classe dérivée à partir d'une méthode héritée?

Comment obtenir le chemin de la classe en cours, à partir d'une méthode héritée?

J'ai le suivant:

<?php // file: /parentDir/class.php
   class Parent  {
      protected function getDir() {
         return dirname(__FILE__);
      }
   }
?>

et

<?php // file: /childDir/class.php
   class Child extends Parent {
      public function __construct() {
         echo $this->getDir(); 
      }
   }
   $tmp = new Child(); // output: '/parentDir'
?>

La constante __FILE__ pointe toujours vers le fichier source du fichier dans lequel elle se trouve, quel que soit l'héritage.
Je voudrais obtenir le nom du chemin pour la classe dérivée.

Y a-t-il une élégante manière de le faire?

Je pourrais faire quelque chose comme $this->getDir(__FILE__); mais cela voudrait dire que je devrais me répéter assez souvent. Je cherche une méthode qui place toute la logique dans la classe parente, si possible.

Mettre à jour:
Solution acceptée (par Palantir ):

<?php // file: /parentDir/class.php
   class Parent  {
      protected function getDir() {
         $reflector = new ReflectionClass(get_class($this));
         return dirname($reflector->getFileName());
      }
   }
?>
38
Jacco

En utilisant ReflectionClass::getFileName avec ceci, vous obtiendrez le nom de répertoire sur lequel la classe Child est définie.

$reflector = new ReflectionClass("Child");
$fn = $reflector->getFileName();
return dirname($fn);

Vous pouvez obtenir le nom de classe d'un objet avec get_class() :)

64
Palantir

Oui. S'appuyant sur la réponse de Palantir:

   class Parent  {
      protected function getDir() {
         $rc = new ReflectionClass(get_class($this));
         return dirname($rc->getFileName());
      }
   }
27
Artefacto

N'oubliez pas que depuis la version 5.5, vous pouvez utilisez le mot clé class pour la résolution du nom de classe , ce qui serait beaucoup plus rapide que d'appeler get_class($this). La solution acceptée ressemblerait à ceci:

protected function getDir() {
    return dirname((new ReflectionClass(static::class))->getFileName());
}
11
Ian Bytchek

Si vous utilisez Composer pour le chargement automatique, vous pouvez récupérer le répertoire sans réflexion.

$autoloader = require 'project_root/vendor/autoload.php';
// Use get_called_class() for PHP 5.3 and 5.4
$file = $autoloader->findFile(static::class);
$directory = dirname($file);
8
ya.teck

Vous pouvez également transmettre le répertoire en tant que constructeur arg. Pas très élégant, mais au moins vous ne devez pas travailler avec la réflexion ou le compositeur.

Parent:

<?php // file: /parentDir/class.php
   class Parent  {
      private $directory;

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

      protected function getDir() {
         return $this->directory;
      }
   }
?>

Enfant:

<?php // file: /childDir/class.php
   class Child extends Parent {
      public function __construct() {
        parent::__construct(realpath(__DIR__));
        echo $this->getDir(); 
      }
   }
?>
0
Adrian