Location: PHPKode > scripts > Friendly class > friendly-class/example.php
<?php
/**
 * This example creates tree classes and two function:
 * - class point: has two friendly methods (set_x and set_y);
 * - class line: is a friend class of set_x and set_y methods;
 * - class other: is not a friend class of set_x and set_y methods;
 * - function good: is a friend function of set_x method only;
 * - function bad: is not a friend function of set_x and set_y methods.
 */
require_once('friendly_class.class.php');


/**
 * POINT: has two friendly methods (set_x and set_y).
 */
class point extends friendly_class {
    private $x;
    private $y;

    /**
     * Specify wich method is friendly.
     */
    protected function is_friendly_method($method) {
        switch ($method) {
        case 'set_x':
        case 'set_y':
            return true;
        }
        return false;
    }

    /**
     * Specify wich class is friend of each friendly method.
     */
    protected function is_friend_class($class, $method) {
        switch ($class) {
        case 'line':
            switch ($method) {
            case 'set_x':
            case 'set_y':
                return true;
            }
            break;
        }
        return false;
    }


    /**
     * Specify wich function is friend of each friendly method.
     */
    protected function is_friend_function($function, $method) {
        switch ($function) {
        case 'good':
            switch ($method) {
            case 'set_x':
                return true;
            }
            break;
        }
        return false;
    }

// Simple public methods

    public function __construct($x, $y) {
        $this->set_x($x); // OK: access from owner class
        $this->set_y($y); // OK: access from owner class
    }

    public function get_x() {
        return $this->x;
    }

    public function get_y() {
        return $this->y;
    }

// Friendly methods

    protected function set_x($x) {
        $this->x = (float)$x;
    }

    protected function set_y($y) {
        $this->y = (float)$y;
    }
}


/**
 * LINE:  is a friend class of set_x and set_y methods.
 */
class line {
    private $start;
    private $end;

    public function __construct($x0, $y0, $x1, $y1) {
        $this->start = new point($x0, $y0);
        $this->end   = new point($x1, $y1);
    }

    // Calling friendly method
    public function set_start($x, $y) {
        $this->start->friend_set_x($x);  // OK: line is friend of set_x
        $this->start->friend_set_y($y);  // OK: line is friend of set_y
    }

    // Calling friendly method
    public function set_end($x, $y) {
        $this->end->friend_set_x($x);    // OK: line is friend of set_x
        $this->end->friend_set_y($y);    // OK: line is friend of set_y
    }

    public function get_start() {
        return array($this->start->get_x(), $this->start->get_y());
    }

    public function get_end() {
        return array($this->end->get_x(), $this->end->get_y());
    }
}


/**
 * OTHER: is not a friend class of set_x and set_y methods.
 */
class other {
    private $point;

    public function __construct($x, $y) {
        $this->point = new point($x, $y);
    }

    public function set_point($x, $y) {
        $this->point->friend_set_x($x); // WARNING: other is not friend of set_x
        $this->point->friend_set_y($y); // WARNING: other is not friend of set_y
    }

    public function get_point() {
        return array($this->point->get_x(), $this->point->get_y());
    }
}


/**
 * GOOD: is a friend function of set_x method only.
 */
function good() {
    $g = new point(1, 2);
    $g->friend_set_x(3); // OK: good is friend of set_x
    $g->friend_set_y(4); // WARNING: good is not friend of set_y
    echo '<p>G: '.$g->get_x().','.$g->get_y().' / Expected: 3,2</p>';
}


/**
 * BAD: is not a friend function of set_x and set_y methods.
 */
function bad() {
    $b = new point(3, 4);
    $b->friend_set_x(5); // WARNING: bad is not friend of set_y
    $b->friend_set_y(6); // WARNING: bad is not friend of set_y
    echo '<p>B: '.$b->get_x().','.$b->get_y().' / Expected: 3,4</p>';
}


/// Test friend classes and friend functions
echo '<h1>Test page</h1>';

// Test access from "point" (direct access)
echo '<h2>Test access from "point" (direct access) (2 warnings)</h2>';
$p = new point(1, 2);
$p->friend_set_x(3); // WARNING: can not be called directly
$p->friend_set_y(4); // WARNING: can not be called directly
echo '<p>P: '.$p->get_x().','.$p->get_y().' / Expected: 1,2</p>';
echo '<hr />';

// Test access from "other"
echo '<h2>Test access from "other" (2 warnings)</h2>';
$other = new other(5, 6);
$other->set_point(7, 8); // WARNING!
$point = $other->get_point();
echo '<p>Other: '.$point[0].','.$point[1].' / Expected 5,6</p>';
echo '<hr />';

// Test access from "line"
echo '<h2>Test access from "line" (no warnings)</h2>';
$line = new line(9, 10, 11, 12);
$line->set_start(13, 14);
$line->set_end(15, 16);
$start = $line->get_start();
$end = $line->get_end();
echo '<p>Line Start: '.$start[0].','.$start[1].' / Expected 13,14</p>';
echo '<p>Line End: '.$end[0].','.$end[1].' / Expected 15,16</p>';
echo '<hr />';

// Test access from "bad"
echo '<h2>Test access from "bad" (2 warnings)</h2>';
bad(); // WARNING!
echo '<hr />';

// Test access from "good"
echo '<h2>Test access from "good" (1 warning)</h2>';
good(); // WARNING!
Return current item: Friendly class