<?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!
|