PHP  
downloads | documentation | faq | getting help | mailing lists | | php.net sites | links | my php.net 
search for in the  
<Variablenfunktionenextends>
view the version of this page
Last updated: Sat, 19 Apr 2003

Kapitel 14. Klassen und Objekte

Klassen

Eine Klasse ist eine Sammlung von Variablen und Funktionen, die mit diesen Variablen arbeiten. Eine Klasse wird folgenderma�en definiert:

<?php
class Cart
{
    var $items;  // Artikel in unserem Einkaufswagen
   
    // F�ge dem Einkaufswagen $num Artikel der Sorte $artnr zu
 
    function add_item ($artnr, $num)
    {
        $this->items[$artnr] += $num;
    }
   
    // Nimm $num Artikel von $artnr aus dem Einkaufswagen
 
    function remove_item ($artnr, $num)
    {
        if ($this->items[$artnr] > $num) {
            $this->items[$artnr] -= $num;
            return true;
        } else {
            return false;
        }   
    }
}
?>

In diesem Beispiel wird eine Klasse "Cart" definiert. Sie besteht aus einem assoziativen Array von Produkten im Einkaufswagen und zwei Funktionen zum Hinzuf�gen und Entfernen von Artikeln.

Achtung

Die folgenden warnenden Bemerkungen gelten f�r PHP 4.

Der Name stdClass ist reserviert, da er intern von Zend benutzt wird. Sie k�nnen in PHP keine Klasse mit dem Namen stdClass haben.

Die Funktionsnamen __sleep und __wakeup sind in PHP Klassen "magisch". Sie k�nnen in Ihren Klassen keine Funktionen mit diesen Namen haben, au�er Sie wollen sie mit dieser "magischen" Funktionalit�t assoziieren. Mehr Informationen dazu finden Sie weiter unten.

S�mtliche mit __ beginnende Funktionsnamen sind PHP als "magisch" vorbehalten. Es wird empfohlen, in PHP keine Funktionsnamen mit __ zu verwenden, au�er Sie m�chten dokumentierte "magische" Funktionalit�t.

Anmerkung: In PHP 4 sind nur konstante Initialisierungen f�r var Variablen erlaubt. Um Variablen mit nicht konstanten Werten zu initialisieren, ben�tigen Sie eine Funktion zur Initialisierung, welche beim Erstellen eines Objektes automatisch von der Klasse aufgerufen wird. Eine solche Funktion wird Konstruktor genannt (siehe unten).

<?php
/* Keine wird in PHP 4 funktionieren */
class Cart
{
    var $todays_date = date("Y-m-d");
    var $name = $firstname;
    var $owner = 'Fred ' . 'Jones';
    var $items = array("VCR", "TV");
}

/* So sollte es gemacht werden */
class Cart
{
    var $todays_date;
    var $name;
    var $owner;
    var $items;

    function Cart()
    {
        $this->todays_date = date("Y-m-d");
        $this->name = $GLOBALS['firstname'];
        /* etc. . . */
    }
}
?>

Klassen sind Typen, das hei�t sie sind die Blaupausen f�r reale Variablen. Um sie zu nutzen, muss zun�chst eine Variable mit dem Operator new angelegt werden.

<?php
$cart = new Cart;
$cart->add_item("10", 1);

$another_cart = new Cart;
$another_cart->add_item("0815", 3);

Dies erstellt die Objekte $cart und $another_cart aus der Klasse Cart. Dann wird die Funktion add_item() des $cart Objektes aufgerufen, um $cart einen Artikel mit der Artikelnummer 10 hinzuzuf�gen. 3 Artikel mit der Artikelnummer 0815 werden $another_cart hinzugef�gt.

Sowohl $cart als auch $another_cart haben die Funktionen add_item(), remove_item() und die Variable items. Dies sind verschiedene Funktionen und Variablen. Sie k�nnen sich Objekte �hnlich den Verzeichnissen in einem Dateisystem vorstellen. Sie k�nnen in einem Dateisystem zwei verschiedene Dateien README.TXT haben, solange sie sich in verschiedenen Verzeichnissen befinden. So wie Sie in Verzeichnissen den vollen Pfadnamen eingeben m�ssen, um jede Datei von dem obersten Verzeichnis aus zu erreichen, m�ssen Sie auch den vollen Namen der aufzurufenden Funktion angeben: Das hei�t f�r PHP, dass das Hauptverzeichnis der globale Namensbereich, und der Separator des Pfadnamens -> w�re. Deshalb benennen die Namen $cart->items und $another_cart->items auch zwei verschiedene Variablen. Beachten Sie, dass die Variable $cart->items, und nicht $cart->$items genannt wird, da ein Variablenname in PHP nur ein einziges Dollarzeichen hat.

// korrekt, einfaches $
$cart->items = array("10" => 1); 

// falsch, denn $cart->$items wird zu $cart->""
$cart->$items = array("10" => 1);

// richtig aber fraglich, ob dies erw�nscht war:
// $cart->$myvar wird zu $cart->items
$myvar = 'items';
$cart->$myvar = array("10" => 1);

Innerhalb einer Klassendefinition ist nicht bekannt, unter welchem Namen das Objekt in Ihrem Programm erreichbar sein wird: Als die Klasse Cart geschrieben wurde war nicht bekannt, dass das Objekt sp�ter $cart oder $another_cart genannt wird. Deshalb k�nnen Sie innerhalb der Klasse Cart selbst auch nicht $cart->items schreiben. Um nun die eigenen Funktionen und Variablen innerhalb einer Klasse anzusprechen, k�nnen Sie die Pseudo-Variable $this verwenden, welche Sie auch als 'meine eigene' oder 'aktuelles Objekt' verstehen k�nnen. Deshalb kann '$this->items[$artnr] += $num' auch als 'addiere $num zu $artnr in meinem eigenen Array items', oder 'addiere $num zu $artnr im Array items innerhalb des aktuellen Objektes' lesen.

Anmerkung: Es gibt ein paar angenehme Funktionen, um mit Klassen und Objekten umzugehen. Mehr dar�ber erfahren Sie im Kapitel Klassen- und Objekt-Funktionen.



User Contributed Notes
Klassen und Objekte
add a note
immo at nospam dot org
17-Dec-1999 07:48

Here is some code to demonstrate member objects and inheritance.

class ParentObject {
   var $value;

  function ParentObject() {
       $this->value = 42;
  }
}

class MemberObject extends ParentObject {
   var $string;

   function MemberObject() {
      $this->string = "This is a test string.";
$this->ParentObject();
  }
}

class ObjTest {
   var $ObjPointer;

  function ObjTest() {
       $tmp = new MemberObject;
$this->ObjPointer = $tmp;
  }
}

echo "Creating object of type ObjTest...";
$object = new ObjTest;
echo "Done.
\n";
echo "String Contents: " . $object->ObjPointer->string . "
\n";
echo "Value  Contents: " . $object->ObjPointer->value . "
\n";

cleong at organic dot com
05-May-2000 01:13

Note that you can refer to class members with variable variables - something that makes up for the lack of pointer. The following would yield "Hello world" -

class a {
var $b;
}

$object = new a;
$object->b = "hello";
$member_name = 'b';
echo $object->$member_name;
$object->$member_name = " world";
echo $object->$member_name;

cleong at organic dot com
17-May-2000 09:30

Quel spectacle! Anyway, in PHP, objects are copied when you perform the assignment operation. The line $a = $b yields two distinct, unrelated objects -- $a and $b. To reference the same object with different variables, use ampersands. e.g. $a = &$b; This only works in PHP4 however.
simon dot li at hongkong dot com
13-Sep-2000 11:15

-------------------------------------------------
[Editor's note: class casting per se is not part of the object/class implementation in PHP, but code like the one in this note can kludge if you need it for very simple cases, more complex ones are left to the imagination of the programmer:
<?php
class foo {
function foo($name="foo") {
$this->name=$name;
}
}

class bar extends foo {
function boom() {
echo "BOOOM!";
}
}

$f = new foo();
$temp = explode(":",serialize($f));
$temp[2] = "\"bar\"";
$b = unserialize(implode(":",$temp));

$b->boom();

?>
This forces $b to be an instance of "bar" using an object $f, an instance of "foo"]
-------------------------------------------------


About casting of object, say, i got:

class A extends B {
      function A() {
               $this->B();
       }
      ....
}

$b = new B();
$a = new A();

I wanna have a object of class A with "content" of $b:
$a = (A) $b; // not a valid code,(right?) as for illustration.

iw at warped dot nu
09-Oct-2000 12:12

Here's a very important reminder to those of you used to Java/C++ object references/pointers. When you send a function arguments which include a class object, PHP will make copies of that object for use inside that function.

This differs from passing a Java reference to an object or passing a C++ pointer to an object. Within the scope of the above-mentioned function, calling class methods of the argument object will only affect the copy that PHP creates. Likewise, when the function itself is completed, the copy of the object you passed ceases to exist.

To emulate Java/C++ functionality of arguments that are objects, you just have to modify the given function's signature from this:

function foo(..., $object, ...)

to this:
function foo(..., &$object, ...)

The ampersand(&) thus signifies that the function should receive a reference to the object, instead of creating a copy of the object.

mircho at abv dot bg
12-Oct-2000 01:19

A short comment on classes [this maybe is an answer on some previous posts.
In PHP4 [I havent tested it on PHP3]
You can't have executable code within the class declaration. Here is what I mean:

define( MY_VAR_1, 4 )
define( MY_VAR_2, 15 )
class classMyWork
{
   var $nClassVar = MY_VAR_1*MY_VAR_2;
   var $nClassVar = MY_VAR_1*10;
   //BOTH WON'T WORK
   var $hOtherClass = new classOtherClass();
   //THIS WON'T WORK TOO
}

Obvoiously there's no syntactic sugar as found in Java or C++
All initialization should be performed in the class constructor
And maybe the assignment of a global variable to a class member is the same problem

eggbird at bigfoot dot com
01-Nov-2000 06:33

[Editor's note: This has to do with the ambiguity of the expression used. When the assignment fails it is because the expression could mean "the property 'tuut' of the object '$this->memberobject'" or "the property 'memberobject->tuut' of the object '$this'", parsing of variables inside quotes in which you have a complex expression is not recommended, the way it should be done is by using the concatenation operator, which is why the last assignment works. This is a know behaviour, see for example the "Variable variables" section of the manual.]


i might be wrong here, but to me it seems that (within a method) something like this:

$bla = "boink and $this->tuut";

does work, but not this:

$bla = "boink and $this->memberobject->tuut";

I had to resort to

$bla = "boink and ".$this->memberobject->tuut;

in this case.

monsy2 at yahoo dot com
09-Nov-2000 12:33

It seems that when you use "extends", the definition of the extended classe must precede the use of "new", otherwise it whon't work.
Which is not the case with a not extended class. (php4)

brice at webprojkt dot com
22-Dec-2000 04:23

Defaulting a function parameter to a variable isn't directly supported, but here's how to get around that:

Suppose you have a class:

class query {
  var $sql;
  var $link;

 function go ($SQLstring = $this->sql)
  {
    return mysql_query($this->sql,$link);
  }
}

This doesn't work.  Here's the workaround:

(function spec):
  function go ($SQLstring)
  {
    if (isset($SQLstring)) { $this->sql = $SQLstring; }
    return mysql_query($this->sql,$this->link);
  }

This may not be the best example of this, but I thought I'd throw this out for you folks ... should allow support of presetting of an object value and then execution of the method on that, or something like query::go("SELECT ...");

Enjoy!

p.s. (in this case query::go wouldn't work because it is coded with $this->link, but if you wanted to just use the default connection, it'd work fine :)

buzz77 at gmx dot net
14-Feb-2001 03:33

You can also store object variables as session variables, so that you don't have to create an object every time the page loads.

Let's see how:
here is my simple class file:

// simple.lib.php
class simple
{
 function dummy
 {
  print "TEST SUCCESSFUL!\n";
 }
}

Then, I create a simple .php which starts a new session and registers the object-variable of the "simple"-class.

// test1.php
require ("simple.lib.php");
session_start();
session_register("CLASSOBJ");
$CLASSOBJ=new simple();

That's all.
In the following .php-files you've only to add the following lines:
require("simple.lib.php");
session_start();

To test out if it works, simply call:
$CLASSOBJ->dummy();
and it will print the message.

I tried it out also with quite huge classes, and it always worked (I think the pointer to the instanciated class is stored and the class object itself won't be deleted if you eg. change to another .php-page)

sgarner at expio dot co dot nz
19-Feb-2001 01:15

[Editor's note: Remember tha PHP is not a hard core OOP language, and even the ones that are do not always support the unusual vector/array references applied to results from methods.]

It seems there is no way to access the return value of a method (or any function) inline, without assigning it to a variable.

For example:

class Test
{
 function blah ()
 {
    return array(1,2,3);
 }

 function childTest ()
 {
    return new Test;
 }
}

$test = new Test;

// This does not work:
$foo = $test->blah()[0];

// Instead have to do:
$temp = $test->blah();
$foo = $temp[0];

// Similarly for objects, cannot do:
$foo = $test->childTest()->blah();

// Instead have to do:
$temp = $test->childTest();
$foo = $temp->blah();


:-(

idont at remember dot it
23-Feb-2001 08:47

[Editor's note: Just a quick comment.

Inherently OO languages should theoretically access attributes using methods, but even in existing ones this is not strictly enforced. PHP is *not* and inherently OO language, but one that has some object/class support.

This note is talking about a "best practice" recommendation, not a necessity that is dictated by the language design or implementation.]


In many exemples (and in the official doc) I saw a problem: many access directly the attributs of the objects. Actually we SHOULD always access an attribut through a method.

<?php
class user{
 var $_name;
 var $_email;

 function user($name,$email){
  $this->_name=$name;
   $this->_email=$email;
 }

function getName(){
   return($this->_name);
 }

function getEmail(){
   return($this->_email);
 }

function setName($name){
   $this->_name=$name;
 }

function setEmail($email){
   $this->_email=$email;
}
}

$me = new user("Bill","[email protected]");
echo "my name is :".$me->getName()."&lt;br&gt;";
echo "and my email :".$me->getEmail()."&lt;br&gt;";

//wrong way
$me->_email="[email protected]";
//Better way
$me->setEmail("[email protected]");

//wrong way
echo "oops sorry, here is the right one:".$me->_email."
";
//Better way
echo "oops sorry, here is the right one:".$me->getEmail()."
";
?>

As you noticed I put a "_" at the beginning of the attributs' names, this is a typo tip to declare them as private. OF course this is not real as PHP doesn't support the notions of public, private for methods and attributs.
A poor solution waiting for a better one. :)

derek at idirect dot com
08-Mar-2001 12:15

Something curious to note...
It seems you cannot call a parent object method via an eval() call.

Example:

class Math
{
   function mul($x, $y)
   {
       return ($x * $y);
   }
}

$result = Math::mul(5, 6);           # works
$result = eval("Math::mul(5, 6);");  # doesn't work

pawsa at theochem dot kth dot se
12-Mar-2001 01:27

[Editor's note: See a sample destructor implementation in the section of the manual dealing with the PEAR code]

Concerning the comment on desctructors: [Editor's note: ... To destroy an object, just assign to the variable, or use unset(), as you would with any other variable in the language. ...]: this does not allow to execute an action on destroying an object. One might want to clear temporary files etc on object destruction. I understand that there is no way to do so with PHP 4.0, is that correct?

DanRichter.at.programmer.dot.net
10-Apr-2001 05:32

If you get the impression that your constructor is not being called, remember the proper syntax for member variables: $this->foo. I spent about a half hour wondering why my constructor "wasn't being called", and finally found out that the variable assignments in the constructor were in the form of $foo = $bar, and so simply created transient variables. (Another possibility: remember that a subclass does not automatically call its parent class's constructor.)
andrew at NOSPAM dot mukau dot net
11-May-2001 06:41

[Editor's note: to avoid this type of problems, you should be using include_once() instead, see the appropriate manual page entry]

Hi there... Something I noticed ...

If you have a Class A which
requires Class B (eg. require ('B.inc'); )
If you have two more classes extending A:
Class C extends A
Class D extends A
you may run into some problems if your script requires both C and D, - you will get an error saying you are redefining Class B.  The solution is to require only class C or class D in a script.

maillist at metacosm dot dhs dot org
11-Jun-2001 11:27

The _Note_ on this page is very misleading.. it says "In PHP 4, only constant initializers for var variables are allowed. To initialize variables with non-constant values...", it appears (unless someone can show me otherwise), that you can not even use var $something = CONSTANT, in a class, and after a heated discussion on #php on openprojects.net, I thought I should post this so others would just accept that _all_ var $stuff must be initialized in the constructor.  The _Note_ would leave you to believe some do not, which I have found to be untrue.
ntunali at isbank dot net dot tr
13-Jun-2001 04:02

Event Driven!!!!!!!

<?
// ============ your class (anywhere) =======================
class a {
var $t;

function lets_call() {
if (!empty($this->t))
call_user_func($this->t);

}
}

//================= your codes ===============================
$new_class=new a;

function ex_one(){
echo 'ex_one function' .'
';
}

function ex_two() {
echo 'ex_two function'.'
';
}

$new_class->t='ex_one';

$new_class->lets_call();

$new_class->t='ex_two';

$new_class->lets_call();

// ==================== That's all ==============================
?>

b dot ruecker at portunity dot de
08-Jul-2001 04:22

If you need a destructor, perhaps it is an idear to simulate it this way with a global Destroy-Function:

<?
function DestroyObject ($name)
{
    $theobject = &$GLOBALS[$name];
    if (method_exists ($theobject,"Destroy"))
        $theobject->Destroy ();
    unset ($GLOBALS[$name]);
}

class xyz
{
   var $somevar;

   // ### This is the constructor
   function xyz ()
   {
   }

   // ### This is the destructor which will be called
   function Destroy ()
   {
      echo ("Now we destroy it !");
   }

   function SomeDo ()
   {
      echo ("doing something: ".$this->somevar);
   }
}

$example = new xyz;

// .... doing something here
$example->somevar = 3;
$example->SomeDo();

DestroyObject ("example");

// ### Test => should produce an error !
$example->SomeDo ();

?>

kynaston at yahoo dot com
22-Jul-2001 06:35

Need to turn all post and get variables into properties of a class? Here's how:

class Params {
 function Params() {
   global $HTTP_POST_VARS, $HTTP_GET_VARS;
   $params = array_merge($HTTP_POST_VARS, $HTTP_GET_VARS);
   foreach($params as $k=>$v) {
     $this->$k = $v;
   }        
}
}

$test = new Params();
foreach(get_object_vars($test) as $k=>$v) {
 print("$k => $v : ");
}

'course, if you've got any class variables with the same name as a get or post variable, you've just clobbered it, but used with care it's handy.

du dot r at bol dot com dot br
17-Aug-2001 03:19

You cannot instantiate objects from classes as below:

class UserInformation_mysql{
       var $useridnr, $userid, $sessionID;
       }
class UserInformation_imap{
       var $userid, $pass, $sessionID;
       }
class UserInformation_pgsql{
       var $useridnr, $userid, $sessionID;
      }


if(defined("SISMAIL_MYSQL")){
define("USER_INF_CLASS","UserInformation_mysql");
}

$UserInformation = new 'USER_INF_CLASS';

and expect it works...
but in my opinion, it should work.....

du dot r at bol dot com dot br
17-Aug-2001 05:49

Thanks to Robin for his solution:
____________________________________
well... maybe. Constants aren't replaced inside a string though, and class
names aren't quoted so there's scope for confusion there.

If you absolutely have to use a constant to carry your classname, the only way
I can think of doing what you're asking is to replace the last line of your
code with this:

$UserInformation = eval( 'return new ' . USER_INF_CLASS . ';' );

hope this helps.

  -robin
___________________________________

nanderson at volvojimfisher dot com
22-Aug-2001 08:35

[Ed. note:  default is a keyword in PHP (used with switch()) and therefor can't be used as a function- or methodname.]

It would appear that no class method can be called 'default()'.  PHP generates an error if you attempt the following:

class MyClass
{
function default()
{
...
}
...
}

mikejohnson at collegecommunityonline dot com
06-Oct-2001 09:07

You can set object properties to have default values.  As long as those values don't come from some other variable.

for example

class foo{

var $test1 = "test";
var $test2 = "test2";

}

would be legal

but

class foo{

var $test1 = $GLOBALS[PHP_SELF];
var $test2 = $GLOBALS[HTTP_HOST];

}

would not be legal

dave at 4-core dot com
16-Oct-2001 01:52

$class->propertyObject->method()

In case you're wondering, PHP 4 has no problem with chaining -> to refer to properties/methods of objects which are themselves properties of other objects. E.g., I was setting up a database class which wanted to know a couple of related records:

In the 'dbRecord' constructor:


$this->child = new child_type($this->value("childFKey"));  


In the main code:  


$record = new parent;  

echo $record->child->childMethod();  


...works just fine :-)

May be obvious to some, but it's not explicitly mentioned and I was a bit worried it wouldn't work 'cause I really need it!

(I guess it follows from the same way you do $multiArray[][] to get at multidimensional array indices.)

promo at card2u dot com dot my
29-Oct-2001 12:56

A very simple class builder utility is at
dougqh at hotmail dot com
29-Oct-2001 09:29

If you want to call a method of class and you do not have an instance of the class and you have the class, method name, or both stored in a variable(s) you can use the following ...

call_user_func( array( $className, $functionName ), [ $param0 [, $param1 [, ... ] ] ] )

For example

$class = "MyClass";
$method = "myMethod";

call_user_func( array( $class, $method ), 0, 1 );

is equivalent to

MyClass::myMethod( 0, 1 );

flash at minet dot net
05-Jan-2002 06:21

It's possible to 'redefine' a class using $this.

Check this example :
<?

class A {
function A() {
print "<div>instance of A</div>";
}
function whoami() {
print "<div>";
var_dump($this);
print "</div>";
}
}

class B {
function B() {
print "<div>instance of B</div>";
}

function transform() {
$this = new A(); // <-- THIS line :)
}
function whoami() {
print "<div>";
var_dump($this);
print "</div>";
}
}

print "<div><b>Instanciations</b></div>";
$A = new A; $A->whoami();
$B = new B; $B->whoami();

print "<div><b>Transformation</b></div>";
$B->transform();
$A->whoami();
$B->whoami();
?>

First, we create two objects : $A -> class A, and $B -> class B.

But the method 'transform' redefines $B instances, and $B is now of class A.

(sorry, there are some problems with the layout)

php at priorwebsites dot com
08-Feb-2002 10:25

If your new to PHP classes, beware of the scope of variables.  

In particular, if a variable is defined as an implicitly static variable for the class as a whole, make sure you use the $this->my_var syntax, not just $my_var.

First, using the scope WRONGLY:

class my_wrong_class
{
 /* A general class variable */
$db_link;

 /* A constructor function for the class */
function my_class()
 {
   /* this will give the $db_link variable a value   */
   /* but only as a local variable in this function. */
   $db_link = mysql_connect('localhost','root','');    
}

 function do_something()
 {
   $query = "SELECT * FROM my_table";

   /* Again, the $db_link reference is wrong! Won't work */
   $result = mysql_query( $query, $db_link );
}
}

Now doing the scope CORRECTLY:

class my_right_class
{
 /* A general class variable */
$db_link;

 /* A constructor function for the class */
function my_class()
 {
   /* Ah! Correctly references the class variable */
   $this->db_link = mysql_connect('localhost','root','');    
 }

 function do_something()
 {
   $query = "SELECT * FROM my_table";

   /* Ah! Correctly uses the class variable */
  $result = mysql_query( $query, $this->db_link );
}
}

If you are a seasonsed PHP programmer you may say nobody would do that.  I as a seasoned non-PHP programmer did, couldn't understand why my code didn't work, and fudged it, till now...

ebypdx at attbi dot com
15-Feb-2002 02:58

(only tested w/ php4.1.0 w/ apache 1.3.20)

It appears that you don't have to declare your vars inside a class, even if you want to serialize an instance of the class.  From within any function including the constructor, calling
$this->foo = $bar;
will create an object var in your class, even if there is no class var named foo declared in your class.  If you serialize the object, for example to register it with the client's session or put it in a database, the object var will remain!

alebiasin at yahoo dot com
28-Feb-2002 04:26

It's possible to extend a class in PHP, from a class made with Visual Basic in a DLL.

Read the post saying "It's possible to 'redefine' a class using $this".

EXAMPLE:

1) Create a class in Visual Basic like this:

  Project Name: projectA
  Class Name: ClassA

Public strPP As String

Private Sub Class_Initialize()
  strPP = "Inicializado"
End Sub

Public Function a() As String
  a = "A_" & strPP
End Function

2) Create a class in PHP like this:

<?
 class classB
 {
   function classB()
  {
     // Cambio el puntero de esta clase, por el de la clase de Visual Basic
     $this = new COM("projectA.classA");
  }
 }

 $B = new classB;
 echo $B->A()."
"; // Uso el metodo A() de la clase de Visual Basic classA
 $B->strPP = "Hola!!!"; // Propiedad strPP de la clase de Visual Basic classA
 echo $B->A()."
";
?>

3) Execute it! It should output this:

A_Inicializado
A_Hola!!!

philhassey dot maybe dot at at hotmail dot com
01-Mar-2002 05:52

When trying to use a dynamically named array in a class, be careful of how you access your dynamic array.

Incorrect:
$dynamic_name="myarray";

$this->$dynamic_name[0]="apples";
// Meant $this->m="apples";

$this->$dynamic_name[1]="oranges";
// Meant $this->y="oranges";

Correct way:
$dynamic_name="myarray";

$this->{$dynamic_name}[0]="apples";
// Meant $this->myarray[0]="apples";

$this->{$dynamic_name}[1]="oranges";
// Meant $this->myarray[1]="oranges";

The incorrect example written differently shows how you could interact with multiple dynamic variable names.
$dynamic_names=array("name_one","name_two");

$this->$dynamic_names[0]="apples";
// Meant $this->name_one="apples";

$this->$dynamic_names[1]="oranges";
// Meant $this->name_two="oranges";

However this example might be more clearly written as
$dynamic_names=array("name_one","name_two");

$this->{$dynamic_names[0]}="apples";
// Meant $this->name_one="apples";

$this->{$dynamic_names[1]}="oranges";
// Meant $this->name_two="oranges";

joey at creativejuices dot ws
22-Mar-2002 07:26

In case you need to, here is how you can do Class variables in addition to Instance variables in php 4.1.2.

class MyClass{
var $classcount = 0;
var $objName;

function MyClass(){
global $classcount;
$classcount++;
}

function setName($theName){
$this->objName = $theName;
}

function getName(){
return $this->objName;
}
}

$class1 = new MyClass;
$class1->setName("class1");
echo "First Class Name: ".$class1->getName();
echo "First Class Count: ".$classcount;

$class2 = new MyClass;
$class2->setName("class2");
echo "Next Class Name: ".$class2->getName();
echo "Next Class Count: ".$classcount;

/***************
This will yield:

First Class Name: class1

First Class Count: 1

Next Class Name: class2

Next Class Count: 2

***************/

s dot hagenbrock at gmx dot de
27-Mar-2002 05:02

There is a great solution for "plugin" API developer's wich didn't know how a extended class would be called later, but likes to use ones.

It's a little tricky way of using a interface_class and the variable variables. I just like to throw you into water and let you learn from following example:

[example]

class my_interface{
  function foo($msg){
     /*it does nothing, and it could be totally ignored.. but it is a help for the class definitions. Just to prevent that things get messed up when "plugin" developers play the "try/error" game...
*/
  }
}

class foobar extends my_interface{
  function foo($msg){
     echo "foobar:: $msg";
  }
}

class hello_world extends my_interface{
  function foo($msg){
      echo "we say hello and '$msg' to the whole world";
  }

}

// now the interesting part :)
$used_interface = "foobar";
$obj = new $used_interface ();
$obj->foo("hallo");
[/example]

Now... try to set up other my_interface childs... the interesting thing ist the variable "$used_interface"!

You must insert a valid class name into this variable, otherwise you get an "cant instanctiate class... " error. So, now,  you can create a class only by knowing it's name - without hardcoding!

Why the hell using an interface class? Well... see it as an help... for you and for the plugin developers. The plugin dev's will know what the api want's, and you know what your api could process... ;)

It works fine under php 4.0.6.

Greetz

s.hagenbrock

Btw... don't forget to include the class files. Else you get an "undefined class" error ;)

ashley at dcs dot warwick dot ac dot uk
05-Apr-2002 04:17

The returned result from a constructor cannot be accessed: the result of the call to new is the instantiated object.

So error handling in a constructor is problematic.  There are a few ways I can think of handling this:
1) call exit() or die() in the constructor -- not good if you want to recover and carry on somehow
2) don't put code that can fail in the constructor, put it in an initialisation function instead which can return an error result -- somewhat defeats the purpose of a constructor (it shouldn't really be possible to construct an object with uninitialised state)
3) when an error occurs, save that state inside the object to be returned using isError and getError functions.  Ideally all other functions should refuse to do their job if an error occurred during construction.

I guess this is one of the reasons that Java has exceptions.

fschaper at zerodegree dot de
17-May-2002 06:18

Despite the comments above this works out very well for me

class CTest {
 function CTest() { }
 function go( $var ) {
    echo "Thats an ".$var;
 }
}

$cTest = new CTest;

$member = "go";
$class = & $cTest;

$class->$member( "whatever" );

philip at cornado dot com
04-Jun-2002 06:14

Know of any basic tutorials on PHP Classes and OOP?
*

mark6139 at yahoo dot com
22-Jun-2002 09:29

Given lack of type checking I understand why it is necessary to use $this every time you access a member variable in a class; but this is a serious gotcha for those used to coding in C++/Java where you can refer to the variable name only.  I am also submitting a feature request that a warning be generated where a variable name is used in a class that matches a class member variable name.
kpower at ardencompanies dot com
17-Jul-2002 08:35

To create an array of objects, try the following:
class Test{
function Test($temp){
   $this->a = $temp;
 }
 function print_a(){
   echo $this->a;
 }
}

$myObj = array();
for($i = 0; $i < 10; $i++)
 $myObj[] = new Test($i);

$myObj[9]->print_a();

Granted there are many ways to create you array. This is just a quick example.

mads at madsnielsen dot nospammm dot dk
19-Jul-2002 03:36

Don't use $this to pass a reference to the current object in the object's constructor.

class parent
{
   var $child;
   function parent()
   {
       $this->child = new child(&$this);
 }
}

class child
{
   var $parent;
   function child(&$parent)
   {
       $this->parent = &$parent;
   }
}

$parent = new parent();

for some reason
$parent != $parent->child->parent

if you need to pass a reference to child objects, use eg. an init-function, in which &$this will work just fine. Just don't use the constructor.

uws (at) xs4all (dot) nl
08-Aug-2002 11:36

The sample code provided above doesn't seem correct to me. The line that says:

if ($this->items[$artnr] > $num)

should be changed to:

if ($this->items[$artnr] >= $num)

Otherwise, you won't be able to remove all items from the cart.

13-Aug-2002 11:13
If you register object class, You must include class file before session started!!
13-Aug-2002 03:23
[Editor's note: There are no real "private" variables/methods in PHP 3 or PHP 4, some functions treat variables/methods whose names start with and underscore as if they were private, but they are still accessible. This is schedule to change when the Zend 2 engine gets released, don't hold your breath just yet ;-)]


Don't know if it's undocumented, or if I just can't find it, but...

yes, you can make private functions/variables!
Just prepend the variable name with an underscore, ie.

var $_myPrivateVar
  or
function _myPrivateFunction

matlin at it dot su dot se
21-Aug-2002 01:54

I noticed that you can't define constants inside classes. Didn't see anything about that on this page?!
hfuecks at pinkgoblin dot com
22-Aug-2002 05:55

If you want to convert an array (for example) to an object, you can do something like this, using the reserved stdClass for data;

<?php
$array = array ( "one" =>"red", "two" => "blue" );
$object = new stdClass ();
foreach ( $array as $key => $val ) {
  $object->{$key}=$val;
}

echo ( "<pre>" );
print_r ( $object );
echo ( "</pre>" );
?>

dhoffutt-dontlike at spam-airmail dot net
22-Sep-2002 06:06

_SESSIONS and CLASSES / OBJECTS

One may instantiate an object as a session variable, however every single page that your object passes through must include the code of the class.

Example:

include("dbObject.php");
session_start();
if (!is_object($_SESSION['testdb']))
{
 $_SESSION['testdb']= new dbObject;
}
$_SESSION['testdb']->do_your_class_functions();

Bit o' trivia worth mentioning: I recently switched to Mozilla 1.1 from IE. When attempting to test multiple session instances from same workstation, each instance of Mozilla on the same workstation used the same session instance as the previous Mozilla. Netscape 6 does the same thing. So, to test multiple sessions simultaneously from a single workstation, use Internet Explorer.

skynet at context-ua dot com
10-Oct-2002 10:35

[Note: here is a trick with inheritance. Consider we have object named 'b' that extends object 'a'. But we would like to call a function 'b::handle' right from object 'a'. The following code will do the trick.]
<?php
class a {
 function a (){
  echo "Class a construct
";
 }

 function handle() {
 echo "Class a handle
";
 }

 function proceed() {
  $this->handle(); //actually b::handle is called here;
  echo "Class a proceed
";
 }
}

class b extends a {
 function b (){
  parent::a();
  echo "Class b construct
";
 }

 function handle(){
  echo "Class b handle
";
  parent::handle();
 }
}

$varriable = new b();
$varriable->proceed();
?>
[Output:
Class a construct
Class b construct
Class b handle
Class a handle
Class a proceed
]

oliver dot ahlberg at smp dot se
12-Oct-2002 02:17

class MyClass {
 function list($args) {
   // Code
}
}

MyClass::list("Value");

Calling the function will result in the following error: "Parse error, unexpected T_LIST, expecting T_STRING or T_VARIABLE or '$'".

smurge at REMOVETHISweb dot de
01-Nov-2002 06:13

The workarounds for chaining/inheriting constructors in here didn't work for me when I tried them. After a while, I found a different way to make sure the parent class constructor was called: Unserializing the child class instance from a (new) parent class instance and then executing its own initialization:

<?php

...

class THECHILD extends THEPARENT {

var $abc;
var $xyz = "xyz"; // NOTE: this value will be lost during unserialization

function _ATOM() {

// NOTE: $this->xyz is now "xyz"
$this = unserialize (serialize (new THEPARENT()));
// NOTE: Original value of $this->xyz is lost

$this->$abc = "abc"; // Better: initialize values after ser/unser. step
}
}

...

?>

Not the fastest to execute maybe, but it seems (!) to work fine.

The pro's:
- Not as much typing and
- Not as confusing to read
as some other solutions I've found.

ronherhuth at mindspring dot com
05-Dec-2002 06:58

I was dissappointed to find that PHP didn't support multiple constructs like Java does.  In short in Java you can create multiple constructs all named the same, and based on the number of variables passed when creating a new object the appropriate construct is used to initialize the object.

I stumbled on a way to do this using an array:

class table
{
function table($aTableStyles)
{
// SET DEFAULT VALUES
$this->titleBar = "off";
$this->titleBarBGColor = "#cccccc";
$this->titleBarFontFace = "#Times New Roman";
$this->titleBarFontColor = "#ffffff";

// OVERRIDE DEFAULT WITH USER SET VALUES
while (list($key, $val) = each($aTableStyles) )
{
$this->$key = $val;
}

}

}

// CREATE NEW OBJECT 1
// set values to send to constructor
$aTableStyles1 = array(
"titleBar" => "on"
)

$newTable1 = new table($aTableStyles1);

// CREATE NEW OBJECT 2
// set values to send to constructor
$aTableStyles2 = array(
$this->titleBarBGColor = "#cccccc";
$this->titleBarFontFace = "#Times New Roman";
$this->titleBarFontColor = "#ffffff";
)

$newTable2 = new table($aTableStyles2);

--

Basically what I have done is created four class variables that hold default values.  When the constructor is called you can choose to override the default values by passing any number of values in an associative array.  The constructor simply loops through and replaces any of the default variables with user supplied ones.  This way when a new object is created you can chose to override only a single value or all of them.  This was very important in my table class because I had 30+ options the user could choose to override.

Ron

duncan at NOTINNED dot MEAT dot emarketeers dot com
09-Dec-2002 02:48

You *can* return a reference from a constructor. You just need to understand exactly what the "=" and "=&" operators do. Try this:

class parent
{
  var $child;
  function parent($name)
  {
      $this->name = $name;
      $this->child =& new child($this);
}
}

class child
{
  var $parent;
  function child(&$parent)
  {
      $this->parent = &$parent;
  }
}

$p = new parent("a");
$p->child->parent->name="b";
echo "Name = $p->name\n";  // Prints "a"

$p =& new parent("a");
$p->child->parent->name="b";
echo "Name = $p->name\n"; // Prints "b"

***
It seems that when a class constructor is called, PHP creates a new instance of the class and then either hands back a reference to this instance if you use the =& assignment operator, or creates and hands back a whole new copy if you use the plain = assignment operator.

You should assign new instances with the =& operator unless you have a good reason not to, because it is faster.

duncan at NOTINNED dot MEAT dot emarketeers dot com
09-Dec-2002 02:55

If you want to use class variables you should use a static method, not a global as suggested above.

class Counter {
 function Counter($name) {
   $this->name = $name;
   $this->id = Counter::id();
 }

 function &_classObj() {
   static $classObj;
   if(!is_object($classObj)) {
     $classObj = new stdClass();
     $classObj->id=0;
   }
   return $classObj;
 }

 function id() {
   $co =& Counter::_classObj();
   $co->id++;
   return $co->id;
}

 function sayHello() {
   echo "Hello, I am $this->name and my ID is $this->id\n";
 }
}

$a = new Counter("Bill");
$b = new Counter("Ben");

$a->sayHello();
$b->sayHello();

**** Prints ****

Hello, I am Bill and my ID is 1
Hello, I am Ben and my ID is 2

nightcat at poczta dot onet dot pl
13-Dec-2002 06:11

Cannot get it...
class A{
var $string;
function ble(){
static $r=0;
print($r++.'
');
}
}
$x=new A();
$y=new A();
$x->ble(); // Prints 0
$y->ble(); // Prints 1
$x->ble(); // Prints 2

method ble() is common for both objects?

If so... what does mean 'new' in PHP ? I think this need to be fixed... otherway PHP can be hanged by quite proper code:

class A{
var $string;
function ble(){
global $x;
static $r=0;
print($r++.'
');
$x->ble();
}
}
$x=new A();
$y=new A();
$y->ble();

And we're down...

components at tgdd dot com
17-Dec-2002 05:45

Reply to the post above...

Correct me if I'm wrong but, thats the great thing about OOP is the Objects hold their parent class's charateristics.  If you want what your trying to do, make a subclass and have it inherit your super class. In the subclass overwrite the method. use b$ = new ClassB(); to get a new template with out that method...

Michael Berndt
17-Dec-2002 04:33

<?
// some array examples
// it works!

$Berndt = array('Dozent'=> 'PHP','Linux' => 'AWK, Sed');

class Berndt {
var $Berndt = array('Michael', 'Berndt', 'phpinfo',
' ');

var $Michael = array('Michael'=> 'Berndt',
'Berlin' =>' ');

function Michael(){
global $Berndt;
echo "<pre>";
print_r($Berndt);
echo "\n" .$Berndt['Dozent']. "\n";
print_r($this->Berndt);     // integer-indices
echo "\n" . $this->Berndt[0] ."\n";
echo "\n". $this->Michael["Berlin"] ."\n\n";
print_r($this->Michael);    // key/value pairs
echo "</pre>";
}

} // End class Berndt
$objekt = new Berndt();
$objekt->Michael();
?>
<?/* PHP Version >= 4.1.2: */?>

acsguy at wtp dot net
19-Dec-2002 09:29

If you want to store class objects in the $_SESSION variable so that pages and scripts that follow are able to access the class without having to re-create the class each time a new page or script loads, you might also want to write some helper functions to make the code easier to use.  I struggled for a week trying to write one that worked.  The main problem I was running into was wanting the function to return a reference to the class object stored in  $_SESSION.  You cannot use the & operator with the return statement.

// error
return &$_SESSION["class"];

//if you use a variable to get past the error, you get a copy.
// NOT a refference
return $var = &$_SESSION["class"];

[solution]
I found the solution here


what it entailed is declaring the function itself as returning a reference e.g.

function &get_class_ref("class_name"){
  return $_SESSION["class_name"];
}

if you call the function like this it STILL passes a copy

// still won't work
$class = get_class_ref("class_name");

//BUT if you also include the & operator it WILL WORK
$class = &get_class_ref("class_name");

//here is a part of my helper functions for clarity

function class_pointer($c_name){
if (empty($c_name)) return false;

if (is_object($_SESSION["classes"][$c_name])){
return true;
}else{
$test = new $c_name;
$_SESSION["classes"][$c_name] = $test;
}

return true;
}

function &load_class($c_name){
switch($c_name){
case "c_dbase":
if (class_pointer("c_dbase")){
if (!$_SESSION["classes"]["c_dbase"]->connect()){
$_SESSION["classes"]["c_page"]->display();
exit();
}
return $_SESSION["classes"]["c_dbase"];
}else{
$_SESSION["classes"]["c_page"]->add("Couldn't create class c_dbase");
$_SESSION["classes"]["c_page"]->display();
exit();
}
break;
}
}

// and is used like this
$cdb = &load_class("c_dbase");

[/solution]

hope this helps!

FYI  if you create a class from within another class method and set a class property by reference to the created class, php will COPY the class, not by reference like you would expect.  if you assign the property by reference from another seperate method call, it will do what you expect......

e.g.
// this will be by VALUE: $this->class is a COPY
class this()
{

var $class;

function getclass(){
  $_SESSION["class"] = new class();
  $this->class = &$_SESSION["class"];
}
}

// this DOES work:  $this->class is a referenc to the one
//stored in $_SESSION but takes 2 SEPERATE calls
class this()
{

var $class;

function make_class(){
  $_SESSION["class"] = new class();
}

function assign_class(){
  $this->class = &$_SESSION["class"];
}
}

Michael Berndt
22-Dec-2002 04:22

initialize various classes

Sample:


Source Code:

Michael Berndt
24-Dec-2002 01:22

Set the type of variable from "array" to "object".

Sample:


Source Code:

Michael Berndt
24-Dec-2002 12:04

Array of Objects

Sample:


Source Code:

tomcat at techie dot com
04-Jan-2003 08:48

Creating Object collection is very easy in PHP. Actually, regular array can serve as one:

class user {

   var $login;
   var $email;
   var $password;

   function user ( $login, $email, $password ) {
       $this->login = $login;
      $this->email = $email;
       $this->password=$password;
  }

}

$arrOBJ = array(); //This line is unnecessary, I would just use it to make code more readable. You can remove.
$arrOBJ[] = new user("1","1","1");
$arrOBJ[] = new user("2","2","2");

echo "success: ".$arrOBJ[0]->login;

tomcat at techie dot com
06-Jan-2003 01:39

The fact that PHP does not support variable types, leads to new opportunities. You can make an object-collection with different classes of objects, extremely easily (pay attention to posession collection of merchant object):

[example]

class user {

   var $login;
   var $email;
   var $password;

   function user ( $login, $email, $password ) {
       $this->login = $login;
      $this->email = $email;
      $this->password=$password;
   }

}

class house {
  var $price;
   var $area;

   function house () {
      $this->price = 10000000000;
   }
}

class car {
      var $price;
       var $speed;
       var $length;
       var $color;

       function car () {
         $this->speed = 300;
       }
}

class merchant {
       var $age;
     var $personality;
       var $posession;

       function merchant () {
               $this->age=27;
      }
}

$oMerchant = new merchant();
$oMerchant->personality = new user("name","pas","email");
$oMerchant->posession[] = new car();
$oMerchant->posession[] = new house();

echo "
<pre>
car-speed: ".$oMerchant->posession[0]->speed."
house-price: ".$oMerchant->posession[1]->price."
</pre>
"
[/example]

It's real cute, how easy it is compared to strictly-typed languages (well, it's less clean but so is everything in non-typed languages, right?).

mcoakley at netplay dot net
18-Jan-2003 03:47

In response to the comments above and using tomcats example directly... I love scripting languages and I love PHP the most out of them. While most programmers (and editors notes) try to state that PHP is not a true OO language it has what you need to develop good OO programs. Sure some of the really strong structured things aren't there but that is the fun you get with scripted languages. But after reading every comment on this page I think people (and I know I am going to get flamed for this one...) should start to fully understand the principles of OO programming: Encapsulation, Polymorphism and Abstraction.

For those new to those terms:
- Encapsulation is what you get when you can have data and the methods that act on those data in an "encapsulated" entity (object)
- Polymorphism is a property of objects that comes through inheritence that allows methods of the same name to perform different (but similar in purpose) actions
- Abstration provides a mechanism to design effective OO heirarchies by pulling common methods or actions into superclasses and using inheritence to provide functionality

If these principles are understood fully, PHP can be used as a great OO language.  Another common complaint is that PHP doesn't offer private/protected members/methods, I too would like to see these features. One BIG thing to keep in mind while desiging an OO program is that the objects should provide funtionality at the class level. Don't think of objects as individual entities but think of a heirarchy that provides "blackboxes" of code. In otherwords the class names should tell you what the object does and the methods only tell you how to invoke the functionality. You should never be concerned with how the object achieves its functionality. To demonstrate these principles more fully (and please do not take this as a finite example) I will create a real simple form building object heirarchy.

Post is too long, so example will be my next post...

mcoakley at netplay dot net
18-Jan-2003 03:48

Here is the example I promised...

//Abstract class - should never be instantiated
class FormField {
 var $name;
 var $value;
var $style;

 construction FormField($name, $value, $style = "") {
   $this->name = $name;
  $this->setValue($value);
   $this->setStyle($style);
}

 function setValue($value) { $this->value = $value; }
function getValue() { return $this->value; }
 function getName() { return $this->name; }
 function setStyle($style) { $this->style = $style; }
 function getStyle() { return $this->style; }
 
//Polymorphism - this method is the main polymorphic point
 function displayField() { echo "YOU MUST OVERRIDE!!!"; }
 
function getDisplayStyle() {
   if ($this->style=="") {
     return "";
   } else {
     return " style=\"$this->style\"";
   }
}

class TextInputField extends FormField {
 var $maxlength;
 var $size;

 function TextInputField($name, $value, $style = "", $maxlength = 255, $size = 20) {
  $this->FormField($name, $value, $style);
   $this->maxlength = $maxlength;
   $this->size = $size;
 }

 function displayField() {
   echo "<input name=\"$this->name\" size=\"$this->size\" maxlength=\"$this->maxlength\"" . $this->getDisplayStyle() . " value=\"$this->value\">";
}
}

//Another abstract class
class CheckboxRadioField extends FormField {
 var displayName;
 var selected;

 function CheckboxRadioField($name, $value, $displayName, $style = "") {
   $this->FormField($name, $value, $style);
  $this->displayName = $displayName;
 }

 function setSelected($selected) { $this->selected = $selected; }
 function isSelected() { $this->selected; }
 
 function getDisplaySelected() {
   if ($this->isSelected()) {
    return " checked";
   } else {
     return "";
   }
 }

}

class CheckboxField extends CheckboxRadioField {
 function CheckboxField ($name, $value, $displayName, $style = "") {
  $this->CheckboxRadioField($name, $value, $displayName, $style);
}

 function displayField() {
   echo "<input type=\"checkbox\" name=\"$this->name\" value=\"$this->value\"" . $this->getDisplaySelected() .  $this->getDisplayStyle() . ">$this->displayName";
 }
}

class RadioField extends CheckboxRadioField {
 function RadioField ($name, $value, $displayName, $style = "") {
  $this->CheckboxRadioField($name, $value, $displayName, $style);
}

 function displayField() {
   echo "<input type=\"radio\" name=\"$this->name\" value=\"$this->value\"" . $this->getDisplaySelected() . $this->getDisplayStyle() . ">$this->displayName";
}
}

//Now a quick usage example
$fields[] = new TextInputField("text1", "Hello World", "", 40);
$fields[] = new CheckboxField("checkbox1", "option_1", "Click here for option #1");
$fields[] = new RadioField("radio1", "rad_option_1", "Polished");
$fields[] = new RadioField("radio1", "rad_option_2", "Rough");

echo "<form action=\"form_handler.php\" method=\"post\">";
for ($i = 0; $i < count($fields); $i++) {
 //Polymorphism at its best
$fields[$i]->displayField();
}
echo "</form>";

Sorry for the long post but I just thought it could help...

jp at antz29 dot com
25-Jan-2003 05:17

ok, found a simple way to implement static class variables. this method may be frowned upon by anyone and everyone but it worked fine for me and is certainly more readable than 99% on alternatives that i have looked into. see below.

class A {
#this is going to be my static class variable.
var $foo;
 
function A() {
#define a global for my static variable.
#prepend the class name to the var name for clarity.
global $A_foo;

#and refrence it to my class variable.
$this->foo =& $A_foo;
}

function setfoo($val) {
$this->foo = $val;
}

function getfoo() {
return $this->foo;
}

}

#create two instances of the A object.
$foobar1 = new A;
$foobar2 = new A;

#set the first object's foo to bar.
$foobar1->setfoo('bar');

print "FOO-1 = ".$foobar1->getfoo()."
";
print "FOO-2 = ".$foobar2->getfoo()."
";

/*
This outputs:
FOO-1 = bar
FOO-2 = bar
*/

#and just to make my point clear, set the second object's foo to foobar.
$foobar2->setfoo('foobar');

print "FOO-1 = ".$foobar1->getfoo()."
";
print "FOO-2 = ".$foobar2->getfoo()."
";

/*
This outputs:
FOO-1 = foobar
FOO-2 = foobar
*/

see ist't that fantastic? feel free to e-mail me with any comments/questions.

phil at philkern dot de
26-Jan-2003 02:43

Subclasses inside of classes are not possible :/
Something like that (which would help to keep the code a bit cleaner) you would have to do in an other way:

class SomeClass {
 class Debug {
  function Log($text) {
   echo $text;
  }
 }

 function some_function() {
  SomeClass::Debug::Log($text); // Error
  }
}

So you can't built up perl alike constructs :)

vegard at copyleft dot no
28-Jan-2003 12:47

Remember that foreach() makes a copy of the assigned var, so don't use it on an array of objects. And foreach does not seem to support the pointer assignment:

foreach ($objarray, &$obj) {}

-- Vego

Evil Liam
29-Jan-2003 06:00

Warning!

PHP does not seem to mind if you declare methods (or even constructors) with the same name in a class.

class Object {
  function Object() {
       echo "Created\n";
  }

   function Method() {
       echo "First Method\n";
   }

   function Method() {
       echo "Second Method\n";
   }
}

$Instance=new Object();
$Instance->Method();

Output is:
Created
Second Method

Most of the time, it seems to just call the last method declared with that name.  However, I have seen it fail in unusual circumstances involving locally-scoped assert() statements and methods with the same name as the constructor.  Be on the safe side, and avoid redeclaring method or constructor names.

twoch
07-Feb-2003 07:38

As noted in another section of this user manual, the variable $this refers to the innermost encompassing class.  

If you invoke a method on class A from and instance of A, and from within that method invoke a method in class B using the "::" syntax (i.e. invoked as a class method), if the method within B uses $this it will refer to the instance of class A that called it.  

Note that this behavior is very different from the case where the same B method is invoked using and instance of class B, in which case $this refers to the instance of class B.

This can cause no end of grief when trying to debug such object methods that were invoked as class methods (although it can also be a powerful tool when used correctly).  However, IMHO, any method that might be invoked as a class method should refrain from the use of $this.

14-Feb-2003 07:29
A nice faq that lists OOP and CLASS information in regards to PHP (including many links to tutorials and resources) can be seen here:

mad dot murdock at unknown dot com
07-Mar-2003 02:34

re: immo at nospam dot org

While this useful example is correct, it contains a few redundant lines that might be a little confusing...

class MemberObject extends ParentObject {
    var $string;

    function MemberObject() {
        $this->string = "This is a test string.";
        $this->ParentObject();  //this line is not needed as the ParentObject funtion is a constructor for ParentObject class, which MemberObject is extending. Thus, it inherits it and since it is a constructor, it is executed automatically.//
    }
}

also

class ObjTest {
  var $ObjPointer;

 function ObjTest() {
      $tmp = new MemberObject;
$this->ObjPointer = $tmp;
    }
}

could be�

class ObjTest {
    var $ObjPointer;

    function ObjTest() {
         $this->ObjPointer = new MemberObject;
    }
}

rsantos at gelre dot com dot br
21-Mar-2003 01:05

/*
Pais: Brasil
Data: 20/03/2003
autor: Rodrigo Rodrigues
email: [email protected]
Descri��o: Heran�a no Php
*/
class pai { // Class pai
  var $nome;
  function setNome($newNome) { // Fun��o Set
     $this->nome = $newNome;
}

  function getNome() { // Fun��o Get
     return $this->nome;
  }
}
class filho extends pai { // Extends to class pai
  function filho($valorNome) { // Construtor
     return pai::setNome($valorNome);
  }
}
$autor = "Rodrigo Rodrigues";
$obj = new filho($autor);
echo ($obj->getNome());

rjkaes at flarenet dot com
05-Apr-2003 04:30

The note and example indicates that arrays cannot be used to initialize class variables, but I've used the following code without a problem:

class Foo {
   function print_field($n)
   {
      print $this->_fields[$n];
   }

   var $_fields = array('field1', 'field2', 'field3');
}

$foo = new Foo;
$foo->print_field(1);

Perhaps the note/example in the documentation needs to be clarified.

russ dot taylor at nifty dot com
18-Apr-2003 08:31

It is sometimes useful to register a class instance as a session variable. This can allow classes and their contained values to persist across multiple pages and/or frames.  Frames which need to use the registered class must be loaded (or reloaded) after the class instance is registered and the class declaration must be included in each file that needs to access the registered class.

i.e.
<?
session_start();// must have a session, duh...

class foo{//normal class declaration

 var $bar;

 function foo(){//normal constructor
   $this->bar = "a value to share and persist";
 }
}

$vital = new foo;//instance "vital" of object type "foo"

session_register("vital");//register the instance "vital"

//other code as needed

?>

**NOTE: it would be helpful to include the class from an external source so the same declaration could be used everywhere its needed, duh

then simply include the class declaration in any other file and you will have access to the registered class instance.  in a separate frame on the same page you could use ...

<?
session_start();

class foo{//same class declaration

 var $bar;

 function foo(){//normal constructor
   $this->bar = "a value to share and persist";
 }
}

echo $vital->bar;

?>

**NOTE: if you use a frameset you must allow processing time of the session registration or the value will not be available!  You can use any number of methods to trigger the delay, but the session must NOT be started on the second page beforre the variable is registered on the first.  On option is to use an onload statement in the first frames body tag, assuming normal html output...

<html><head></head><body onLoad="parent.frame[1].location.reload();"><!--what ever else you need to output--></body></html>

"frame[1]" assumes a two frame layout with frame[0] containing the values to share and frame[1] requiring those values. thus this, when included in frame[0] will force a reload of frame[1] AFTER the class instance was registered.

chris at dontwantspam dot com
23-Apr-2003 06:29

Even though you can't set a default value for an argument like this:

function foo($bar = 'rar') {
 // do stuff
}

You can use the func_get_arg, func_get_args, and func_num_args on class methods.

function foo() {
 $bar = func_num_args >= 1 ? func_get_arg(0) : 'rar';
}

yaroukh at email dot cz
23-Apr-2003 03:21

to Mad Murdock:

@ 06-Mar-2003 08:34 you wrote:

"this line is not needed as the ParentObject funtion is a constructor for ParentObject class, which MemberObject is extending. Thus, it inherits it and since it is a constructor, it is executed automatically."

I think you're wrong. A constructor of the "parent" class is being called only if the "child" class constructor is not found.
Following example prooves this - the Parent's constructor is not being executed and the output is only: "here I am - Child constructor"

<?..class Parent {
........function Parent() {
............print "here I am - Parent constructor";
........}
....}

....class Child extends Parent {
........function Child() {
............print "here I am - Child constructor";
........}
....}

....$child =& new Child();
?>

Have a nice day
 Yaroukh

add a note

<Variablenfunktionenextends>
 Last updated: Sat, 19 Apr 2003
show source | credits | mirror sites 
Copyright © 2001-2003 The PHP Group
All rights reserved.
This mirror generously provided by: /
Last updated: Mon May 12 21:12:21 2003 CEST