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 i> à a_original.php i>: p> a ensuite créé un nouveau a.php i>: p> ceci échoue car sur Les autres fichiers de projet (WhIC I ne peuvent pas modifier) Utiliser un Comment accomplir cela? P> < / p> y compris code> 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. p>
nécessiter "A.PHP" CODE>. P>
3 Réponses :
Vous pouvez étendre une classe sans modifier son comportement existant: 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. P> P>
Si je ne me trompe pas, Cydo veut quelque chose comme de Ruby's Emptendre code> ou
inclure code>. le code existant i> qui instancie un objet de classe A obtient la version modifiée / améliorée sans changer la base de code.
Comment sur Nouveau eval () code>?
$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";
}
}
Ne fonctionne pas si a_original.php classe est basée sur une autre classe Classe A étend quelque ouvertureClass code> 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!
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]);
}
}
?>