10
votes

Espace de noms PHP et inclure () avec des classes

Il y a un projet que je dois prolonger. Toutes les classes sont dans des fichiers séparés, je dois étendre certaines des classes sans réécrire le code existant dans d'autres fichiers. Mon idée était d'utiliser des espaces de noms mais j'échoue. Voici un exemple:

J'ai renommé le fichier d'original a.php à a_original.php : xxx

a ensuite créé un nouveau a.php : xxx

ceci échoue car sur y compris l'original A_ORIGINAL.PHP Fichier La classe est larguée vers la portée globale (ignorant ainsi la commande d'espace de noms). Je ne peux pas modifier le code existant au fichier a_original.php, mais le renommage est correct.

Les autres fichiers de projet (WhIC I ne peuvent pas modifier) ​​Utiliser un nécessiter "A.PHP" .

Comment accomplir cela? < / p>


0 commentaires

3 Réponses :


3
votes

Vous pouvez étendre une classe sans modifier son comportement existant: xxx

Vous pouvez ajouter vos propres méthodes à mysubclassofa, c'est-à-dire une barre (). Vous pouvez appeler la méthode FOO sur MySubClassofa et son comportement est identique, sauf si vous définissez une méthode appelée FOO dans MySubClassofa.


1 commentaires

Si je ne me trompe pas, Cydo veut quelque chose comme de Ruby's Emptendre ou inclure . le code existant qui instancie un objet de classe A obtient la version modifiée / améliorée sans changer la base de code.



-4
votes

Comment sur eval () code>?

Nouveau A.PHP STRT> P>

$lines = file('a_original.php');
array_unshift($lines, 'namespace AO;?>');
$string = implode(chr(13).chr(10), $lines);
eval($string);

class A extends AO\A
{   
    public function hello()
    {
        parent::hello();
        echo "hello world from Class A Extended\n";
    }
}


1 commentaires

Ne fonctionne pas si a_original.php classe est basée sur une autre classe Classe A étend quelque ouvertureClass car maintenant cette autre classe doit être dans la même espace de noms - qui ne comprend pas ("quelque purtulass.php") - sa dans la portée mondiale. aaargs. Je suis perdu. Inclure () ne doit pas changer l'espace de noms actuel - mais cela fait!



1
votes

Je suppose que vous n'avez pas d'autre choix mais ajoutez la ligne unique de " Nomspace xxx; code>" CODE sur tous vos fichiers. Le script CLI PHP suivant peut être utile.

<?php
function convert($namespace, $srcdir, $dstdir)
{
  try
  {
    $files = glob("$srcdir/{*,.*}", GLOB_BRACE);

    if ( ! file_exists($dstdir) && ! mkdir($dstdir) )
    {
      throw new Exception("Cannot create directory {$dstdir}");
    }

    if ( ! is_dir($dstdir) )
    {
      throw new Exception("{$dstdir} is not a directory");
    }

    foreach ( $files as $f )
    {
      extract(pathinfo($f)); // then we got $dirname, $basename, $filename, $extension

      if ( $basename == '.' || $basename == '..' )
      {
        continue;
      }

      if ( is_dir($f) )
      {
        $d = $dstdir. substr($f, strlen($srcdir));
        convert($namespace, $f, $d);
        continue;
      }

      print "processing {$f} ... ";

      if ( ($s = file_get_contents($f)) === FALSE )
      {
        throw new Exception("Error reading $f");
      }

      if ( preg_match("/^\s*namespace\s+\S+;/m", $s) )
      {
        print "already has namespace, skip";
      }
      else
      {
        $lines   = preg_split("/(\n|\r\n)/", $s);
        $output  = array();
        $matched = FALSE;

        foreach ( $lines as $s )
        {
          $output[] = $s;

          // check if this is a PHP code?
          if ( ! $matched && preg_match('/<(\?(php )*|%)/', $s) )
          {
            $matched = TRUE;
            print "insert namespace ... ";
            $output[] = "namespace {$namespace};";
          }
        }

        if ( file_put_contents("{$dstdir}/{$basename}" , implode("\n", $output)) === FALSE )
        {
          throw new Exception("Cannot save file {$dstdir}/{$basename}");
        }

        if ( ! $matched )
        {
          print ("not a PHP file, skip.");
        }
        else
        {
          print "done!";
        }
      }

      print "\n";
    }
  }
  catch (Exception $e)
  {
    print 'Error: '. $e->getMessage() .' ('. $e->getCode() .')' ."\n";
  }
}

extract($_SERVER);

if ( $argc < 4 )
{
?>
Usage: php -F <?=$argv[0]?> <namespace> <source_dir(s)> <dst_dir>
Convert PHP code to be namespace-aware
<?
  return;
}
else
{
  for ( $i = 2; $i < $argc - 1; $i++ )
  {
    convert($argv[1], $argv[$i], $argv[$argc-1]);
  }
}
?>


0 commentaires