Sınıflar ile PHP Ad ve (dahil)

3 Cevap php

Ben uzatmak gereken bir proje var. Bütün sınıflar ayrı dosyalarda, diğer dosyalarda mevcut kodu yeniden yazmadan bazı sınıfların genişletmek için ihtiyaç vardır. Benim fikrim ad kullanmak oldu ama başarısız. İşte bir örnek:

Ben orijinal A.php class dosyası yeniden adlandırıldı ettik A_Original.php:

class A
{

    public function hello()
    {
    	echo "hello world from Class A\n";
    }

}

Sonra oluşturulan yeni bir A.php:

namespace AOriginal {

    include 'A_Original.php';
}


namespace {

class A
{

    public function hello()
    {
    	echo "hello world from Class A Extended\n";
    }

}

}

This fails because on including the original A_Original.php file the class is dumped to the global scope (thus ignoring the namespace command). I can not modify the existing code inthe A_Original.php file, but renaming is ok.

Diğer proje dosyaları (I değiştiremezsiniz hangi) bir require "A.php" kullanın.

Bunu gerçekleştirmek için?

3 Cevap

Bunu mevcut davranışını değiştirmeden bir sınıf uzatabilirsiniz:

class A {
  public function foo(){

  }
}

class MySubClassOfA extends A {
  public function bar(){

  }
}

Sen MySubClassOfA, yani bar () kendi yöntemleri ekleyebilirsiniz. Sen MySubClassOfA üzerinde foo yöntemini çağırabilir ve MySubClassOfA foo adında bir yöntemi tanımlar sürece, aynı davranış.

Ben hiçbir seçim var ama tüm dosyaların üstüne "namespace xxx;" kod tek satır eklemek sanırım. Aşağıdaki PHP CLI komut yararlı olabilir.

<?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]);
  }
}
?>

Peki eval()?

Yeni A.php

$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";
    }
}