Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP - Class that can be instantiated only by another class

Tags:

oop

php

Imagine this scenario:

class Page {}

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

Is there anyway i can make sure only objects of my class Book can instantiate Page? Like, if the programmer tries something like:

$page = new Page('pagename');

the script throws an exception?

Thanks

like image 875
André Alçada Padez Avatar asked Aug 22 '11 15:08

André Alçada Padez


2 Answers

It's a bit contrived, but you could use this:

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 );
like image 199
Decent Dabbler Avatar answered Nov 14 '22 22:11

Decent Dabbler


Well, I see your point, but with the tools provided by the language, this is not possible.

One thing you could do, is require a Book object when constructing a Page:

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

class Book {
    public function addPage() {
        $this->pages[] = new Page( $this );
    }
}
like image 27
Rijk Avatar answered Nov 14 '22 23:11

Rijk