add a note add a note User Contributed Notes
DTcorp dot 2004 at gmail dot com
23-Oct-2006 07:22
It's easy to create a simple emulation of the namespaces or packages support available in java, c++, etc...

<?php
class myPackage {
  
public function myPublicClassEmu() {
      
$this->myPrivateClassEmu();
   }
  
private function myPrivateClassEmu() {
      
$this->myProtectedClassEmu();
   }
  
protected function myProtectedClassEmu() {
       function
myPrivateFunction() {
           echo
'test';
       }

       return
myPrivateFunction();
   }
}

$MyPackage = new myPackage(); // or: new myPackage

$MyPackage->myPublicClassEmu();
?>
This will output:
test

Off course this isn't the same as the namespaces in C++, but does provide the same functionality idea
osculabond at gmail dot com
07-Oct-2006 02:20
A better way to simulate an enum in php5:

<?php
final
class Days {
   const
Sunday    = 0x00000001;
   const
Monday    = 0x00000010;
   const
Tuesday    = 0x00000100;
   const
Wednesday = 0x00001000;
   const
Thursday  = 0x00010000;
   const
Friday    = 0x00100000;
   const
Saturday  = 0x01000000;
   const
Unknown    = 0x00000000;

  
// ensures that this class acts like an enum
   // and that it cannot be instantiated
  
private function __construct(){}
}
?>

This will allow you to do things like:

<?php
$day_to_email
= Days::Thursday;

if(
$day_to_email == Days::Wednesday) echo "Wednesday<br />";
if(
$day_to_email == Days::Thursday) echo "Thursday<br />";
if(
$day_to_email == Days::Friday) echo "Friday<br />";
?>

Which would output:
Thursday

Or if you wanted to get a little fancier you could also do the following:

<?php
$days_to_email
= Days::Monday | Days::Wednesday | Days::Friday;

if(
$days_to_email & Days::Monday) echo "Monday<br />";
if(
$days_to_email & Days::Tuesday) echo "Tuesday<br />";
if(
$days_to_email & Days::Wednesday) echo "Wednesday<br />";
if(
$days_to_email & Days::Thursday) echo "Thursday<br />";
if(
$days_to_email & Days::Friday) echo "Friday<br />";
?>

Which would output:
Monday
Wednesday
Friday
devoid at digital-ritual dot net
09-Sep-2006 04:41
After several hours of trying different patterns I have finally figured out a decent method of emulating the concept of TypeSafe ENUM (Java/C++/etc.) with PHP5. Below is an example from a logging application that I am working on.

<code>
/**
 * First we need to define a class to act as our 'type'
 */
final class LogLevel extends Object {
   private $lvl;
   private $description;
  
   public function __construct($lvl,$desc) {
       $this->lvl = $lvl;
       $this->description = $desc;
   }
  
   public function getDescription() {
       return $this->description;
   }
  
   public function getLevel() {
       return $this->lvl;
   }
  
   public static function createLevel($lvl,$desc) {
       return new LogLevel($lvl,$desc);
   }
  
   public static function getByLevel($lvl) {
       if (gettype($lvl) !== 'int') {
           throw new InvalidArgumentException();
       }
      
       foreach (self::$logLevels as $logLevel) {
           $level = $logLevel;
           if ($lvl < $logLevel->getLevel()) {
               break;
           }
       }
      
       return $level;
   }
}

/**
 * Here is the part where I ran into problems. I need to make 
 * 'constant-values' for the static 'Enum Array' as you can
 * not set a static object-scope variable to the results of
 * a function at classload time as you can in Java. Several
 * people might consider this 'bad-form' in PHP spec, however
 * it is the only way I have found to accomplish this feat.
 */
define('LVL_BASIC', new LogLevel(1,  'BASIC'));
define('LVL_ERROR', new LogLevel(5,  'ERROR'));
define('LVL_WARN',  new LogLevel(10, 'WARN'));
define('LVL_BASIC', new LogLevel(20, 'INFO'));
define('LVL_DEBUG', new LogLevel(50, 'DEBUG'));
</code>

Now we need to add our static 'enum' to the class which acts as our type. This 'Enum' will allow us to get an Enum value by id, description, or any other internal property which is part of your class.

<code>
/**
 * Add this line to the LogLevel Class
 */
private static $logLevels = array(LVL_BASIC, LVL_ERROR, LVL_WARN, LVL_INFO, LVL_DEBUG);
</code>
  
I am sure there is probably a way that I could have accomplished something similar by extending PHP's Array classes however, this seemed a much easier and more abstract approach to the problem.
seva-php at zend dot com
08-Aug-2006 04:35
Semi-proxy-patterned multi inheritance simulation example:

<?php

interface INamed
{
  
public function getName();
}
interface ISon
{
  
public function getFather();
}
interface IFather
{
  
public function getSons();
}

abstract class Named implements INamed
{
  
protected $name;
  
public function __construct($name)
   {
      
$this->name = $name;
   }
  
public function __destruct()
   {}
  
public function getName()
   {
       return
$this->name;
   }
}
abstract class Son implements ISon
{
  
protected $father;
  
public function getFather()
   {
       return
$this->father;
   }
  
public function __construct(IFather $father = null)
   {
      
$this->father = $father;
   }
  
public function __destruct()
   {}
}
abstract class Father implements IFather
{
  
protected $sons = array();
  
public function getSons()
   {
       return
$this->sons;
   }
  
public function __construct($sons = array())
   {
      
$this->sons = $sons;
   }
  
public function __destruct()
   {}
}

class
Man implements INamed, ISon, IFather
{
  
public function __construct($name, IFather $father = null, $sons = array())
   {
      
// note: these are just __construct() calls - not real class initializations
      
Named::__construct($name);
      
Son::__construct($father);
      
Father::__construct($sons);
   }
  
public function __destruct()
   {
      
Named::__destruct();
      
Son::__destruct();
      
Father::__destruct();
   }
  
public function getFather()
   {
       return
Son::getFather();
   }
  
public function getSons()
   {
       return
Father::getSons();
   }
  
public function getName()
   {
       return
Named::getName();
   }
}

$siarhej = new Man('Siaroh', new Man('Adas'), array(new Man('Seva')));

var_dump($siarhej->getName());
var_dump($siarhej->getFather()->getName());
$siarhejSons = $siarhej->getSons();
var_dump($siarhejSons[0]->getName());

?>
markfarquaad at gmail dot com
05-Aug-2006 05:23
Variable Object Attributes instead of variable variables:

Actually I figured this out on PHP 4.3, but I'm sure it works on the current PHP 5+:

If you like using variable variables and would like to use the same functionality with attributes of class objects, here's how you can can get a specific attribute of a specific class with variable OBJECTS:

Let's say this is our class:

class Car
{
   var $brand;
   var $color;
   var $year;
   function Car()
   {
       etc...
   }
}

Let's say we have an object of Class 'Car', my own car, where $brand = 'Ferrari', $color='red', etc.:

$mycar = new Car();

And another 'Car' object, your car, where $brand='Porsche', $color='black', etc.:

$yourcar = new Car();

Now we need a uniform code snippet to access the color attribute of anyone's 'Car', but we would like to change the object dynamically outside the code delivering the color attribute. Here's how:

The variable or dynamic part is the object (the car owner):

$objectName = 'mycar';
or
$objectName = 'yourcar';
etc...

The static reusable code to deliver the color of any object dynamically is:

$objectAttributeName = 'color';
$objectAttribute = ${$objectName}->$objectAttributeName;

Now:

echo $mycar->color;

will deliver exactly the same as:

echo $objectAttribute

THe difference is, with the dynamic version, you do not have to know $objectName in the static code part, while in the non-variable version you must always specify the object name $mycar, $yourcar, etc to access the obeject's attributes.

I hope this helps anyone who likes reusing code like I do.
Mark
01-May-2006 09:06
Members can be added to instances on the fly.
Simply use
$apple= new fruit();
$pear=new fruit();
$apple->color='red';
$pear->smell='sweet';

and $apple only will contain a member (field) color, but $pear only will contain a field smell.

It is not clear however whether members an be added to the class at large on the fly.
26-Apr-2006 10:53
<?php
if (class_exists("cl_test")) return;

echo
"ppppp";

class
cl_test{
  function
cl_test(){
   echo
"quirky...";
  }
}
// class definition ends

?>

although the logic is clear php treats the above code differently.  PHP translates it to:

class cl_test{
  function cl_test(){
   echo "quirky...";
  }
} // class definition ends

if (class_exists("cl_test")) return;

echo "ppppp";

If you must have the previous logic to work you are forced to have the following code:

if (!class_exists("cl_test")) {

     echo "ppppp";

     class cl_test{
       function cl_test(){
           echo "quirky...";
       }
     } // class definition ends
}
epeterson5 at student dot gsu dot edu
08-Oct-2005 01:46
This isn't explicity noted anywhere, I don't think.
If you use a variable after the "->" part of a class attribute call, it will parse the variable as a string to assign/compare that class attribute:

<?php
class User {
   var
$test;
   var
$test2;
}
 
$user1 = new User();
$user2 = new User();
$user1->test = "user1's test";
$user1->test2 = "user1's test2";
$user2->test = "user2's test";
$user2->test2 = "user2's test2";

print_r($user1); print_r($user2);

foreach(
$user1 as $key => $value)
  
$user2->$key = $value;

print_r($user1); print_r($user2);
?>

Which outputs:

User Object: user1
   [test] => user1's test
   [test2] => user1's test2
User Object: user2
   [test] => user2's test
   [test2] => user2's test2
User Object: user1
   [test] => user1's test
   [test2] => user1's test2
User Object: user2
   [test] => user1's test
   [test2] => user1's test2

This is particularly useful when you want to assign a different instance of the same class to $this- I have a standard method that I call when I need to do that:

<?php

  
function assignToThis($new)  {
       foreach(
$new as $key => $value)
          
$this->$key=$value;
   }
?>
turgut85 at hotmail dot com
30-Jun-2005 09:04
<?PHP

// How to hold objects in an arrayList and retrieve it //
// Interface implementation //

class Data {
  
  
public $Name;
  
public $Age;
  
public $Address;
  
  
public function __construct($Name,$Age,$Address) {
      
$this->Name = $Name;
      
$this->Age = $Age;
      
$this->Address = $Address;
   }
  
  
public function __destruct() {
       echo
"Default Constructor...\n";
   }

}

$ArrayList = array();

$ArrayList[0] = new Data("John McDonald","65","Address");
$ArrayList[1] = new Data("Turgut Z. Yesilyurt","30","NJ, USA");
$ArrayList[2] = new Data("Maria ","25","NJ, USA");

print_r($ArrayList);

$obj1 = $ArrayList[1];
echo
"Name : ".$obj1->Name."\n";
echo
"Age  : ".$obj1->Age."\n";
echo
"Address : ".$obj1->Address."\n";

// Interface Usage //
interface ShowMe {
  
public function ShowName();
}

class
ShowData implements ShowMe {
  
public $obj;
public function __construct($Obj) {
  
$this->obj = $Obj;
  
$this->ShowName();
}

public function ShowName() {
   echo
"Age  : ".$this->obj->Age."\n";
}
}

echo
"\nDisplay Single Data =========================\n\n";
new
ShowData($ArrayList[1]);
echo
"\n=============================================\n";

// Turgut Z. YESILYURT, MS
// Software Developer //
// NJ, USA  //

?>

Array
(
   [0] => Data Object
       (
           [Name] => John McDonald
           [Age] => 65
           [Address] => Address
       )

   [1] => Data Object
       (
           [Name] => Turgut Z. Yesilyurt
           [Age] => 30
           [Address] => NJ, USA
       )

   [2] => Data Object
       (
           [Name] => Maria
           [Age] => 25
           [Address] => NJ, USA
       )

)
Name : Turgut Z. Yesilyurt
Age  : 30
Address : NJ, USA

Display Single Data =========================

Age  : 30

=============================================
Default Constructor...
Default Constructor...
Default Constructor...
zabmilenko at hotmail dot com
27-Jun-2005 03:27
Dynamic instantiation trick:

<?php

class CITY
{
  
private $population;

  
public function __construct($cityname)
   {
      
// Load some city-specific data
  
}

  
public function population($demographic = 'all')
   {
       return
$this->population[$demographic];
   }
}

class
COUNTRY
{
  
private $code = null;
  
private $cities = array();

  
public function __construct($code)
   {
      
$this->code = $code;
   }

  
public function city($cityname)
   {
       if (!
$this->cities[$cityname])
       {
          
$this->cities[$cityname] = new CITY($cityname);
       }

       return
$this->cities[$cityname];
   }
}

class
WORLD
{
  
private $countries = array();

  
public function country($code = 'us')
   {
       if (!
$this->countries[$code])
       {
          
$this->countries[$code] = new COUNTRY($code);
       }

       return
$this->countries[$code];
   }
}

$world = new WORLD;

// Load the country AND city object
echo $world->country('us')->city('seattle')->population('employed');

// Country US is already loaded, only need to load a new city object.
echo $world->country('us')->city('new york')->population();

?>

This example uses Countries and Cities wrapped around a World object.  You can use any schema you want, however.  Think:  Domain->Subdomain->Node or KINGDOM->PHYLUM->CLASS->ORDER->FAMILY->GENUS->SPECIES

What is happening here is that a private array is storing the class objects.  Only the class objects that are needed are loaded, when they are needed.  You can nest this many many times as needed.

You see that the array is never exposed.  Each function reference will check to see if a new class object is needed and create it if necessary.

This is literally as simple as it looks.  Hope it helps someone out.
Obeliks
11-Jun-2005 05:56
You can call parent::__construct(), even if the class yours inherits from uses the old constructor style "Classname()".

Example:

<?php

class A {
  function
A() {
   echo
'Constructor of A<br/>';
  }
}

class
B extends A {
  function
__construct() {
  
parent::__construct();
   echo
'Constructor of B<br/>';
  }
}

class
C extends A {
  function
__construct() {
  
parent::A();
   echo
'Constructor of C<br/>';
  }
}

$b = new B();
echo
'<br/>';
$c = new C();

/* will output:
Constructor of A
Constructor of B

Constructor of A
Constructor of C
*/

?>

So you see you can also call parent::Classname() if your superclass uses this format. Keep in mind that it doesn't work the other way round though:

<?php

class A {
  function
__construct() {
   echo
'Constructor of A<br/>';
  }
}

class
B extends A {
  function
__construct() {
  
parent::A();
   echo
'Constructor of B<br/>';
  }
}

$b = new B();

/* will output:
Fatal error: Call to undefined method A::a() in __FILE__ on line __LINE__
*/

?>

So it's always the best choice to use the __construct style! (at least if you're running PHP5)
bartlewis at gmail dot com
08-Jun-2005 09:29
In regards to gaehngaehn at hotmail dot com...

More simply, to create an object from a class using a variable, just try the following.

$a = new $class();

Works in php4 and php5.
Sb.
28-May-2005 12:50
We can't create easily anonymous objects like in JavaScript.
JS example :

   var o = {
       aProperty : "value",
       anotherProperty : [ "element 1", "element 2" ] } ;
   alert(o.anotherProperty[1]) ; // "element 2"

So I have created a class Object :

   class Object {
       function __construct( ) {
           $n = func_num_args( ) ;
           for ( $i = 0 ; $i < $n ; $i += 2 ) {
               $this->{func_get_arg($i)} = func_get_arg($i + 1) ;
           }
       }
   }

   $o = new Object(
       'aProperty', 'value',
       'anotherProperty', array('element 1', 'element 2')) ;
   echo $o->anotherProperty[1] ; // "element 2"

You must feel free to make it better :)
AJG
16-May-2005 11:13
[Note from et@php.net:
Your way to create a new, empty, generic object is:
<?php $obj = new stdClass(); ?>
]

I never found a way to create a new, empty, generic object so I coded something up myself. In addition, let me show you some imperfect examples.

<?
  
// Incorrect:   
  
$obj1 = (object) '';
  
$obj2 = (object) 0;
  
$obj3 = (object) 1;
  
$obj4 = (object) true;
  
$obj5 = (object) false;

  
// Syntax error:
  
$obj6 = (object);

  
// Correct:
  
$obj7 = (object) NULL;
?>

The first five ones will work, but will create a 'scalar' field in the object. This is undesirable at best, and can be a real nuisance when doing object automation. For that reason, I now use the following function, which produces a 'clean' object. It's also better semantically, in my opinion.

<?
  
function object() { return ((object) NULL); }

  
// Usage:
  
$object = object();

  
// Just like:
  
$array = array();
?>

Please post if you see any problems arising due to this method; thanks. Otherwise enjoy.
--AJG.
29-Mar-2005 07:21
There are 3 simple, and utterly annoying problems with your classes (not because of how you want them to work, but because how the Zend II engine handles them):

1) You cannot type hint string or int/integer in a method signature. This is incredibly annoying that the Zend II engine doesn't support it, but there are workarounds.
2) Supplying null in a method signature for a default value means that you will not accept any null value for that parameter. (therefore the method doesn't need to check if the parameters are null anyway).
3) Sadly, overriding methods is only possible with the Zend II engine via Inheritance or Polymorphism, ( and __construct() can only be defined within a class). If you want to override a method in the same class, my suggestion is to provide the method signature with a $flag = null variable, which you call a SWITCH on to pick what the data should do.

==============================================
Other than the afformentioned, the Zend II engine works very similarly to Java, which has made PHP much more versatile and robust in version 5. Thank you again Zend!
spam at afoyi dot com
21-Mar-2005 09:18
You can call a function defined in an inherited class from the parent class. This works in both PHP 4.3.6 and 5.0.0:

<?php

class p {
  
   function
p() {
       print
"Parent's constructor\n";
   }
  
   function
p_test() {
       print
"p_test()\n";
      
$this->c_test();
   }
}

class
c extends p {
  
   function
c() {
       print
"Child's constructor\n";
      
parent::p();
   }
  
   function
c_test() {
       print
"c_test()\n";
   }
}

$obj = new c;
$obj->p_test();

?>

Outputs:

Child's constructor
Parent's constructor
p_test()
c_test()
farzan at ifarzan dot com
06-Oct-2004 07:04
PHP 5 is very very flexible in accessing member variables and member functions. These access methods maybe look unusual and unnecessary at first glance; but they are very useful sometimes; specially when you work with SimpleXML classes and objects. I have posted a similar comment in SimpleXML function reference section, but this one is more comprehensive.

I use the following class as reference for all examples:
<?
class Foo {
  
public $aMemberVar = 'aMemberVar Member Variable';
  
public $aFuncName = 'aMemberFunc';
  
  
   function
aMemberFunc() {
       print
'Inside `aMemberFunc()`';
   }
}

$foo = new Foo;
?>

You can access member variables in an object using another variable as name:
<?
$element
= 'aMemberVar';
print
$foo->$element; // prints "aMemberVar Member Variable"
?>

or use functions:
<?
function getVarName()
{ return
'aMemberVar'; }

print
$foo->{getVarName()}; // prints "aMemberVar Member Variable"
?>

Important Note: You must surround function name with { and } or PHP would think you are calling a member function of object "foo".

you can use a constant or literal as well:
<?
define
(MY_CONSTANT, 'aMemberVar');
print
$foo->{MY_CONSTANT}; // Prints "aMemberVar Member Variable"
print $foo->{'aMemberVar'}; // Prints "aMemberVar Member Variable"
?>

You can use members of other objects as well:
<?
print $foo->{$otherObj->var};
print
$foo->{$otherObj->func()};
?>

You can use mathods above to access member functions as well:
<?
print $foo->{'aMemberFunc'}(); // Prints "Inside `aMemberFunc()`"
print $foo->{$foo->aFuncName}(); // Prints "Inside `aMemberFunc()`"
?>