PHP - 只能由另一个类实例化的类

时间:2011-08-22 15:14:20

标签: php oop

想象一下这种情况:

class Page {}

class Book {
   private $pages = array();
   public function __construct() {}
   public function addPage($pagename) {
      array_push($this->pages, new Page($pagename));
   }
}

无论如何,我可以确保只有我班级的对象可以实例化页面吗? 就像,如果程序员尝试类似的东西:

$page = new Page('pagename');

脚本会抛出异常吗?

由于

4 个答案:

答案 0 :(得分:4)

嗯,我明白你的观点,但是使用该语言提供的工具,这是不可能的。

您可以做的一件事是,在构建Page时需要Book对象:

class Page {
    public function __construct( Book $Book ) {}
}

class Book {
    public function addPage() {
        $this->pages[] = new Page( $this );
    }
}

答案 1 :(得分:4)

这有点做作,但你可以使用它:

abstract class BookPart
{
    abstract protected function __construct();
}

class Page
    extends BookPart
{
    private $title;

    // php allows you to override the signature of constructors
    protected function __construct( $title )
    {
        $this->title = $title;
    }
}

class Book
    extends BookPart
{
   private $pages = array();

   // php also allows you to override the visibility of constructors
   public function __construct()
   {
   }

   public function addPage( $pagename )
   {
      array_push( $this->pages, new Page( $pagename ) );
   }
}

$page = new Page( 'test will fail' ); // Will result in fatal error. Comment out to make scrip work 

$book = new Book();
$book->addPage( 'test will work' ); // Will work.

var_dump( $book );

答案 2 :(得分:2)

我认为你能得到的最多,就是让Page要求Book作为其中一个构造函数参数,并将它添加到这个Book实例中。这样你就不会有Page个浮动,但它们总是绑定到某本书(尽管在许多Page中仍然可以使用相同的Book

class Book {
  public function addPage($page) {
    if(is_a($page,'Page') {
      $this->pages->push($page);
    } else if (is_string($page)) {
      new Page($this,$page)
    } else {
      throw new InvalidArgumentException("Expected string or 'Page' - ".gettype($page)." was given instead");
    }
  }
}

class Page {
  public function __construct(Book $book, $pagename) {
    $book->addPage($this);
  }
}

虽然看起来很难看......:/

答案 3 :(得分:1)

没有。在PHP中,它是不可能的。即使有可能,开发人员也可以根据自己的需要进行修改并禁用您的执行...